目录标题
在 MySQL 的主备复制架构中,“半同步复制(semi-synchronous replication)”是一种兼顾性能与数据可靠性的机制。相较异步复制,半同步可以降低主库写成功但备库未收到数据就故障的“数据丢失”风险;相较全同步复制,又不至于严重牺牲主库性能。
✅ 一、什么是 MySQL 半同步复制?
🔹 定义
在半同步复制模式下,主库(Primary)提交事务时需等待至少一个备库(Replica)确认收到 binlog(写入中继日志),才算真正提交成功。
✅ 收到确认 → 主库 commit 成功
❌ 未确认(超时或无备库)→ 回退为异步复制
📌 二、MySQL 半同步复制的分类
| 模式 | 简要说明 |
|---|---|
| 半同步复制(老) | 主库只需等待一个备库确认“收到”binlog,即可提交事务 |
| 增强半同步(AFTER_SYNC) | 主库需等待备库写入 relay log + flush 到磁盘,更强一致性 |
| Loss-less 半同步 | (MySQL 8.0.26+)支持 group replication 的 lossless commit,不再有同步窗口 |
🛠 三、开启半同步的基本步骤
✅ 1. 安装插件(主从都要)
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
✅ 2. 配置主库参数
# my.cnf
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 1000 # 等待备库确认的毫秒数(默认10秒)
✅ 3. 配置从库参数
rpl_semi_sync_slave_enabled = 1
✅ 4. 检查状态变量
SHOW STATUS LIKE 'Rpl_semi_sync%';
SHOW VARIABLES LIKE 'rpl_semi_sync%';
🚀 四、半同步的性能优化策略
为提高吞吐量、降低延迟、减少回退为异步的情况,建议从以下方面进行优化:
✅ 1. 增加备库数量 + 优先确认设置
- 增加从库数量,主库收到任意一个确认即可继续提交。
- 从库中设置
--rpl_semi_sync_slave_enabled=ON,只选1个最快的备库作为确认者。
🔧 从 MySQL 5.7.17+ 支持 --rpl_semi_sync_master_wait_for_slave_count 设置确认数,默认=1。
✅ 2. 降低超时时间
rpl_semi_sync_master_timeout = 500 # 缩短主库等待时间(默认10秒)
- 太大会拖慢写入延迟
- 太小会频繁 fallback 为异步
🔍 可通过实际部署延迟观测调整
✅ 3. 启用增强半同步模式(AFTER_SYNC)
增强版提高了安全性,写入更加可控,但性能略降。
rpl_semi_sync_master_wait_point = AFTER_SYNC
| wait_point 取值 | 含义 |
|---|---|
AFTER_SYNC(推荐) | 等待备库写完 relay log 并 fsync |
AFTER_COMMIT | 等待备库收到 binlog 即可 |
✅ 4. 使用异步落盘优化延迟(备库)
- 确保从库
innodb_flush_log_at_trx_commit=2配置为优化写盘性能 - relay log 的
sync_relay_log=0可减少 I/O,但降低一致性保障(谨慎)
✅ 5. 主库异步回退容忍控制
-
配置是否允许自动回退为异步:
rpl_semi_sync_master_wait_no_slave = 1 # 若无备库,主库可自动回退 -
生产建议允许回退,避免主库阻塞导致雪崩
📈 五、相关状态与监控指标
📊 常用状态变量
SHOW STATUS LIKE 'Rpl_semi_sync%';
| 变量名 | 含义说明 |
|---|---|
| Rpl_semi_sync_master_status | 当前是否处于半同步状态(ON/OFF) |
| Rpl_semi_sync_master_clients | 具备半同步功能的备库数 |
| Rpl_semi_sync_master_yes_tx | 成功使用半同步提交的事务数量 |
| Rpl_semi_sync_master_no_tx | 回退为异步提交的事务数量 |
| Rpl_semi_sync_master_timefunc_failures | 等待过程中的系统时间函数失败次数 |
🧠 用于判断实际运行中是否频繁回退为异步,是否存在等待过久等问题。
🧩 六、半同步常见问题与建议
| 问题 | 原因分析 | 解决建议 |
|---|---|---|
| 主库事务提交延迟高 | 备库响应慢 / 网络延迟大 | 增加备库数量 / 缩短超时 / 优化网络 |
| 主库频繁回退为异步 | 备库掉线 / 延迟太大 | 定期监控从库状态,确保至少一个备库稳定在线 |
| 从库延迟积压严重 | relay log 写入慢 / 磁盘I/O瓶颈 | 优化从库 I/O 参数,如设置 innodb_flush_log_at_trx_commit=2 |
| 出现主备不一致 | 半同步未能严格执行 / 回退后异步 | 开启 AFTER_SYNC 并结合 lossless semi-sync |
✅ 七、MySQL 半同步复制总结
| 特性 | 描述 |
|---|---|
| 适用场景 | 高一致性要求的业务场景,如金融、订单、账户系统 |
| 优点 | 较好兼顾性能与一致性 |
| 风险点 | 若备库不稳定,会影响主库性能 |
| 最佳实践 | 与监控系统、告警系统配合使用,保障运行状态 |
如果你是在设计一套数据库运维可观测系统(比如结合 QFusion、Prometheus 监控等),可以将这些半同步相关变量纳入采集指标体系,设定告警阈值(如回退率过高、备库掉线、同步延迟高)实现更强的保障。需要我可以帮你进一步设计这部分的监控模板。
早期 MySQL 半同步复制的缺陷



