MySQL binlog 设计
通过这篇文章你能了解到的知识
binlog
是什么binlog
的作用binlog
的三种类型,以及各自优缺点binlog
文件的结构与内容
binlog
是什么
Binary Log
,顾名思义是一种二进制格式的日志。具体来说,binlog
日志是一组包含了对 MySQL server 实例进行数据修改(update/delete/insert/...
)信息的文件。binlog 作用
- 用于复制,如主从复制
- 数据恢复
- 基于语句 (
Statement-based
)的日志记录 (SBL
): 事件包含产生数据变化的SQL语句。 - 基于行 (
Row-based
) 的日志记录(RBL
): 描述单个行的变化 - 混合 (
Mixed
):上述两者结合使用, 以SBL
为主,特殊情况下切换到RBL
一开始只有
statement-based
,但 statement-based
存在不少问题,后面才有的 row
与 mixed
。SBL
优点- 产生的日志文件少, io 次数少
SBL
缺点- 在一些不安全的语句上,主从复制做不到数据一致,比如
- 含有系统函数的语句,可能会在副本上返回不同的值,如
RAND(), USER(),UUID(), SYSDATE() ....
- 更新一个有
AUTO_INCREMENT
列的表 - Updates using LIMIT
- ...
- 含有系统函数的语句,可能会在副本上返回不同的值,如
- 慢 SQL 会在副本中再执行一次
RBL
优点- 这是最安全的复制形式
- 在
INSERT/UPDATE/DELETE
语句中,副本相对主行锁范围更小。
RBL 缺点
RBL
日志文件更大
推荐使用
RBL
,利大于弊,最新 MySQL 版本默认也是使用 RBL
。binlog
结构
binlog 文件结构binlog.index
: 文本文件,如下面的例子,列出了当前的二进制日志文件(现在有 6 个)。binlog.xxxxxx:
log 二进制文件,binlog.000001
binlog.000002
binlog.000003
binlog.000004
binlog.000005
binlog.000006
binlog.index
每个日志文件以一个 4 字节魔数 ( 0xfe b i n) 开头,后面是一组描述数据修改的事件,文件格式如下:
+===================+
| Magic Number|
+===================+
| Start Event|
+===================+
| Event 1|
+===================+
| ...|
+===================+
【MySQL binlog 设计】一个具体的例子:
show BINLOG EVENTS in 'binlog.000001'
+---------------+---------+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name| Pos| Event_type| Server_id | End_log_pos | Info|
+---------------+---------+----------------+-----------+-------------+-------------------------------------------------------------------+
| binlog.000001 | 4| Format_desc| 1| 125| Server ver: 8.0.26, Binlog ver: 4|
| binlog.000001 | 125| Previous_gtids | 1| 156||
| binlog.000001 | 156| Anonymous_Gtid | 1| 233| SET @@SESSION.GTID_NEXT= 'ANONYMOUS'|
| binlog.000001 | 233| Query| 1| 337| use `mysql`;
TRUNCATE TABLE time_zone /* xid=3 */|
| binlog.000001 | 337| Anonymous_Gtid | 1| 414| SET @@SESSION.GTID_NEXT= 'ANONYMOUS'|
| binlog.000001 | 414| Query| 1| 523| use `mysql`;
TRUNCATE TABLE time_zone_name /* xid=4 */|
事件 Event 常见分类
START_EVENT_V3
: 每个日志文件的第一个事件, 该事件在MySQL 3.23 至 4.1 中使用,在 MySQL 5.0 中被FORMAT_DESCRIPTION_EVENT
所取代, 从第五个字节开始(魔数后)QUERY_EVENT
:SBL
的binlog
记录 sql 语句,在 row 模式下记录事务 beginSTOP_EVENT
: mysqld 进程停止时记录ROTATE_EVENT
: log 文件大小到达设置的最大值,切换到新的 log 文件时写入,切换事件TABLE_MAP_EVENT
: 在 binlog 文件是以 ROW 格式记录才会使用,TABLE_MAP_EVENT
中记录了表的定义(包括database name, table name,字段定义),记录的每个更改的记录之前都会有一个对应要操作的表的TABLE_MAP_EVENT
WRITE_ROWS_EVENT
: 插入记录,ROW 格式记录才会使用UPDATE_ROWS_EVENT
: 更新记录,ROW 格式记录才会使用DELETE_ROWS_EVENT
: 删除记录,ROW 格式记录才会使用- ...
binlog
版本的演变实质上是 Event
的演变- v1:在MySQL 3.23 中使用
- v3:在MySQL 4.0.2 和4.1中使用
- v4:在MySQL 5.0 及以上版本中使用
其中 Event 又分为两个部分: Event header 和 Event data。header 部分的长度由 binlog 版本决定,data 部分的长度又由 header 决定
+===================+
| event header|
+===================+
| event data|
+===================+
以下是 Event 的具体结构以及各版本之间的差异
其中数字代表着这个字段在 Event 中的 limit 与 offset, 例如 0:4,代表着在这个字段的位置在 Event 的 0-4 个字节。
+=====================================+
| event| timestamp0 : 4|
| header +----------------------------+
|| type_code4 : 1|
|+----------------------------+
|| server_id5 : 4|
|+----------------------------+
|| event_length9 : 4| v1 header 共 13 个字节
|+----------------------------+
|| next_position13 : 4| v3 版本增加。
|+----------------------------+
|| flags17 : 2| v3 版本增加。 v3 header 共 19 个字节
|+----------------------------+
|| extra_headers19 : x-19 | v4 版本增加。 v4 header 最少 19 个字节
+=====================================+
| event| fixed partx : y|
| data+----------------------------+
|| variable part|
+=====================================+
header 部分各字段解释
timestamp
: 事物开始执行的时间,单位秒type_code
: 事件类型, 见上文 事件常见分类,它决定了 data 部分的写入数据server_id
: 来自服务器配置文件中为复制目的设置的 server-id 选项,破除复制中可能的死循环。event_length
: 这个 event 的总长度next_position
: v3 新加,在 v3 版本中代表这个事件开始的位置,在 v4 版本中这个事件结束的位置flags
: v3 新加,一些标志位 https://dev.mysql.com/doc/int...extra_header
: v4 新加,目前是 0,即空
由事件类型决定,如 v1,v3 query 事件,data 部分构成如下:
+======================================+
| fixed| issue_thread0 : 4| 触发该语句的线程id
| part+----------------------------+
|| timestamp4 : 4| 语句执行的时间
|+----------------------------+
|| db_name_len8 : 1| 使用数据库名长度
|+----------------------------+
|| error_code9 : 2| 错误码
+======================================+
| variable| db_name| db name
| part+----------------------------+
|| sql_statment| sql 语句
+======================================+
总结
binlog
文件由魔数与事件列表构成,事件列表分成三部分:开始事件 + 数据更新相关的事件 + 切换事件- 事件的类型决定了事件的格式,因为每种事件所需的信息是不一致的
- 主从复制,采取的是 push 模式还是 pull 模式
- MySQL binlog 为什么不默认使用 Mixed 模式
- 在使用
RBL
前提下 ,DDL(CREATE/ALTER) 语句怎么记录 - 使用
NOW()
的语句是不安全么(SBL
主从复制 ) - 如果让你来设计开始事件类型的结构,data 部分需要什么数据
binlog
与redo log
区别
- https://dev.mysql.com/doc/int...
- http://mysql.taobao.org/month...
- https://zhuanlan.zhihu.com/p/...
推荐阅读
- PMSJ寻平面设计师之现代(Hyundai)
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 爱琐搭配(喜欢复古、冷淡,像这种双环设计的气质耳环)
- 别墅庭院设计,不同的别墅庭院设计也给人视觉上完全不一样的!
- 数据库设计与优化
- py连接mysql
- 2019-01-18Mysql中主机名的问题
- MySql数据库备份与恢复
- 设计模式-代理模式-Proxy
- mysql|InnoDB数据页结构