MySQL 半同步复制配置与故障切换

MySQL半同步复制在异步复制基础上增加了数据安全保证,但配置不当会引发性能问题或故障切换失效。本文从原理出发,逐步演示配置方法,分析故障切换中的关键点与常见误区。

MySQL 半同步复制配置与故障切换
封面图:ZuCDN · ZuCDN 原创

MySQL 半同步复制(semi-synchronous replication)是介于异步复制与全同步复制之间的折中方案:主库在提交事务前,至少等待一个从库确认收到 binlog,从而降低数据丢失风险。但很多 DBA 在配置后遇到性能骤降或故障切换失效的问题,根源往往在于对半同步复制的工作机制理解不深。本文直接围绕配置与故障切换中的关键问题,逐层排查并提供可操作的步骤。

半同步复制的核心机制与适用条件

半同步复制通过插件实现(rpl_semi_sync_masterrpl_semi_sync_slave)。主库在提交事务时,会阻塞等待从库的 ACK 确认,确认代表从库已收到 binlog 并写入中继日志,但尚未应用。这种设计保证了事务在主库提交时,至少有一份 binlog 副本在从库,从而在主库崩溃时减少数据丢失。

适用条件:对数据安全要求高于性能、且网络延迟较低的环境。若网络抖动频繁,半同步复制会导致主库事务提交延迟显著增加。因此,在配置前需评估业务对写入延迟的容忍度。

配置半同步复制的具体步骤

以下步骤基于 MySQL 5.7 及以上版本(8.0 同样适用)。

  1. 安装插件:在主库和从库分别执行:
    INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
    INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
  2. 启用半同步:设置相关变量。主库:
    SET GLOBAL rpl_semi_sync_master_enabled = 1;
    SET GLOBAL rpl_semi_sync_master_timeout = 1000; -- 毫秒,超时后降级为异步

    从库:

    SET GLOBAL rpl_semi_sync_slave_enabled = 1;
  3. 重启 IO 线程:从库执行 STOP SLAVE IO_THREAD; START SLAVE IO_THREAD; 使设置生效。
  4. 持久化配置:在配置文件 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_FileExec_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 半同步复制配置并不复杂,但故障切换和性能调优需要深入理解机制。本文从配置步骤、切换要点、常见陷阱到监控调优,提供了完整的实操指引。记住,半同步复制不是银弹,务必结合业务需求评估风险,并建立完善的监控和告警体系。

参考资料

延伸阅读