在 MySQL 中,默认的 异步复制(Asynchronous Replication)不会等待从库确认即可提交事务;半同步复制(Semisynchronous Replication)会在主库提交时至少等待一个从库接收到并写入二进制日志后才返回;而真正的 同步复制(Synchronous Replication)通常通过 Group Replication 或 MySQL Cluster(NDB) 实现,它们使用内部协议保证事务在所有成员上都已提交后才算完成。下面分别介绍如何检测当前所用的复制模式。
一、检测异步复制
MySQL 默认即为异步复制,无需额外配置。如果未安装或启用半同步插件,也没有部署 Group Replication,那么集群即处于异步复制状态。
-
验证半同步插件是否启用:
SHOW VARIABLES LIKE 'rpl_semi_sync_source_enabled'; SHOW VARIABLES LIKE 'rpl_semi_sync_replica_enabled';
两者若均为
OFF
(或0
),则当前采用的是异步复制 (Severalnines, MySQL Developer Zone)。 -
检查复制状态:
SHOW SLAVE STATUS\G
如果
Slave_IO_Running
和Slave_SQL_Running
都为Yes
,且无半同步相关状态变量,则为标准异步复制 (MySQL Developer Zone)。
二、检测半同步复制
半同步复制依赖插件,需要在主库和从库两端都启用:
-
查看系统变量
SHOW VARIABLES LIKE 'rpl_semi_sync_source_enabled'; SHOW VARIABLES LIKE 'rpl_semi_sync_replica_enabled';
rpl_semi_sync_source_enabled=ON
表示主库启用了半同步复制;rpl_semi_sync_replica_enabled=ON
表示至少有一个从库启用了半同步复制 (MySQL Developer Zone, MariaDB)。
-
监控运行时状态
SHOW STATUS LIKE 'Rpl_semi_sync_source_status';
Rpl_semi_sync_source_status=ON
表示当前事务正在以半同步模式提交;- 如果值为
OFF
则已回退到异步 (MySQL Developer Zone, MySQL Developer Zone)。
-
从库确认情况
SHOW STATUS LIKE 'Rpl_semi_sync_replica_status';
1
表示从库的 I/O 线程正在以半同步模式接收数据;否则为异步 (MySQL Developer Zone, MariaDB)。
三、检测同步复制(Group Replication / NDB Cluster)
MySQL 原生不支持完全同步复制,需使用 Group Replication 插件或 MySQL Cluster(NDB)。
3.1 Group Replication
-
检查插件和通道
SHOW STATUS LIKE 'group_replication_%'; SELECT * FROM performance_schema.replication_group_members;
- 如果能查询到
group_replication_applier
、group_replication_recovery
通道,以及replication_group_members
表中的成员列表,表明已部署 Group Replication (MySQL Developer Zone, MySQL Developer Zone)。
- 如果能查询到
-
确认单主/多主模式
SHOW VARIABLES LIKE 'group_replication_single_primary_mode';
ON
表示单主模式;OFF
表示多主模式,但均为“虚拟同步”,在提交时需要多数派节点确认 (Amazon Web Services, Inc.)。
3.2 MySQL Cluster(NDB)
-
检查 NDB 引擎
SHOW ENGINES;
- 查看
NDB
或NDBCLUSTER
是否支持;
- 查看
-
查询节点组配置
SELECT * FROM INFORMATION_SCHEMA.CLUSTER_NODES;
- NDB Cluster 默认采用两阶段提交,保证在多个数据节点上同步写入后才返回 (Wikipedia)。
总结:
- 异步复制:无半同步或 Group Replication 插件,
rpl_semi_sync_*
均为关闭状态。 - 半同步复制:主库和至少一个从库启用
rpl_semi_sync_*
插件,并通过Rpl_semi_sync_source_status
及Rpl_semi_sync_replica_status
观察实时模式。 - 同步复制:通过查询 Group Replication 的 Performance Schema 表或 NDB Cluster 节点信息确认事务两阶段或多数派确认。
正确识别当前复制模式,有助于评估数据一致性保障水平,并据此选择合理的高可用策略。
四、增强半同步
增强半同步复制在传统的半同步复制基础上,通过插件和可调参数进一步提升了数据安全性与性能。MySQL 5.7 引入了新版本的半同步复制插件,优化了并发度和流水线处理,显著降低了事务提交延迟;MySQL 8.0 则新增了一系列动态系统变量,如 rpl_semi_sync_master_wait_for_slave_count
、rpl_semi_sync_master_timeout
等,允许用户灵活配置需要等待的从库数量和等待超时时间,从而在可用性和一致性之间取得更优平衡。
1. 什么是增强半同步复制
增强半同步复制(Enhanced Semi‐Synchronous Replication)依然属于半同步复制范畴,但用更现代的插件架构及更多可调参数来克服传统半同步的性能瓶颈与可用性限制。
1.1 插件架构
- MySQL 5.7:提供了全新的半同步主库(Source)和从库(Replica)插件,取代早期版本中 master/slave 插件的单一实现;插件会在启用时自动创建独立线程来发送与接收确认,无需手动管理。
- MySQL 8.0:继续沿用插件机制,并在命令行和动态系统变量层面大规模扩展了控制选项,去除了“master/slave”命名,用更中立的“source/replica”术语增强可读性和一致性。
2. MySQL 5.7 的改进
2.1 性能与并发度
- 在 MySQL 5.7 中,半同步插件将确认线程与二进制日志线程解耦,支持更高并发的 ACK 处理,缩小与异步复制的吞吐量差距。
- 支持配置等待确认的从库数目,用户可在插件参数中指定需要至少几个从库 ACK 才完成提交,从而在多从库场景下获得更高的可靠性。
2.2 数据完整性保障
- 强制至少一个从库将事务写入并刷新到磁盘后主库才返回成功,这意味着主库崩溃后,至少有一份持久化的事务副本存在于从库上,恢复时丢失的事务最小化。
3. MySQL 8.0 的新特性
3.1 rpl_semi_sync_master_wait_for_slave_count
- 控制每次事务提交前,需要获得多少个从库 ACK。默认值为
1
,但可设置为2
、3
等,以支持多副本确认并减少单点失效风险。
3.2 rpl_semi_sync_master_timeout
- 以毫秒为单位定义等待 ACK 的超时时间(默认为
10000
毫秒),超时后若未收到足够确认则自动回退到异步复制,保证可用性不因过长等待而大幅下降。
3.3 rpl_semi_sync_master_wait_no_slave
- 当半同步从库数不足时,是否仍等待超时后再回退;默认
ON
表示即使中途从库掉线,只要最终在超时前收到足够 ACK,就继续半同步;置为OFF
则一旦确认数低于配置值即刻回退。
3.4 其他优化变量
replication_sender_observe_commit_only
:在 8.0.23+ 可开启,仅在事务提交点进行回调,减少锁竞争;replication_optimize_for_static_plugin_config
:避免不必要的锁获取,提升在多从库场景下的吞吐能力。
4. 效益与限制
4.1 效益
- 更高的数据安全性:可保证多份副本接收日志后再确认,降低主从丢失差异;(PlanetScale, Database Administrators Stack Exchange)
- 可控的性能开销:通过参数精细调节 ACK 等待策略,在网络延迟和数据一致性需求间灵活权衡;
- 动态调整能力:无需重启,通过
SET GLOBAL
即可修改上述多数变量,实现运行时策略变更;(MySQL Developer Zone)
4.2 限制
- 网络依赖:半同步 ACK 回合仍需在超时时间内往返网络,跨区域部署需格外留意延迟;(MySQL Developer Zone)
- 主库阻塞风险:若超时策略不当或从库不可用,主库可能长时间处于等待状态,影响可用性;建议合理配置超时与等待数量。(Run Percona: Embrace Open)
5. 最佳实践
- 多从库确认:生产环境建议将
rpl_semi_sync_master_wait_for_slave_count
设置为2
或以上,确保至少两个副本持久化事务后再确认; - 合理超时:根据网络 RTT 调整
rpl_semi_sync_master_timeout
(如 50ms 至 500ms),既防止过快回退也避免长时间阻塞; - 监控指标:持续关注
Rpl_semi_sync_source_status
、Rpl_semi_sync_source_num_waiting_slaves
等状态变量,及时调整策略; - 失败演练:定期模拟从库故障或网络抖动,验证超时和回退机制,以保证业务连续性。
通过上述增强半同步复制特性,MySQL 用户能够在性能和数据一致性之间找到更灵活、可控的平衡点,显著提升高可用部署的可靠性与效率。
五、区分半同步和增强半同步
1. 插件与架构差异
1.1 插件名称与版本
- 传统半同步:使用旧版插件
rpl_semi_sync_master
(主库端)与rpl_semi_sync_slave
(从库端),变量与状态名称中仍含 “master/slave” 术语。 - 增强半同步:自 MySQL 8.0.23 起提供新版插件
rpl_semi_sync_source
/rpl_semi_sync_replica
,替换了“master/slave”命名,并可二选一安装,安装新版后旧版变量即不可用。
1.2 内部线程与回调
- 传统半同步:在提交事务时,主库阻塞当前线程,等待来自至少一个从库的 ACK;回调与日志线程耦合,ACK 处理与提交线程共享锁,可能产生锁争用。
- 增强半同步:将提交线程与 ACK 回调解耦,引入独立的 ACK 回调线程,大幅减少锁竞争,同时可以仅在事务真正提交时观察(
replication_sender_observe_commit_only
)。
2. 配置项对比
维度 | 传统半同步 | 增强半同步 |
---|---|---|
等待副本数 | 仅固定为 1(通过 rpl_semi_sync_master_wait_for_slave_count 最早提案) | 可动态设置 rpl_semi_sync_master_wait_for_slave_count=N (N≥1),主库需等待 N 个副本 ACK 后才提交 |
超时回退 | rpl_semi_sync_master_timeout (ms),超时即回退异步;该变量在 8.0.26 起被标注为 Deprecated | 同样使用 rpl_semi_sync_master_timeout ,且新增 rpl_semi_sync_master_wait_no_slave 控制是否在副本不足时立即回退或继续等待 |
性能优化 | 无额外选项 | replication_sender_observe_commit_only (仅在提交点触发回调)、replication_optimize_for_static_plugin_config (减少锁获取) |
变量可动性 | 部分变量需重启才能生效 | 主要变量均为 DYNAMIC ,可在线 SET GLOBAL 调整,无需重启 |
3. 运行时指标与状态
3.1 传统半同步指标
Rpl_semi_sync_source_status
:ON
表示当前以半同步模式运行,OFF
表示已回退到异步。Rpl_semi_sync_slave_status
:从库确认当前是否支持半同步。
3.2 增强半同步新增指标
Rpl_semi_sync_source_wait_for_slaves
:动态反映当前主库在提交事务时实际等待了多少副本 ACK(可观察最少与最大值)。Rpl_semi_sync_source_num_waiting_slaves
:实时显示正在等待 ACK 的副本数,便于监控是否达到wait_for_slave_count
要求。- 性能指标:可结合
performance_schema
中的等待事件与锁争用统计,验证replication_sender_observe_commit_only
、replication_optimize_for_static_plugin_config
是否生效。
结论:
- 若只需确保至少一个副本持久化日志,可继续使用传统半同步;
- 若在多副本场景下追求更高吞吐且希望灵活调整等待策略,应启用增强半同步插件及相关新变量,从而在数据安全与性能之间获得更优平衡。
六、异步丢数?
异步复制因不等待从库确认,即主库在提交事务后便立即返回成功,因此在以下场景中可能丢失尚未被从库接收或应用的事务,丢失量取决于故障发生时的复制延迟窗口。
1. 主库崩溃或意外故障
当主库在事务提交并写入本地二进制日志(binlog)后,但在将该日志事件发送给从库前就发生崩溃时,该事务永远不会到达从库,恢复时也无法找回这部分数据。
- 示例:Master1 崩溃,已提交的事件尚未复制到 Master2,从库上不存在这些事务,造成数据不一致与丢失。
- 参考:StackOverflow 上多次提到,如果主库崩溃,异步复制无法保证已提交事务被复制,造成丢失;必须借助半同步或切换回放 binlog 手动恢复。
2. 网络中断或链路故障
在网络抖动、链路中断或高延迟环境中,主库发送 binlog 事件到从库可能被阻塞或丢包,恢复链路后常常发现从库落后于主库。若中断期间有新事务写入主库,则这些事务未传输至从库,即使故障解决也无法补回这段时间的事务。
- 证据:CockroachLabs 提到,若复制需 1 秒,故障转移需 1 秒,则最坏会丢失 2 秒内的写入;网络延迟更大时丢失窗口随之增大。
- 参考:Pure Storage 博客指出,异步复制的主要劣势即为主从之间的时间差,事故或故障发生时在那里尚未复制的数据就会丢失。
3. 从库宕机或脱机
若从库意外下线、重启或手动停止复制服务,在此期间主库继续接收写请求,则所有在此期间提交的事务都不会复制至从库;如果此后主库故障,脱机期间的事务将丢失。
- 场景:因为维护或故障导致从库停止,后续写入无法复制;即便从库重启,也只能从主库的 binlog 中恢复能够找到的日志,若 binlog 已被清理,也无法恢复。
- 参考:SaigonTechnology 博客说明,从库因网络或硬件问题落后,会造成数据不一致与潜在丢失风险。
4. 磁盘或 I/O 问题
异步复制仅保证 binlog 事件被写入从库文件系统,但若从库在写入 binlog 或 relay log 后因磁盘故障丢失数据,或未及时 flush 至磁盘,主库此后的事务就会比从库“更安全”,恢复时也难补齐这些差异。
- 示例:从库的 relay log 写入后,但未 flush 即因磁盘损坏丢失;此后主库崩溃时,丢失存储在这部分 relay log 的事务。
- 参考:Hezmatt 博客指出,因 I/O 缓冲或磁盘异常,从库可能未持久化接收的事务,造成丢失风险。
5. 滞后过大与清理策略
如果主从复制延迟超过 binlog 保留策略设置(如 expire_logs_days
、binlog_expire_logs_seconds
),MySQL 会自动删除过期的 binlog,从库落后时相应事件可能已被移除,从库无法获取缺失的事务,数据永远丢失。
- 操作影响:自动或手动 purge binlog,可在落后较大时导致丢失从库未获取的事务。
- 参考:ServerFault 上提到,若落后严重,主库的老 binlog 已被删除,无法再从从库恢复这些事务。
6. “异步”自身局限
异步复制设计上就不保证“零数据丢失”;在接受略微数据丢失(RPO)与系统性能之间做权衡。对苛刻的业务场景,需采用半同步、增强半同步或群组复制等更强一致性方案。
- 行业实践:Continuent 强调,异步复制存在固有丢失窗口,不适合对数据一致性要求极高的场景;需结合其它 HA/DR 方案弥补风险。
- 替代方案:PingCAP TiDB 指出,在可接受少量丢失的场景下可选异步复制,否则应考虑半同步或同步复制方案。
综上,异步复制在以下主要情况下会丢失事务:
- 主库在提交后崩溃,未将事务发送至从库;
- 网络中断或高延迟导致复制滞后;
- 从库宕机、重启或脱机期间提交的事务;
- 从库 I/O 或磁盘故障导致未持久化事务;
- 落后超过 binlog 保留策略被清理;
- 设计层面不保证零丢失,需根据业务需求选择更强一致性机制。
为了降低风险,可选用半同步复制、增强半同步复制或 MySQL Group Replication,并结合监控告警、故障演练与备份恢复策略来保障数据安全。