早期 MySQL 半同步复制(semi-synchronous replication)的设计初衷是为了解决异步复制中“主库写入成功但从库未同步”的一致性隐患。然而其早期实现(如 MySQL 5.5、5.6 初期版本)存在多项架构性与可靠性缺陷,对数据安全与可用性产生严重影响,下面是这些缺陷的核心解析:
一、核心机制回顾(背景)
早期半同步复制流程如下:
- 主库执行事务并提交(
COMMIT); - 在提交之前,将 binlog 写入磁盘(fsync);
- 将 binlog 通过网络发送给从库;
- 等待至少一个从库返回 ACK(确认收到并写入 relay log);
- 收到 ACK 后才真正完成
COMMIT; - 若超时未收到 ACK,则降级为异步复制继续执行。
二、早期半同步的主要缺陷
1. ✅ 确认点错误:仅确认 relay log 写入,不确认事务回放
✅ 主库只等待从库写入 relay log 即可返回 COMMIT 成功,不等待从库真正执行 SQL 事务(回放到表)
问题后果:
- 主库以为数据已安全同步,但从库可能尚未应用事务;
- 如果主库此时宕机,从库可能还未完成事务回放,数据丢失。
🧠 实际场景举例:
主库写入一条关键交易记录,ACK 收到后立即宕机,从库 relay log 已写但 SQL 线程尚未应用,恢复后该记录“凭空消失”。
2. ⏱️ ACK 等待机制粗糙,易引发主库阻塞或频繁降级
- 主库
commit阶段阻塞等待 ACK,默认超时时间rpl_semi_sync_master_timeout(如 1000ms); - 如果网络抖动、从库延迟、从库故障,主库会频繁超时;
- 一旦超时,即自动降级为异步复制,失去半同步保护。
问题后果:
- 高峰期主库
COMMIT卡顿严重,影响吞吐; - 一旦降级为异步,后续事务都不再保证数据安全复制。
3. ❌ 主库故障切换存在不一致风险
由于只是“写到 relay log”就返回,主库崩溃后无法确保事务是否已被从库应用:
-
如果执行
GTID切换(如 MHA/Fabric/Orchestrator 选主),存在:- 主库比从库新:从库回滚部分事务;
- 从库比主库新:主库恢复后数据缺失。
4. ⚠️ ACK 模式单一,无法动态选最优从库
- 默认策略是“只要有一个 ACK”,不管从库延迟是否大、负载是否高;
- 无法优先选“健康、低延迟的从库”确认 ACK,性能受影响。
5. 🔒 ACK 线程阻塞主库事务提交流程
- 主库每次事务
commit时都要等待 ACK; - 一旦网络延迟或从库忙碌,主线程卡死,无法提交后续事务。
三、从 MySQL 5.7 开始的优化改进(简述)
为弥补上述缺陷,MySQL 在 5.7+ 引入增强半同步(lossless semi-sync)机制:
| 改进项 | 描述 |
|---|---|
| 事务确认点延后 | 可配置为等待从库 执行完事务 后再 ACK(通过 rpl_semi_sync_master_wait_for_slave_count + after_sync) |
| 多从库 ACK 策略 | 支持设定必须等多个从库 ACK(提高容错性) |
| 更精细的超时控制 | 支持动态切换、快速降级,减少阻塞 |
支持 Group Replication 替代 | 官方推荐使用 Group Replication 提供更强的一致性保障 |
四、结论
| 维度 | 早期半同步表现 | 问题根源 |
|---|---|---|
| 数据一致性保障 | ❌ ACK 时未确保从库事务已应用 | 确认点太早 |
| 宕机恢复安全性 | ❌ 主库宕机会出现主从数据不一致 | 依赖 relay log 状态 |
| 性能与可用性 | ❌ ACK 阻塞 COMMIT,易触发降级 | 缺乏灵活调度与健康检测机制 |
| 网络异常容错 | ❌ 易频繁切换异步,失去保护 | 超时控制粗糙 |
✅ 早期半同步“看似比异步安全”,但关键场景下仍无法彻底避免数据丢失与主从不一致,必须慎重使用。如今推荐使用增强半同步或基于 Paxos/Raft 的更强一致性方案(如 Group Replication、TiDB、PolarDB、CockroachDB 等)。
如果你正在使用某个 MySQL 版本,我也可以帮你分析当前半同步机制是否安全、是否适合线上环境部署。是否需要进一步分析你当前环境下的建议策略?
4332

被折叠的 条评论
为什么被折叠?



