1 基本概念
BinLog是一种记录所有MySQL数据库表结构变更以及表数据变更的二进制日志。BinLog中不会记录诸如select和show这类查询操作的日志。BinLog有如下两个重要的使用场景
- 主从复制:在主数据库上开启BinLog,主数据库把BinLog发送至从数据库,从数据库获取BinLog后通过IO线程将日志吸入到中继日志,也就是Relay Log中。然后通过SQL线程将Relay Log中的数据同步至从数据库,从而达到主从数据库的一致性。
- 数据恢复:当MySQL数据库发生故障或者崩溃时,可以通过BinLog进行数据恢复。
2 记录模式
2.1 Row模式
- 记录内容 :记录数据行的实际变更(如某行的字段从
A
变为B
)。 - 特点 :
- 优点:复制更精确,不会出现因语句执行环境不同导致的主从数据不一致。
- 缺点:日志量大(尤其是批量操作时),性能略低。大批量操作时候,会产生大量的二进制日志。比如使用alter table操作修改用友大量数据的数据表结构时,会使二进制日志的内容暴涨,产生大量的二进制日志,从而大大影响主从数据库的同步性能。
- 适用场景:对数据一致性要求高的场景(如金融系统),或使用了不确定函数的环境。
2.2 Statement模式
- 记录内容 :记录 SQL 语句本身(如
INSERT
、UPDATE
)。 - 特点 :
- 优点:日志量小,节省存储空间,性能较高。由于不记录数据的修改细节,只是记录数据表结构和数据变更的SQL语句,因此产生的二进制日志数据量比较小,这样能够减少磁盘的IO操作,提升数据存储和恢复的效率。
- 缺点 :某些语句在复制时可能导致主从数据不一致(如
NOW()
、RAND()
等函数,或使用触发器、存储过程时)。
- 适用场景:语句确定性高、无特殊函数或触发器的环境。
2.3 Mixed模式
- 记录内容 :自动选择 使用 STATEMENT 或 ROW 模式:
- 默认使用 STATEMENT 模式。
- 遇到不确定语句(如
RAND()
)或可能导致数据不一致的操作时,自动切换为 ROW 模式。
- 特点 :
- 优点:平衡了性能和数据一致性。
- 缺点:仍可能存在少量特殊场景下的不一致风险。
- 适用场景:大多数生产环境的默认选择。
3 文件结构
3.1 单个Binlog文件内部结构
每个Binlog文件由以下几部分组成:
3.1.1 文件头(4字节)
- 魔术数字
0xfe 0x62 0x69 0x6e
(即"bin"前面加0xfe)
3.1.2 事件序列
- 由多个事件(Event)按时间顺序排列组成
- 每个事件代表一个数据库操作或元数据变更
3.1.3 文件尾
- 当文件正常关闭时,会写入一个
Rotate Event
指向下一个文件 - 非正常关闭时可能没有文件尾
3.2 事件(Event)结构
每个事件包含以下部分:
部分 | 大小 | 说明 |
---|---|---|
事件头 | 19字节 | 包含事件元数据 |
事件体 | 可变 | 事件的具体内容 |
校验和 | 4字节(可选) | 事件的CRC32校验值 |
3.2.1 事件头详细结构(19字节):
偏移量 | 长度 | 字段 | 说明 |
---|---|---|---|
0 | 4 | timestamp | 事件发生的时间戳 |
4 | 1 | type_code | 事件类型代码 |
5 | 4 | server_id | 产生事件的服务器ID |
9 | 4 | event_length | 整个事件长度(头+体) |
13 | 4 | next_position | 下一个事件的位置 |
17 | 2 | flags | 事件标志位 |
3.3 常见事件类型
类型代码 | 事件类型 | 说明 |
---|---|---|
0x01 | START_EVENT_V3 | 旧版本开始事件 |
0x02 | QUERY_EVENT | 执行SQL语句(STATEMENT 模式) |
0x04 | ROTATE_EVENT | binlog文件切换 |
0x0f | FORMAT_DESCRIPTION_EVENT | 文件格式描述 |
0x10 | XID_EVENT | 事务提交事件 |
0x11 | TABLE_MAP_EVENT | 表映射事件(ROW模式) |
0x12 | WRITE_ROWS_EVENT | 插入行事件(ROW模式) |
0x13 | UPDATE_ROWS_EVENT | 更新行事件(ROW模式) |
0x14 | DELETE_ROWS_EVENT | 删除行事件(ROW模式) |
0x15 | INCIDENT_EVENT | 服务器异常事件 |
3.4 不同模式下的事件差异
3.4.1 STATEMENT 模式
-
QUERY_EVENT :直接记录 SQL 语句。
sql+--------+----------------+-------------------+ | 头信息 | 数据库名长度 | SQL语句 | +--------+----------------+-------------------+
3.4.2 ROW 模式
-
TABLE_MAP_EVENT:定义表结构(表 ID、列类型等)。
-
WRITE_ROWS_EVENT :记录插入的行数据。
diff+--------+-------+----------------+----------------+ | 头信息 | 表ID | 列掩码 | 行数据 | +--------+-------+----------------+----------------+