必须设为AFTER_SYNC才能防丢数据:主库先fsync binlog再等从库relay log落盘后才提交事务;AFTER_COMMIT则先提交再发binlog,主库宕机时已提交事务仍可能丢失。
必须设为,否则半同步不防丢数据。
默认值虽已是
(MySQL 5.7+),但升级、重装或从旧版本迁移后常被忽略,导致实际运行在
模式下——主库宕机时已提交事务仍可能丢失。
为什么
才算真正“无损”
关键区别不在“等不等 ACK”,而在“提交时机”:
:主库写完 binlog 并
到磁盘 → 等至少一个从库写入 relay log 并
→ 再提交事务到 InnoDB(即打上
标签)→ 客户端才收到成功响应
:主库先提交事务到 InnoDB → 再发 binlog → 再等 ACK → 若此时主库 crash,事务已提交但 binlog 还没发完,从库收不到,数据就丢了
换句话说:
把“客户端看到数据”和“数据已安全落盘到至少一个从库”严格对齐;
只保证“主库自己认为完成了”,不保证别人能拿到。
如何确认并强制生效
该变量是会话级只读变量,不能用
修改,必须用
,且仅对后续新事务生效:
验证是否生效:
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
查当前值:
(注意 MySQL 8.0+ 中变量名含
,不是
)
查半同步状态:
关注
是否为
,以及
是否 ≥1
检查从库是否真在接收:在从库执行
,确认
非 NULL 且
为
⚠️ 注意:该设置不持久化,MySQL 重启后失效。需写入配置文件(如
)的
段:
常见踩坑点:你以为启用了,其实没生效
以下情况会导致
形同虚设:
主库插件未启用:
(8.0+)或
(5.7)
从库插件未启用或未开启:
+
网络超时后自动降级为异步:
默认 10s,超时后主库继续提交,但不再等 ACK —— 此时
变为
,需监控告警
主库双 1 未配齐:
和
缺一不可;否则 binlog 或 redo log 可能只在 OS cache,crash 后丢失
真正难的不是设这个参数,而是确保整个链路:主库 binlog 落盘 → 网络可靠 → 从库 relay log 落盘 → 主库收到 ACK → 事务才提交。任何一个环节松动,
就守不住一致性边界。
AFTER_SYNCAFTER_SYNCAFTER_COMMITAFTER_SYNCAFTER_SYNCfsyncfsyncCOMMITTEDAFTER_COMMITAFTER_SYNCAFTER_COMMITrpl_semi_sync_master_wait_pointSET SESSIONSET GLOBALSET GLOBAL rpl_semi_sync_source_wait_point = 'AFTER_SYNC';SELECT @@rpl_semi_sync_source_wait_point;sourcemasterSHOW STATUS LIKE 'Rpl_semi_sync%';Rpl_semi_sync_source_statusONRpl_semi_sync_source_clientsSHOW SLAVE STATUS\GSeconds_Behind_MasterSlave_SQL_RunningYesmy.cnf[mysqld]rpl_semi_sync_source_wait_point=AFTER_SYNCAFTER_SYNCINSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';semisync_master.soINSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';SET GLOBAL rpl_semi_sync_replica_enabled = ON;rpl_semi_sync_source_timeoutRpl_semi_sync_source_statusOFFsync_binlog = 1innodb_flush_log_at_trx_commit = 1AFTER_SYNC