rpl_semi_sync_master_status从on变off是主库因未收到ack而主动降级为异步,并非插件故障;根本原因是rpl_semi_sync_master_timeout设置不当,无法匹配实际网络rtt峰值或从库响应延迟,导致超时即退化。

Rpl_semi_sync_master_status 从 ON 变 OFF 不是插件坏了,而是主库在告诉你:它没等到 ACK。
为什么网络抖动会触发降级
半同步不是“永远等”,而是“只在能稳住的时候才坚持”。主库提交事务时,必须在 rpl_semi_sync_master_timeout 毫秒内收到至少一个从库的 ACK(即 relay log 已写盘并确认),否则立刻退为异步,不阻塞、不报错、不重试。
- 一次 RTT 尖峰(比如从 1ms 飙到 8ms)就可能超时,尤其当
rpl_semi_sync_master_timeout设为 100 或 500 这类低值时 - UDP 小包丢包率 > 0.1%(比 ping 更贴近 ACK 行为)会让 100ms 超时几乎必降级
- 主库不检测从库状态,也不发心跳——它只在每个 COMMIT 瞬间发起一次等待,失败即切异步
查什么才能定位真问题
只看 rpl_semi_sync_master_enabled = 1 或 SHOW SLAVE STATUS 完全没用。真实状态全在主库运行时指标里:
-
Rpl_semi_sync_master_status= OFF:当前已退异步(结果,不是原因) -
Rpl_semi_sync_master_off_times每小时涨几十次 → 网络或从库 IO 已扛不住,不是参数问题 -
Rpl_semi_sync_master_no_times持续上涨但off_times几乎不涨 → 从库响应慢(比如 sync_relay_log=0、磁盘慢、SQL 线程积压) -
SHOW STATUS LIKE 'Rpl_semi_sync_master_clients':确认真有从库注册为半同步客户端
rpl_semi_sync_master_timeout 怎么设才不瞎调
它不是越长越安全,也不是越短越“强一致”。设错反而放大风险:
- 太短(
- 太长(≥10000ms,默认值)→ 单事务卡 10 秒,用户侧直接超时,而主库还在傻等
- 局域网环境:设 1000~2000(覆盖 P95 RTT + relay log fsync 耗时)
- 跨机房或高负载:3000~5000,别碰 10000;改完立即生效:
SET GLOBAL rpl_semi_sync_master_timeout = 3000
降级后不会自己恢复,这点最容易被忽略
主库不会轮询、不发心跳、不检测从库是否“好了”。它安静地等下一个事务来重新走一遍等待流程。如果主库空闲,Rpl_semi_sync_master_status 就一直卡在 OFF —— 你得主动触发轻量事务(比如 INSERT INTO heartbeat VALUES (NOW()))才能让它重试。监控告警只是第一步,没配套的自动恢复动作,等于白看。











