MySQL 半同步复制(semi-synchronous replication)是介于异步复制与全同步复制之间的折中方案:主库在提交事务前,至少等待一个从库确认收到 binlog,从而降低数据丢失风险。但很多 DBA 在配置后遇到性能骤降或故障切换失效的问题,根源往往在于对半同步复制的工作机制理解不深。本文直接围绕配置与故障切换中的关键问题,逐层排查并提供可操作的步骤。
半同步复制的核心机制与适用条件
半同步复制通过插件实现(rpl_semi_sync_master 和 rpl_semi_sync_slave)。主库在提交事务时,会阻塞等待从库的 ACK 确认,确认代表从库已收到 binlog 并写入中继日志,但尚未应用。这种设计保证了事务在主库提交时,至少有一份 binlog 副本在从库,从而在主库崩溃时减少数据丢失。
适用条件:对数据安全要求高于性能、且网络延迟较低的环境。若网络抖动频繁,半同步复制会导致主库事务提交延迟显著增加。因此,在配置前需评估业务对写入延迟的容忍度。
配置半同步复制的具体步骤
以下步骤基于 MySQL 5.7 及以上版本(8.0 同样适用)。
- 安装插件:在主库和从库分别执行:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; - 启用半同步:设置相关变量。主库:
SET GLOBAL rpl_semi_sync_master_enabled = 1; SET GLOBAL rpl_semi_sync_master_timeout = 1000; -- 毫秒,超时后降级为异步从库:
SET GLOBAL rpl_semi_sync_slave_enabled = 1; - 重启 IO 线程:从库执行
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;使设置生效。 - 持久化配置:在配置文件
my.cnf中加入相应选项,防止重启丢失。
验证是否启用:主库执行 SHOW STATUS LIKE 'Rpl_semi_sync_master_status';,返回 ON 表示成功。同时关注 Rpl_semi_sync_master_tx_avg_wait_time 等状态变量,评估延迟。
故障切换的关键点与操作流程
半同步复制并非高可用解决方案,它只保证数据复制的一致性。故障切换通常依赖第三方工具(如 MHA、Orchestrator)或手动提升从库。在切换时,需注意以下几点:
确认从库数据是最新的
在提升从库前,检查从库的 Seconds_Behind_Master 是否为 0,以及 Relay_Master_Log_File 和 Exec_Master_Log_Pos 是否与主库最新 binlog 位置一致。若半同步复制因超时降级为异步,从库可能落后,此时提升会丢失数据。
处理未提交的 ACK
主库崩溃时,可能有事务已提交但未收到从库 ACK。根据 MySQL 官方文档,这些事务在主库上已提交,但从库可能尚未收到 binlog。因此,提升从库时需检查从库是否包含这些事务,否则需要手动补偿或接受数据丢失。
切换后的重新配置
提升的从库变为新主库,需重新启用半同步插件,并调整其他从库的复制指向。同时,原主库若恢复,应作为新主库的从库重新配置,避免双主冲突。
常见陷阱与性能调优
- 陷阱1:超时设置过长。若
rpl_semi_sync_master_timeout设置过大,主库会长时间阻塞,导致写入延迟飙升。建议根据网络延迟设置合理值(如 1000ms),并监控超时次数。 - 陷阱2:从库 ACK 丢失。半同步复制要求从库启用 binlog 和中继日志,且
log_slave_updates需开启,否则从库无法转发 ACK。 - 陷阱3:多从库时的 ACK 策略。MySQL 默认等待任意一个从库 ACK,但若该从库落后,数据仍可能丢失。可通过
rpl_semi_sync_master_wait_for_slave_count设置等待的从库数量,但会增加延迟。 - 性能调优:使用
rpl_semi_sync_master_wait_point参数控制等待时机。默认AFTER_SYNC在 binlog 写入后等待 ACK,可减少数据丢失;AFTER_COMMIT则在提交后等待,性能更好但风险更高。根据业务权衡。
监控与故障排查
半同步复制的状态变量是监控的关键。通过 SHOW STATUS LIKE 'Rpl_semi_sync%' 可查看主库的等待次数、超时次数、切换状态等。若发现 Rpl_semi_sync_master_status 变为 OFF,说明已降级为异步,需检查网络或从库状态。
在排查问题时,日志是重要依据。根据 OWASP 日志安全速查表,应用日志应记录安全事件,但数据库的复制状态同样需要记录。建议将半同步复制状态变量纳入监控系统,并设置告警。同时,可参考 OpenTelemetry 日志规范,将复制状态作为日志的一部分,便于关联分析。
与异步复制的对比及取舍
异步复制下,主库提交事务无需等待从库,性能最好但数据丢失风险高。半同步复制在性能和安全性间取得平衡,但并非零丢失:若主库崩溃且从库未收到 ACK,事务仍可能丢失。全同步复制(如 MySQL Group Replication)可保证强一致,但性能开销大,且对网络要求极高。
因此,选择半同步复制时,需明确业务对 RPO(恢复点目标)的要求。若要求 RPO=0,可能需要考虑其他方案;若可接受秒级丢失,半同步复制是合理选择。
总结
MySQL 半同步复制配置并不复杂,但故障切换和性能调优需要深入理解机制。本文从配置步骤、切换要点、常见陷阱到监控调优,提供了完整的实操指引。记住,半同步复制不是银弹,务必结合业务需求评估风险,并建立完善的监控和告警体系。
参考资料
延伸阅读
