一、Binlog 基础认知
1.1 什么是 Binlog
Binary Log(二进制日志,简称 Binlog)是 MySQL 最重要的日志之一,它记录了所有修改数据库数据的操作,包括表结构变更和数据增删改语句,是 MySQL 实现数据恢复、主从复制和数据审计的核心基础MySQL。
1.2 Binlog 的核心作用
- 数据恢复:通过 Binlog 实现时间点恢复(PITR),找回误操作或故障丢失的数据
- 主从复制:从库通过读取主库 Binlog 实现数据同步,保障高可用与负载均衡
- 数据审计:追踪数据变更历史,满足合规性要求
- 数据分析:解析 Binlog 获取业务数据变化趋势,辅助决策
二、核心 Binlog 参数详解
2.1 基础控制参数
| 参数名 | 作用 | 推荐值 | 版本差异 |
|---|---|---|---|
| max_binlog_size | 单个 Binlog 文件最大大小 | 100M-1G | 所有版本支持,默认 1G |
| expire_logs_days | Binlog 自动过期时间(天) | 3-7 天 | 5.7 + 支持,默认 0(永不过期) |
| binlog_format | Binlog 记录格式 | ROW(生产环境) | 5.7/8.0 均支持,可选 STATEMENT/MIXED/ROW |
| sync_binlog | Binlog 同步刷盘策略 | 100-1000(普通场景)/1(金融) | 所有版本支持,默认 1 |
| binlog_cache_size | 单个事务 Binlog 缓存大小 | 32K-1M | 所有版本支持,默认 32K |
| max_binlog_cache_size | 事务 Binlog 缓存最大值 | 1G | 所有版本支持,默认 4G |
| binlog_row_image | ROW 格式下记录的数据量 | minimal | 5.6 + 支持,默认 FULL |
| binlog-ignore-table | 忽略指定表的 Binlog 记录 | 按需配置 | 8.0 + 支持,5.7 不支持 |
2.2 参数详细说明与配置示例
2.2.1 max_binlog_size
控制单个 Binlog 文件的最大大小,当文件达到此值时自动滚动生成新文件。注意:此参数不会严格限制文件大小,事务未完成时会允许文件超出限制。
配置示例:
[mysqld]
max_binlog_size = 100M # 单个binlog最大100MB
2.2.2 expire_logs_days
设置 Binlog 文件的自动过期时间,MySQL 会定期清理超过指定天数的 Binlog 文件。MySQL 5.7 默认没有 max_binlog_files 参数,需通过此参数间接控制 Binlog 数量。
配置示例:
[mysqld]
expire_logs_days = 3 # Binlog保留3天
2.2.3 binlog-ignore-table(MySQL 8.0+)
MySQL 8.0 新增参数,用于指定不需要记录 Binlog 的表,支持通配符。MySQL 5.7 原生不支持该参数,只能通过复制过滤(replicate-ignore-table)间接实现,但本机 Binlog 仍会包含该表操作MySQL。
配置示例:
[mysqld]
# 忽略特定表
binlog-ignore-table=paas_wms_material.qc_report_day
# 忽略整个数据库
binlog-ignore-db=test_db
# 支持通配符(8.0.23+)
binlog-ignore-table=paas_wms_material.*_log
三、Binlog 参数配置方法
3.1 静态配置(my.cnf/my.ini)
编辑 MySQL 配置文件,重启服务后永久生效:
[mysqld]
# 基础配置
server-id = 1 # 必须配置,主从复制标识
log-bin = mysql-bin # 开启Binlog,指定日志前缀
max_binlog_size = 100M
expire_logs_days = 3
# 高级配置(性能优化)
sync_binlog = 100
binlog_format = ROW
binlog_row_image = minimal
binlog_cache_size = 64K
max_binlog_cache_size = 1G
# MySQL 8.0专属
binlog-ignore-table=paas_wms_material.qc_report_day
3.2 动态配置(无需重启)
通过 SQL 命令实时修改,重启后失效:
-- 设置Binlog过期时间为3天
SET GLOBAL expire_logs_days = 3;
-- 设置Binlog文件最大大小为100MB
SET GLOBAL max_binlog_size = 104857600; -- 100*1024*1024
-- MySQL 8.0.14+支持持久化动态设置(重启后不失效)
SET PERSIST expire_logs_days = 3;
SET PERSIST max_binlog_size = 104857600;
注意:动态修改后,新的 Binlog 文件才会使用新参数,已生成的 Binlog 不受影响。
四、Binlog 清理策略详解
4.1 自动清理
-
通过 expire_logs_days 自动清理(推荐)配置后 MySQL 会在后台自动清理过期 Binlog 文件,无需手动干预。
-
触发式自动清理
- 执行 FLUSH LOGS 或 FLUSH BINARY LOGS 时触发清理
- 重启 MySQL 服务时触发清理
- Binlog 文件滚动时触发清理
4.2 手动清理(紧急场景)
4.2.1 按时间清理
sql
-- 清理3天前的Binlog
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);
-- 清理到指定日期前的Binlog
PURGE BINARY LOGS BEFORE '2026-01-13 00:00:00';
4.2.2 按文件名清理
sql
-- 查看当前Binlog文件列表
SHOW BINARY LOGS;
-- 清理到指定文件之前(不包含该文件)
PURGE BINARY LOGS TO 'mysql-bin.000020';
4.2.3 立即滚动 Binlog(参数修改后生效)
sql
FLUSH BINARY LOGS; -- 生成新的Binlog文件,新参数立即生效
警告:手动清理前务必确认从库已同步完成对应 Binlog,避免主从数据不一致。
五、MySQL 5.7 与 8.0 Binlog 差异对比
表格
| 功能 | MySQL 5.7 | MySQL 8.0 | 优化建议 |
|---|---|---|---|
| binlog-ignore-table | ❌ 不支持 | ✅ 支持 | 5.7 用户升级到 8.0,或通过应用层控制 |
| PERSIST 参数 | ❌ 不支持 | ✅ 支持 | 8.0 用户优先使用 SET PERSIST 动态配置 |
| Binlog 加密 | ❌ 不支持 | ✅ 支持(8.0.14+) | 敏感数据场景启用 Binlog 加密 |
| 角色权限控制 | ❌ 基础 | ✅ 完善 | 生产环境使用最小权限原则 |
| 并行复制 | 基础(基于库) | 高级(基于 LOGICAL_CLOCK) | 8.0 用户设置 slave_parallel_workers=8-16 |
六、Binlog 优化实战
6.1 空间优化策略
-
精准控制 Binlog 保留时间
- 结合业务恢复需求设置 expire_logs_days(一般 3-7 天)
- 高写入场景缩短保留时间,或结合 max_binlog_size 控制文件大小
-
选择性记录 Binlog
- MySQL 8.0 使用 binlog-ignore-table/binlog-ignore-db 忽略非关键表
- 5.7 用户通过应用层拆分,将非核心业务移至独立实例
-
ROW 格式优化
sqlbinlog_format = ROW binlog_row_image = minimal # 只记录变更列,减少Binlog体积30%-50%
6.2 性能优化核心策略
表格
| 优化方向 | 关键参数 | 推荐配置 | 适用场景 |
|---|---|---|---|
| 刷盘策略 | sync_binlog | 100-1000 | 非金融场景,平衡性能与安全 |
| 1 | 金融场景,强一致性要求 | ||
| 缓存优化 | binlog_cache_size | 64K-1M | 小事务为主场景 |
| max_binlog_cache_size | 1G | 避免大事务 OOM | |
| I/O 优化 | 存储介质 | 独立 SSD/NVMe | 所有场景,提升写入性能 |
| 组提交 | binlog_group_commit_sync_delay | 100-500μs | 高并发写入场景 |
| binlog_group_commit_sync_no_delay_count | 100 | 高并发写入场景 |
6.3 最佳实践配置示例
bash
[mysqld]
# 基础配置
server-id = 1
log-bin = /data/mysql/binlog/mysql-bin # 独立磁盘存储Binlog
max_binlog_size = 100M
expire_logs_days = 3
# 性能优化
sync_binlog = 100
binlog_format = ROW
binlog_row_image = minimal
binlog_cache_size = 64K
max_binlog_cache_size = 1G
# MySQL 8.0专属优化
binlog-ignore-table=paas_wms_material.qc_report_day
binlog-ignore-table=paas_wms_material.statistics_*
binlog_encryption = ON # 启用Binlog加密
# 组提交优化(5.6+)
binlog_group_commit_sync_delay = 200
binlog_group_commit_sync_no_delay_count = 100
6.4 大事务优化(Binlog 写入性能杀手)
-
拆分大事务
- 将单条 UPDATE/DELETE 10 万行拆分为 10 次 1 万行操作
- 避免一次性导入大量数据,使用分批导入
-
临时关闭 Binlog(谨慎使用)
sqlSET SESSION sql_log_bin = 0; -- 仅当前会话关闭Binlog -- 执行批量操作 SET SESSION sql_log_bin = 1; -- 恢复Binlog记录警告:仅适用于非核心数据批量操作,且需手动同步从库。
七、MySQL Binlog 配置 & 命令 速查清单(可直接复制使用)
7.1 my.cnf 核心配置(直接粘贴至 [mysqld] 段)
sql
# 基础 Binlog 必配
server-id = 1
log-bin = mysql-bin
max_binlog_size = 100M
expire_logs_days = 3
# 性能优化
binlog_format = ROW
binlog_row_image = minimal
sync_binlog = 100
binlog_cache_size = 64K
max_binlog_cache_size = 1G
# 组提交优化
binlog_group_commit_sync_delay = 200
binlog_group_commit_sync_no_delay_count = 100
# MySQL 8.0 专用:忽略表 binlog
binlog-ignore-table=paas_wms_material.qc_report_day
# binlog_encryption = ON
7.2 动态设置命令(无需重启,直接执行)
sql
-- 动态设置过期时间与单文件大小
SET GLOBAL expire_logs_days = 3;
SET GLOBAL max_binlog_size = 104857600;
-- MySQL 8.0 持久化配置(重启不失效)
SET PERSIST expire_logs_days = 3;
SET PERSIST max_binlog_size = 104857600;
-- 手动切换 binlog,使新配置立即生效
FLUSH BINARY LOGS;
7.3 binlog 清理常用命令
sql
-- 查看当前 binlog 列表
SHOW BINARY LOGS;
-- 清理 3 天前的 binlog
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);
-- 按指定时间清理
PURGE BINARY LOGS BEFORE '2026-01-13 00:00:00';
-- 按文件名清理(保留到指定文件)
PURGE BINARY LOGS TO 'mysql-bin.000020';
7.4 临时关闭当前会话 binlog(批量操作专用)
sql
SET SESSION sql_log_bin = 0;
-- 执行批量插入/更新/删除
SET SESSION sql_log_bin = 1;
7.5 状态查看命令
sql
-- 查看主库 binlog 位点
SHOW MASTER STATUS;
-- 查看 binlog 相关参数
SHOW VARIABLES LIKE 'binlog%';
-- 查看 binlog 运行状态
SHOW GLOBAL STATUS LIKE 'Binlog%';
八、常见问题与解决方案
8.1 Binlog 磁盘爆满应急处理
-
临时清理旧 Binlog(确保从库已同步完成)
sql-- 查看从库当前Binlog位置 SHOW SLAVE STATUS\G -- 清理到从库已同步的位置 PURGE BINARY LOGS TO 'mysql-bin.000100'; -
永久解决方案
sqlexpire_logs_days = 2 # 缩短保留时间 max_binlog_size = 50M # 减小单个文件大小
8.2 MySQL 5.7 Binlog 过滤替代方案
由于 MySQL 5.7 不支持 binlog-ignore-table,可通过以下方法实现类似效果:
-
应用层控制:将不需要 Binlog 的操作移至单独数据库连接,临时关闭 Binlog
python
运行
python# Python示例 conn = pymysql.connect(...) conn.cursor().execute("SET SESSION sql_log_bin = 0") # 执行不需要记录的操作 conn.cursor().execute("SET SESSION sql_log_bin = 1") -
复制过滤(仅影响从库,主库 Binlog 仍会记录)
bash[mysqld] replicate-ignore-table=paas_wms_material.qc_report_day
8.3 Binlog 写入性能瓶颈排查
-
查看 Binlog 相关状态
sqlSHOW GLOBAL STATUS LIKE 'Binlog%'; SHOW GLOBAL VARIABLES LIKE 'binlog%'; -
关键指标监控
- Binlog 写入延迟:正常应 < 1ms,高则检查 I/O 子系统
- Binlog 文件切换频率:过高说明 max_binlog_size 设置过小
- 大事务比例:通过 binlog_cache_disk_use 监控,比例过高需拆分事务
九、总结与最佳实践清单
-
基础配置必选
- 开启 Binlog(log-bin=mysql-bin)并设置 server-id
- 配置 max_binlog_size=100M-1G 和 expire_logs_days=3-7
- 生产环境使用 binlog_format=ROW 和 binlog_row_image=minimal
-
版本升级建议
- MySQL 5.7 用户尽快升级到 8.0,获得 binlog-ignore-table 等高级功能
- 新部署环境直接使用 MySQL 8.0.26 + 版本
-
运维必备命令
sql-- 查看Binlog列表 SHOW BINARY LOGS; -- 查看Binlog状态 SHOW MASTER STATUS; -- 手动清理Binlog PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY); -- 滚动Binlog FLUSH BINARY LOGS;
Binlog 作为 MySQL 的核心组件,合理配置与优化不仅能提升系统性能,还能保障数据安全。建议结合业务场景定期评估 Binlog 策略,在数据恢复需求、存储成本和系统性能之间找到最佳平衡点。