rpl_semi_sync_master_status在on/off间跳变不是插件故障,而是主库明确提示未收到从库ack;需结合rpl_semi_sync_master_off_times和rpl_semi_sync_master_no_times趋势判断:每小时涨几十次为系统性瓶颈,偶发跳变为瞬时抖动,须排查从库tcp接收队列、io负载及ack生成逻辑。

怎么看Rpl_semi_sync_master_status在ON/OFF间跳变是不是真问题
状态来回切换不是插件坏了,而是主库在明确告诉你:它等不到ACK。只查Rpl_semi_sync_master_status = ON没用,必须结合Rpl_semi_sync_master_off_times和Rpl_semi_sync_master_no_times看趋势。
如果这两个值每小时涨几十次,说明不是偶发抖动,是系统性瓶颈;如果只是偶尔跳一次,可能就是瞬时网络毛刺。别急着调rpl_semi_sync_master_timeout,先确认是否真有从库在参与半同步:
-
SHOW STATUS LIKE 'Rpl_semi_sync_master_clients';—— 看当前连上并声明支持半同步的从库数量 - 挨个登录每个从库,检查
rpl_semi_sync_slave_enabled和Rpl_semi_sync_slave_status是否都为ON - 重点看
Rpl_semi_sync_master_no_tx:这个值增长,代表主库提交了事务但始终没收到任何ACK,比off_times更直接反映“完全失联”
为什么调大rpl_semi_sync_master_timeout反而让问题更难定位
rpl_semi_sync_master_timeout设得过大(比如10000毫秒),会让单个事务卡住10秒才降级,业务明显卡顿,但你却看不到频繁跳变——表象是“稳定”,实则是掩盖了底层传输失败。它单位是毫秒,合理值取决于真实RTT和负载波动:
- 局域网(RTT 0.5–2ms):起点设
1000,覆盖99%尖峰抖动足够 - 跨机房或高负载(RTT偶发15ms+):可设
3000~5000,但别碰默认10000 - 绝对不要设低于
500:UDP小包丢包率>0.1%时,100毫秒超时几乎必降级 - 改完立刻生效:
SET GLOBAL rpl_semi_sync_master_timeout = 3000;,无需重启
从库TCP接收队列和IO负载才是沉默杀手
主库收不到ACK,不一定是网络断了,更可能是从库内核把ACK包丢了,或者SQL线程根本没空处理。常见但容易被忽略的点:
- 从库
net.ipv4.tcp_rmem过小(如仍用默认4096 16384 32768),导致小ACK包被内核丢弃或延迟 - 从库正在执行大查询或备份,
Slave_IO_Running: Yes但Seconds_Behind_Master持续上涨,说明relay log写入已滞后 - 开了并行复制(
slave_parallel_workers > 0)但slave_parallel_type = DATABASE,SQL线程未执行完就提前发了ACK,主库误判成功 - 查从库
SHOW PROCESSLIST,重点关注State为Waiting for master to send event或Reading event from the relay log是否长期卡住
怎么确认是网络抖动还是从库能力不足
单纯ping或mtr看延时不够,因为半同步依赖的是TCP ACK往返,不是ICMP。要抓关键指标:
- 主库侧:
tcpdump -i any port 3306 -w semi-sync.pcap,过滤出主库发binlog后是否收到对应ACK(注意:ACK是纯TCP层,无MySQL协议内容) - 从库侧:
ss -i看rcv_space和rcv_ssthresh是否长期接近上限,netstat -s | grep "packet receive errors"查是否有丢包 - 对比
Rpl_semi_sync_master_no_times增长速率和Com_commit速率:如果前者占后者5%以上,基本可以判定是ACK通路不稳定 - 临时关闭从库其他负载(如备份、慢查询监控脚本),观察
Rpl_semi_sync_master_status是否稳定为ON
rpl_semi_sync_master_wait_point = AFTER_SYNC,也不能绕过网络传输和从库内核接收这俩物理环节。











