MySQL 是否开启 binlog 需执行 SHOW VARIABLES LIKE 'log_bin' 确认返回 ON;仅配置文件含 log-bin 不足,须确保路径可写、未被 skip-log-bin 覆盖且重启后验证。

如何确认 MySQL 是否已开启 binlog
直接查 SHOW VARIABLES LIKE 'log_bin',返回 ON 才算真正启用。别只看配置文件里有没有 log-bin,MySQL 启动失败或路径不可写时,它会静默关闭 binlog 且不报错。
常见错误现象:mysqld 进程在运行,但 SHOW MASTER STATUS 报错 ERROR 1378 (HY000): The server is not configured with binary logging —— 这说明配置没生效,不是权限或语法问题。
- 检查
my.cnf(或my.ini)中是否写了log-bin = /var/lib/mysql/mysql-bin(路径必须可写、目录存在、无中文/空格) - 确认没有被
skip-log-bin覆盖(尤其在 Docker 或云数据库的启动脚本里) - 重启后执行
mysql -u root -p -e "SHOW VARIABLES LIKE 'log_bin';"验证,别只依赖配置文件内容
binlog_format 必须设为 ROW 还是 MIXED
除非你明确依赖 STATEMENT 的低空间占用且业务全是确定性 SQL,否则一律用 ROW。MySQL 5.7+ 默认已是 ROW,但升级或迁移后容易被忽略。
使用场景差异明显:STATEMENT 在 NOW()、UUID()、自增主键插入等场景下主从不一致;MIXED 自动切换但行为难预测;ROW 安全但日志体积大、解析需专用工具(如 mysqlbinlog --base64-output=DECODE-ROWS)。
-
binlog_format = ROW是线上生产环境事实标准,DDL 语句仍以 statement 形式记录,不影响 DML 一致性 - 如果用 Canal / Debezium 做实时同步,必须
ROW,否则拿不到变更字段级数据 - 不要在会话级临时改
binlog_format,DML 可能混入不同格式,增加恢复和审计难度
如何安全清理过期 binlog 文件
别手动 rm 删除 mysql-bin.* 文件,MySQL 不会自动更新 index 文件,下次重启可能报错或跳过部分日志。
正确方式只有两个:PURGE BINARY LOGS SQL 命令,或配置 expire_logs_days 让 MySQL 自动清理。后者更稳妥,但注意:该参数单位是「天」,且只对非当前活跃日志生效。
- 立即清理:执行
PURGE BINARY LOGS TO 'mysql-bin.000123';(目标文件名必须存在于SHOW BINARY LOGS;列表中) - 长期管理:设
expire_logs_days = 7,MySQL 每次启动和每小时检查一次过期日志 - 误删后发现
SHOW MASTER STATUS显示的File不在SHOW BINARY LOGS;里?说明 index 已损坏,需重启 mysqld 并检查错误日志
binlog 开启后磁盘爆满怎么办
根本原因往往不是日志太多,而是没设置 max_binlog_size + expire_logs_days 组合策略,或者应用有大量小事务未合并(比如逐行 update)。
性能影响真实存在:binlog 写入是串行刷盘操作,sync_binlog = 1(推荐值)会略微降低写入吞吐,但能保主从一致性;设为 0 则崩溃可能丢日志。
- 先紧急释放空间:
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 1 DAY); - 检查是否有长事务阻塞清理:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 3600; -
max_binlog_size = 100M比默认 1G 更利于监控和归档,但太小会导致频繁切日志,增加索引维护开销
最常被忽略的一点:从库开启 log_slave_updates 后,它也会写 binlog,如果做级联复制却不清理,磁盘增长速度是双份的。


















