binlog 三种格式深度解析
候选人小张在美团二面中,面试官问:
"MySQL 的 binlog 有几种格式?你们用的哪种?为什么?"
小张说:"有 STATEMENT、ROW、MIXED 三种格式,我们用的 ROW。"
面试官追问:"为什么用 ROW 格式?STATEMENT 格式有什么问题?"
小张说:"ROW 更精确..."
面试官继续追问:"ROW 格式有什么缺点?你们考虑过吗?"
小张答不上来了。
【面试官心理】 这道题我用来测试候选人对 binlog 格式的理解深度。能说出三种格式名称的占 60%,能讲清各自优缺点的占 30%,能说出选型理由的占 15%。binlog 格式是 MySQL 面试的进阶知识点。
一、binlog 的作用 🔴
1.1 binlog 是什么
binlog(Binary Log)是 MySQL 服务端产生的二进制日志,记录了所有数据库的修改操作。
1.2 binlog 和 redo log 的区别
二、STATEMENT 格式 🔴
2.1 原理
STATEMENT 格式记录的是原始 SQL 语句。
2.2 优点
- 日志量小:只记录 SQL,不记录每行数据变化
- 可读性好:人类可读的 SQL 语句
- 审计方便:可以直接查看执行了什么操作
2.3 缺点
⚠️
STATEMENT 格式在高并发场景下可能导致主从数据不一致。MySQL 5.1 之前默认使用 STATEMENT 格式,但 MySQL 5.7+ 推荐使用 ROW 格式。
三、ROW 格式 🔴
3.1 原理
ROW 格式记录的是每一行数据的变化。
3.2 优点
- 数据一致性:直接记录行变化,主从完全一致
- 无函数问题:不依赖函数执行结果
- 无触发器问题:触发器的影响也被记录
3.3 缺点
- 日志量大:每行变化都要记录,可能大 10 倍
- 可读性差:ROW 格式的 binlog 不是人类可读的
- 分析困难:使用 mysqlbinlog 分析时需要指定 -v
四、MIXED 格式 🔴
4.1 原理
MIXED 格式自动选择 STATEMENT 或 ROW:
- 使用 STATEMENT:确定性 SQL(如 UPDATE orders SET amount = 100 WHERE id = 1)
- 使用 ROW:不确定性 SQL(如 UPDATE orders SET time = NOW())
4.2 自动切换规则
MySQL 根据以下规则自动切换:
- 使用了
NOW(),RAND(),UUID()等非确定性函数 - 使用了触发器或存储过程
- 访问了用户变量
- 使用了
LOAD_FILE(),UUID_SHORT()等函数 - 使用了
INSERT DELAYED - 涉及多表更新
五、三种格式对比 🟡
5.1 对比表
5.2 选型建议
5.3 生产配置
:::tip 💡
binlog_row_image 参数控制 ROW 格式下记录多少数据:
- FULL:记录修改前后的完整行
- MINIMAL:只记录修改的列
- NOBLOB:和 FULL 类似,但忽略未修改的 BLOB 列 :::
六、binlog 分析与恢复 🟡
6.1 查看 binlog 文件
6.2 数据恢复
6.3 分析 binlog
【面试官心理】
能说出 binlog 分析命令的候选人,基本都有数据恢复经验。能说清楚 ROW 格式下 binlog_row_image 参数作用的,是 P7 的水准。
七、面试追问链 🟡
第一层:binlog 有几种格式?
- 候选人:STATEMENT、ROW、MIXED
第二层:STATEMENT 格式有什么问题?
- 候选人:函数、NOW() 等可能导致主从不一致
第三层:ROW 格式有什么缺点?
- 候选人:日志量大
第四层:binlog 和 redo log 的区别?
- 候选人:binlog 用于主从复制,redo log 用于崩溃恢复