mysql的异步复制与半同步复制模式的选择

7次阅读

异步复制在主库崩溃时会丢数据,因为主库写入成功即返回客户端,不等待从库确认,未发送的binlog事件永久丢失。

mysql的异步复制与半同步复制模式的选择

异步复制为什么在主库崩溃时会丢数据

mysql 默认的异步复制(AFTER_COMMITAFTER_SYNC 模式未启用)下,主库写入成功后就返回客户端 OK,不等待从库确认。此时 binlog 虽已刷盘,但 relay log 在从库可能还没开始拉取,或刚写入 OS cache 未落盘。

常见错误现象:主库宕机后切从库,发现最新几秒的事务完全丢失;监控显示 Seconds_Behind_Master 为 0,但实际仍有未应用的 Event 缓存在 SQL 线程内存中。

  • 主库 crash 后,未发送到从库的 binlog event 永久丢失
  • 从库 IO 线程延迟(如网络抖动、磁盘慢)不会阻塞主库,但放大数据不一致窗口
  • sync_binlog=1innodb_flush_log_at_trx_commit=1 只保主库本地持久性,不解决复制级一致性

半同步复制不是“强一致”,而是“至少一个从库收到”

半同步(rpl_semi_sync_master_enabled=ON)要求主库至少收到一个从库的 ACK(收到并写入 relay log 文件),才提交事务。但它不保证该事务已被从库 SQL 线程执行,也不保证 ACK 是 fsync 到磁盘后的——取决于从库配置 rpl_semi_sync_slave_enabledrelay_log_info_repository=table 是否开启。

使用场景:对 RPO(恢复点目标)有硬性要求(比如不能丢超过 1 个事务),且能接受主库提交延迟升高(典型增加 1–5ms)。

  • 若所有从库都不可用,半同步自动降级为异步(由 rpl_semi_sync_master_timeout 控制超时时间,默认 10s)
  • MySQL 5.7+ 支持 AFTER_SYNC 模式(默认),主库 commit 前等 ACK,崩溃后可保证从库有完整事务;5.5/5.6 是 AFTER_COMMIT,主库 commit 后等 ACK,崩溃仍可能丢
  • 必须同时在主从两端安装插件:INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so' 和对应 slave 插件

选异步还是半同步?关键看你的 RPO 和 TP99 延迟容忍度

没有银弹。异步复制吞吐高、延迟低,适合日志类、分析类业务;半同步牺牲部分性能换确定性,适合订单、支付等核心事务。

  • 如果业务能容忍分钟级数据丢失(例如离线报表库),用异步 + 定期备份更简单可靠
  • 如果要求“主挂了立刻切,数据不能少”,半同步是底线,但需配合 read_only=ON、从库定期 STOP SLAVE; START SLAVE; 防 relay log 积压
  • 不要只看复制模式:max_allowed_packet 不一致会导致半同步握手失败静默退化;从库 slave_parallel_workers > 0 时,ACK 时间点可能滞后于实际写入顺序
-- 检查当前半同步状态(主库) SELECT * FROM performance_schema.replication_applier_status_by_coordinator; SHOW VARIABLES LIKE 'rpl_semi_sync%'; SHOW STATUS LIKE 'Rpl_semi_sync%'; 

-- 查看是否真正生效(Rpl_semi_sync_master_status = ON 且 Rpl_semi_sync_master_clients > 0)

半同步的“半”字很准确——它不解决故障切换逻辑、不防止脑裂、不替代备份。真正容易被忽略的是:当网络分区发生时,主库可能因超时降级,而你监控里只看到“semi sync is on”,却没盯住 Rpl_semi_sync_master_no_times 这个计数器是否在涨。

text=ZqhQzanResources