mysql主从切换无法实现绝对零丢失,但通过半同步生效验证、位点对齐校验、sync_binlog与innodb_flush_log_at_trx_commit设为1、双从库冷备及延迟监控等组合措施可将丢失风险降至极低。

MySQL 主从切换时无法靠单一配置实现“零丢失”,但通过组合配置、严格校验和流程控制,能把数据丢失风险压到极低水平。核心不是“有没有半同步”,而是“它是否真在起作用”以及“切主时选的库到底执行到哪了”。
确认半同步真正生效,而不是形同虚设
很多团队开了 rpl_semi_sync_master_enabled=1 就以为万事大吉,结果切主时发现一直 fallback 到异步模式。关键要看实时状态,不是变量值:
- 执行
SHOW STATUS LIKE 'Rpl_semi_sync%',重点检查:Rpl_semi_sync_master_status 必须为ON,且 Rpl_semi_sync_master_no_tx 应长期为0;非零说明已有事务降级提交 - 从库必须运行
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;(不是START SLAVE),否则插件不响应、无法上报 ACK - 主库插件名是
rpl_semi_sync_master,从库是rpl_semi_sync_slave,装反或漏装会导致Rpl_semi_sync_master_clients = 0 - 检查插件文件是否存在:
ls -l $(mysql -Nse "SELECT @@plugin_dir")/semisync_*.so;5.7 以下版本需手动补全,且注意架构(x86_64/aarch64)匹配
切主前必须验证两个执行位点是否对齐
只看 Seconds_Behind_Master = 0 是危险的——SQL 线程可能卡在某个大事务里,IO 已追平但实际没执行。真正要确认的是:
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
- Read_Master_Log_Pos == Exec_Master_Log_Pos:表示从库不仅收到了日志,而且已全部执行完毕
-
Slave_SQL_Running_State 显示
Slave has read all relay log,而非Reading event from the relay log - 用
mysqlbinlog对比主库最新 binlog position 和从库SHOW SLAVE STATUS\G中的Read_Master_Log_Pos,差值过大说明 IO 延迟高,半同步容易超时退化
强制主库不丢日志,为切换兜底
即使半同步生效,若主库崩溃时 binlog 或 redo 日志还没刷盘,照样丢已提交事务。必须配齐这两项:
- sync_binlog = 1:每次事务提交都强制刷 binlog 到磁盘
- innodb_flush_log_at_trx_commit = 1:每次事务提交都刷 redo log,保证崩溃后可恢复
- 这两个参数开启后性能略有下降,但在金融、交易类场景属于硬性底线
生产环境建议补上三道防线
半同步只是其中一环,真实故障下必须多层防护:
- 部署至少两个从库,其中一个设为
skip_slave_start = 1+read_only = ON,只收日志不执行,作为“冷备半同步节点”,切主前再启动 SQL 线程并校验位点 - 用
pt-heartbeat或自建心跳表持续监控复制延迟,不能只依赖Seconds_Behind_Master - 切换前人工或脚本强制停写:设置原主库
super_read_only = ON,等所有从库Exec_Master_Log_Pos对齐后再提升










