朋友们,MySQL能成为当今是最流行的开源关系型数据库,BinLog可以说功不可没,主从同步和数据恢复都依赖它,下面我们对BinLog简要说明。
概念
全名是Binary Log,即二进制日志文件。Binlog 是 Server 层的日志,它记录了所有的 DDL 和 DML(不包含数据查询语句)语句,是以事件形式记录的,还包含语句所执行的消耗的时间等。
BinLog是逻辑日志(仔细想想也是,由于它用于主从同步,主从的数据页可能是不一致的,无法记录数据页的变化,只能记录数据的逻辑变化)。开启 binlog 之后,大致会有 1% 的性能损耗,不过这还是可以接受的,一般来说,binlog 有两个重大的使用场景:MySQL 主从复制 和MySQL 数据恢复。
binlog 是追加写,文件写满(默认1GB)后会自动切换到下一个日志文件继续写。binlog默认在data目录里,mysql-bin.00000n 存储实际的数据库更改事件,mysql-bin.index是binlog索引文件。

格式
binlog 日志有三种格式,分别为 STATMENT 、 ROW 和 MIXED。
ROW:基于行的复制,记录哪条数据被修改了(不记录每条SQL语句的上下文信息)。
- 优点:兼容性好;从库无需扫描直接定位更新往往比较快。
- 缺点:批量修改时会产生大量的日志。
STATMENT:基于SQL语句的复制,记录修改的SQL语句 。相对于ROW模式,STATEMENT模式下只会记录这个 update 的语句,所以此模式下会超级节省日志空间,也避免着大量的IO操作。
- 优点:不需要记录每一行的变化,减少了 binlog 日志量, 从而提高了性能。
- 缺点:在某些情况下会导致主从数据不一致,列如执行sysdate() 等 ;主从都需要扫描,两者锁表时间几乎一样长。
MIXED:STATMENT 和 ROW 的混合模式,可以说不是一种新格式。
文件清理
binlog是保存在磁盘上的,会占用磁盘空间,为了避免磁盘占满MySQL支持自动清理和手动清理;
自动清理
binlog有‘过期’这个概念,对过期文件的自动清理由如下几个触发点:
- MySQL服务重启;一般会生成新的binlog文件,触发过期文件清理。
- 手动刷新日志;执行命令flush binary logs 和 flush logs 时生成新的binlog文件 ,触发过期文件清理。
- 自动刷新日志;当前日志文件大小达到 max_binlog_size 值 (默认1GB)时生成新的binlog文件,触发过期文件清理。
但是,上面的触发过期文件清理只是“触发”不是真正的“清理”, 是否真正清理还要满足如下:
binlog_expire_logs_auto_purge=ON;表明开启过期文件自动清理。
binlog_expire_logs_seconds不等于0;0表明永远不过期,大于0表明有具体的过期时间(MySQL5.7之前是expire_logs_days)。
手动清理
进入MySQL执行
# 恢复到初始只有 mysql-bin.000001的状态
reset master;
# 删除mysql-bin.000003之前的所有binlog
purge binary logs to
'mysql-bin.000003';
# 删除2025-11-12 14:53:10之前的所有文件
purge binary logs before
'2025-11-12 14:53:10';
# 产生新的binlog文件
flush binary logs;
查看binlog
binlog是二级制文件直接打开看不懂,可以通过MySQL自带的mysqlbinlog命令查看。
# 查看binlog文件列表(SQL命令)
show binary logs;
# 查看某binlog文件
mysqlbinlog -v mysql-bin.000001
# 查看某binlog文件中数据库bee的信息
mysqlbinlog -v --database=bee
mysql-bin.000001
# 解析指定时间范围内的 binlog(不如根据position定位)
mysqlbinlog
--start-datetime="2025-11-12 10:00:00"
--stop-datetime="2025-11-12 11:00:00"
mysql-bin.000001
# 解析指定位置范围内的 binlog(超级好用)
mysqlbinlog
--start-position=123
--stop-position=789
mysql-bin.000001
# 解析binlog,内容输出到指定文件
mysqlbinlog mysql-bin.000001
> output.sql
# 从mysql-bin.000002开始,一直读取到最后一个binlog文件
mysqlbinlog --to-last-log
mysql-bin.000002
# 解析binlog并执行
mysqlbinlog --skip-gtids
mysql-bin.000005 |
mysql -uroot -p
# 指定第一个文件的开始位置和最后一个文件的
# 结束位置,批量解析并执行(超级方便)
mysqlbinlog --skip-gtids
--start-position=193
-stop-position=462
mysql-bin.000003
mysql-bin.000004
mysql-bin.000005 |
mysql -uroot -p
根据position解析binlog
要解析 insert into emp(name) values('bbb') 对应的部分,怎么确定start-position和stop-position呢?步骤如下:
1、使用 mysqlbinlog -v mysql-bin.00000n 命令解析出可识别的binlog。binlog内容看着许多,实则多半是注释和无需关注的,只关注我们需要的即可。
3、DML都是有事务的,会被 BEGIN 和 COMMIT包括着(DDL没有事务);找到对应的INSERT语句,从SQL处往上找到最近的BEGIN,继续往上找最近的at * 找到 497,也就是 start-position就是497;从SQL处往下找到最近的COMMIT,继续往下找最近的at * 找到691,也就是 stop-position就是691;则得到完整的命令为:
mysqlbinlog –start-position=497 –stop-position=691 mysql-bin.000001

关键参数
log_bin
说明:是否开启binlog。
可选值:ON:开启;OFF:不开启。为了数据恢复和主从同步提议开启。
binlog_format
说明:binlog日志格式。
可选值:
- Statement:每一条修改数据的SQL都会记录 binlog 。
- Row:不记录SQL 语句上下文信息,仅保存哪条记录被修改。
- Mixed(Mixed-Based Replication,MBR):Statement 和 Row 的混合体。
binlog_expire_logs_seconds
说明:binlog过期时间,单位秒,0表明永远不过期,大于0表明具体的过期时间。
mysql8之前是 expire_logs_days,单位天。
binlog_expire_logs_auto_purge
说明:binlog过期清理。
可选值:ON:过期自动清理 ,OFF:过期不自动清理,提议设置ON。
要和
binlog_expire_logs_seconds配合,只有
binlog_expire_logs_seconds>0且
binlog_expire_logs_auto_purge=ON 才会触发过期文件自动清理。
binlog_cache_size
说明:binlog的内存缓冲区的大小。
默认32KB,提议设置2~4M。
max_binlog_size
说明:每隔binlog文件的的大小。
默认1G。
sync_binlog
说明:BinLog落盘机制。
可选值:
0:事务提交后,数据只write到OS_Cache但不sync盘(等OS sync盘),最高效;
1:数据write到OS_Cache并立即sync盘,最安全;
n(n>1):数据write OS_Cache但不sync盘,每n个事务sync盘一次,折中方案;
提议平时设置 1。
平时说的双一是指 sync_binlog 和
innodb_flush_log_at_trx_commit 均设置为 1。

















暂无评论内容