MySQL binlog解析
目录
- 1、binlog是什么?
- 2、Binlog作用
- 3、Binlog格式
- 3.1、Statement(语句格式)
- 3.2、Row(行格式)
- 3.3、Mixed(混合格式)
- 4、总结
1、binlog是什么?
Binlog
(Binary Log),也叫二进制日志,是 MySQL 中记录“对数据库执行更改操作的事件日志
”。
通俗点讲,只要你的 SQL
会改变数据库的内容,比如 INSERT
、UPDATE
、DELETE
、CREATE TABLE
、DROP TABLE
等,MySQL 就会在 binlog
中记一笔,而 SELECT
、SHOW
等纯查询类操作,不会记录。
MySQL
的 Binlog
是理解 MySQL
内部执行机制、实现高可用、数据恢复、审计分析等高级能力的核心之一。
2、Binlog作用
-
主从复制的基础:主库将
binlog
发送给从库,从库重放binlog
,实现数据同步。 -
数据恢复:比如误删了一行数据,你可以从
binlog
中“反推”出来,结合全量备份 +binlog
可恢复任意时间点的数据(PITR,Point In Time Recovery)。 -
增量备份:只有变更的数据才记录,空间效率高。
-
审计与分析:可查看操作历史、追踪问题。
-
数据同步与中间件接入:如
Canal
等工具通过解析binlog
实现实时数据流转。
3、Binlog格式
通过配置 binlog_format
参数,有三种格式:
Statement
(语句格式)Row
(行格式)Mixed
(混合格式)
3.1、Statement(语句格式)
这是最原始的一种格式,binlog
记录的是 SQL
语句本身,比如:
UPDATE users SET score = score + 1 WHERE id = 10
Binlog
就直接记录这条 SQL
语句,从库执行相同 SQL 语句。
风险举例:
UPDATE users SET created_at = NOW();
如果主从库的时钟不同步,执行结果不同。
优点:
- 日志体积小,效率高;
- 不依赖表结构,简单直接。
缺点:
- 一旦涉及“非确定性操作”,结果可能不一致;
- 比如函数 UUID()、NOW()、RAND() ——主库和从库生成的值可能不同!
一句话总结:语义不够精确,不适合数据强一致场景
。
3.2、Row(行格式)
Row
格式更“踏实”一点,它不记录 SQL
语句,而是记录执行后影响的每一行数据的变化
。
例如:
UPDATE users SET score = score + 1 WHERE id = 10
Binlog
记录的不是 SQL
语句,而是记录:
- 旧数据:id=10, score=59
- 新数据:id=10, score=60
优点:
- 精确无误,不怕函数、触发器、存储过程搞鬼;
- 保证主从一致性非常好。
缺点:
- 日志体积大;
- 一次更新一万条记录,那
binlog
就得写一万个变化记录!
一句话总结:精确、安全,但对存储和性能要求高
。
3.3、Mixed(混合格式)
看到这名字你就知道,它是 Statement
和 Row
的折中方案。
MySQL
会根据实际情况自动选择使用哪种格式:
- 优先使用
Statement
; - 若
SQL
存在副作用(如 UUID(), NOW() 等),自动切换为Row
。
适合大部分生产环境的折中选择。
优点:
- 尽量兼顾体积与一致性;
- 程序员省心,不用每次手动切换格式。
缺点:
- 对开发者来说是个“黑盒”,不容易预估日志内容;
- 故障排查时可能比较麻烦。
一句话总结:一刀切的折中选择,适合多数场景
。
4、总结
格式 | 一致性 | 日志大小 | 可读性 | 推荐 |
---|---|---|---|---|
Statement | 较差 | 小 | 高 | 银行系统 ,主从复制且对一致性要求极高的系统 |
Row | 最好 | 大 | 低 | 日志系统 ,对性能要求极致的 |
Mixed | 较好 | 中 | 中 | 不确定场景 ,建议默认使用 Mixed,也是 MySQL 8.x 默认推荐格式。 |