主从复制必须设binlog_format=ROW,sync_binlog和innodb_flush_log_at_trx_commit均为1,relay_log_recovery=ON,GTID模式下禁用sql_slave_skip_counter,并确保expire_logs_days足够长。

主从复制中 binlog_format 必须设为 ROW
STATEMENT 或 MIXED 模式下,非确定性函数(如 NOW()、UUID()、SYSDATE())在从库重放时可能产生不一致结果,导致数据逻辑丢失。ROW 格式记录每一行变更的完整镜像,是保证主从数据严格一致的前提。
-
SET GLOBAL binlog_format = 'ROW';仅对新会话生效,需写入my.cnf的[mysqld]段并重启才持久生效 - 已存在业务表若含触发器或外键级联操作,ROW 模式仍能准确捕获最终行变更,但日志体积显著增大
- MySQL 8.0+ 默认为 ROW,但升级后务必确认:执行
SELECT @@binlog_format;验证
sync_binlog 和 innodb_flush_log_at_trx_commit 必须设为 1
这是防止主库崩溃丢事务的核心配置。两者配合才能确保“事务提交”和“binlog 写盘”原子绑定:
-
sync_binlog = 1:每个事务都 fsync binlog 文件,避免 crash 后 binlog 缺失 -
innodb_flush_log_at_trx_commit = 1:每个事务都刷 redo log 到磁盘,保证 InnoDB 层不丢事务 - 若任一值为 0 或 2,主库断电/宕机时可能出现“主库已提交但从库收不到对应 binlog”,造成永久性数据丢失
- 性能影响真实存在,但高可靠场景不可妥协;可通过 SSD + 合理 IOPS 规划缓解
从库必须启用 relay_log_recovery=ON
从库意外宕机重启后,若未开启该参数,可能因 relay log 不完整而跳过部分事件,导致从库数据落后且无法自动修复。
- 设置
relay_log_recovery = ON后,从库启动时会自动丢弃当前不完整的 relay log,并向主库重新拉取缺失的 binlog 位置 - 该参数仅在
relay_log_info_repository = TABLE(推荐)且使用 GTID 时效果最稳定 - 注意:首次启用需重启从库;若之前 relay log 已损坏但未察觉,开启后可能触发全量重同步,建议先检查
SHOW SLAVE STATUS\G中的Relay_Log_File和Relay_Log_Pos
GTID 模式下禁止手动执行 SET GLOBAL sql_slave_skip_counter
在 GTID 模式中,跳过事务会破坏 GTID 执行序列的连续性,后续可能导致从库无法正确计算 Executed_Gtid_Set,引发复制中断甚至数据错乱。
- 遇到错误事务(如 1062 重复键),应使用
STOP SLAVE; SET GTID_NEXT='xxx-xxx-xxx:nnn'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START SLAVE;注入空事务跳过 - 跳过前务必确认错误是否可逆——例如主库误删数据后又插入同主键记录,直接跳过会导致从库丢失该行
- 所有 GTID 相关操作必须在
gtid_mode=ON且enforce_gtid_consistency=ON下进行,否则 MySQL 拒绝启动
expire_logs_days 过短(如设为 1),而从库因网络或负载原因延迟超过 1 天,就会出现“主库 binlog 已清理,从库还来不及拉取”的情况,复制永久中断。监控 Seconds_Behind_Master 和 show master logs 的保留窗口,比调参数更关键。










