MySQL Binlog 详解
MySQL 的二进制日志(Binary Log,简称 Binlog)是 MySQL Server 记录数据库变更操作的重要日志文件,主要用于数据恢复、主从复制(Replication)和审计。
Binlog 记录什么?
Binlog 记录会修改数据库数据或结构的操作,例如:
-
INSERT -
UPDATE -
DELETE -
CREATE TABLE -
ALTER TABLE -
DROP TABLE
通常不会记录纯查询语句(如 SELECT)。
Binlog 的作用
1. 主从复制(Replication)
MySQL 主从架构中:
-
主库(Master)将数据变更写入 Binlog。
-
从库(Replica)读取 Binlog 并重放其中的操作。
-
从而保持主从数据一致。
流程:
Client
↓
Master
↓ 写入 Binlog
Binlog
↓
Replica IO Thread
↓
Relay Log
↓
Replica SQL Thread
↓
执行变更
2. 数据恢复(Point-in-Time Recovery)
假设:
-
凌晨 1:00 做了全量备份。
-
上午 10:00 误删数据。
恢复步骤:
-
恢复 1:00 的备份。
-
使用 Binlog 重放 1:00~9:59 的所有操作。
-
恢复到误操作前的状态。
这种方式称为:
PITR(Point In Time Recovery,时间点恢复)
3. 数据同步与 CDC
许多数据同步工具直接解析 Binlog:
应用场景:
-
MySQL → Elasticsearch
-
MySQL → Kafka
-
MySQL → Data Warehouse
-
实时数据同步
Binlog 的三种格式
1. Statement-Based Logging(SBL)
记录执行的 SQL 语句。
例如:
UPDATE user
SET balance = balance - 100
WHERE id = 1;
Binlog 中保存的是这条 SQL。
优点:
-
日志小
-
写入快
缺点:
- 某些非确定性函数可能导致主从不一致
例如:
UPDATE user
SET create_time = NOW();
或者:
INSERT INTO t VALUES(UUID());
2. Row-Based Logging(RBL)
记录数据行变化。
例如:
UPDATE user
SET balance = 900
WHERE id = 1;
Binlog 记录:
Before:
id=1 balance=1000
After:
id=1 balance=900
优点:
-
数据最准确
-
主从一致性最好
缺点:
- 日志体积较大
3. Mixed-Based Logging(MBL)
混合模式:
binlog_format=MIXED
MySQL 自动决定:
-
普通 SQL → Statement
-
风险 SQL → Row
查看当前 Binlog 格式
SHOW VARIABLES LIKE 'binlog_format';
结果:
+---------------+-----+
| binlog_format | ROW |
+---------------+-----+
MySQL 8.0 默认通常为:
ROW
Binlog 文件示例
查看:
SHOW BINARY LOGS;
结果:
mysql-bin.000001
mysql-bin.000002
mysql-bin.000003
当前使用的文件:
SHOW MASTER STATUS;
例如:
File: mysql-bin.000003
Position: 1547
这里的:
-
File = Binlog 文件名
-
Position = 写入位置
主从复制就是依赖这两个值定位同步位置。
查看 Binlog 内容
使用 MySQL 自带工具:
mysqlbinlog mysql-bin.000003
查看某个时间段:
mysqlbinlog \
--start-datetime="2025-01-01 10:00:00" \
--stop-datetime="2025-01-01 11:00:00" \
mysql-bin.000003
查看指定位置:
mysqlbinlog \
--start-position=1000 \
--stop-position=2000 \
mysql-bin.000003
开启 Binlog
查看是否开启:
SHOW VARIABLES LIKE 'log_bin';
结果:
ON
配置文件(my.cnf):
[mysqld]
server-id=1
log_bin=mysql-bin
binlog_format=ROW
重启 MySQL 后生效。
Binlog 与其他日志的区别
| 日志类型 | 作用 |
|---|---|
| Binlog | 记录数据变更,用于复制和恢复 |
| Redo Log | 保证事务持久性(崩溃恢复) |
| Undo Log | 支持事务回滚和 MVCC |
| Error Log | 记录 MySQL 错误信息 |
| Slow Query Log | 记录慢 SQL |
| General Log | 记录所有客户端请求 |
Binlog 与 Redo Log 的核心区别
很多会问:
| Binlog | Redo Log |
|---|---|
| MySQL Server 层 | InnoDB 存储引擎层 |
| 逻辑日志 | 物理日志 |
| 记录数据变更 | 记录页修改 |
| 用于主从复制 | 用于崩溃恢复 |
| 可追加写 | 循环写 |
简化理解:
-
Binlog:记录“执行了什么操作”。
-
Redo Log:记录“数据页如何被修改”。
例如:
UPDATE account
SET money = 100
WHERE id = 1;
Binlog 记录:
UPDATE account ...
Redo Log 记录:
Page 100:
offset 320
1000 → 100
因此:
-
Binlog 负责复制和时间点恢复。
-
Redo Log 负责数据库宕机后的事务恢复。
这是 MySQL 日志体系中最重要的两个日志。