mysql主从复制如何防止数据丢失_mysql安全策略说明

14次阅读

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

mysql 主从复制如何防止数据丢失_mysql 安全策略说明

主从复制中 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 STATUSG 中的 Relay_Log_FileRelay_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=ONenforce_gtid_consistency=ON 下进行,否则 MySQL 拒绝启动

真正容易被忽略的是:即使上述配置全部正确,如果主库启用了 expire_logs_days 过短(如设为 1),而从库因网络或负载原因延迟超过 1 天,就会出现“主库 binlog 已清理,从库还来不及拉取”的情况,复制永久中断。监控 Seconds_Behind_Mastershow master logs 的保留窗口,比调参数更关键。

text=ZqhQzanResources