不能。半同步复制仅保证至少一个从库接收并刷盘binlog,不保证事务已在从库执行完毕,因此无法确保主从实时一致,且受超时退化、未提交事务、ddl、非事务引擎及主从持久化配置等因素影响。

半同步复制不能保证主从数据“完全一致”,它只确保主库事务至少被一个从库接收并刷盘 relay log,不保证该事务已在从库执行完毕。想靠它实现强一致性,会踩坑。
为什么 SHOW SLAVE STATUS 显示 0 却查不到新数据
这是最典型的误解场景:主库 INSERT 返回成功,从库 SHOW SLAVE STATUS 中 Seconds_Behind_Master: 0,但立刻 SELECT 却看不到刚插入的记录。
原因很直接:半同步只要求从库的 IO 线程把 binlog 写入 relay log 并刷盘(relay_log_info_repository = TABLE 且 sync_relay_log = 1 时才真正落盘),SQL 线程还没来得及回放。数据还在 relay log 里,没进表。
- 检查是否真在回放:在从库运行
SHOW PROCESSLIST,确认有Slave_SQL_Running: Yes且状态不是Waiting for an event from Coordinator这类空转态 - 查 relay log 进度:
SELECT * FROM performance_schema.replication_applier_status_by_coordinator(5.7+)或看Relay_Log_File和Relay_Log_Pos是否在推进 - 避免误判:别只盯
Seconds_Behind_Master,它基于 SQL 线程时间戳计算,大事务、系统时间不同步都会让它失真
如何确认半同步真的在生效,而不是“假开启”
装插件、设变量、重启服务只是第一步。MySQL 半同步在运行中极易因网络抖动、从库 IO 延迟、磁盘满等原因被自动关闭,必须查实时状态。
- 主库上必须同时满足两个条件:
SELECT @@rpl_semi_sync_master_status返回ON,且SELECT @@rpl_semi_sync_master_clients> 0 - 从库上:
SELECT @@rpl_semi_sync_slave_status返回ON,且SHOW PROCESSLIST中能看到semi sync相关线程(如Slave_IO_State含 “Waiting for master to send event”) - 关键陷阱:
rpl_semi_sync_master_enabled是动态变量,但它的值为ON不代表当前链路有效——它可能刚被内核置为OFF,需每 5 分钟轮询一次以上状态
主库 INSERT 变慢,是不是半同步拖的
是,而且这是设计使然。主库提交事务时,必须等待至少一个从库返回 ACK(默认超时 10 秒,由 rpl_semi_sync_master_timeout 控制),这个 RTT 就是延迟来源。
- 性能影响真实存在:电商实测显示,99% 的事务延迟增加 5–20ms;若网络 RTT 达到 30ms,延迟会直接翻倍
- 退化机制要警惕:当所有从库超时或断连,主库自动降级为异步模式(
rpl_semi_sync_master_status变为OFF),此时一致性保障瞬间失效,但业务无感知 - 调优重点不在“加速”,而在“可控”:把
rpl_semi_sync_master_timeout设为 1000000(1 秒)而非默认 10000000(10 秒),避免单次卡顿过长;rpl_semi_sync_master_wait_for_slave_count保持为 1,设更高值只会放大延迟,不提升可靠性下限
配置后仍丢数据?这些细节常被忽略
半同步本身不解决持久化问题。即使从库收到了 binlog 并刷盘 relay log,如果它自己崩溃且未启用 sync_relay_log = 1,那 relay log 也可能丢失。
- 主库侧必须配牢:
sync_binlog = 1+innodb_flush_log_at_trx_commit = 1,否则主库崩溃照样丢事务 - 从库侧同样关键:
sync_relay_log = 1+relay_log_info_repository = TABLE,否则 ACK 只是“内存收到”,非“磁盘落定” - GTID 要配套:不启用
gtid_mode = ON,故障切换时容易因 binlog position 错位导致跳过事务或重复执行,一致性反而更差
半同步真正的价值,是把“主库单点崩溃导致数据丢失”的概率压到极低,而不是让主从变成实时镜像。它是个保险绳,不是同步锁。任何指望它替代应用层幂等、最终一致性校验或 pt-table-checksum 的做法,都会在某个凌晨三点被报警叫醒。











