乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 数据库基础与安装

    • MySQL 简介
    • MySQL 5.6 到 5.7 到 8.0 关键差异速查
    • 安装 MySQL 5.7
    • 连接与断开服务器
    • 创建数据库
    • 创建数据表
    • 数据库与数据表
    • 加载数据
    • 获取数据库信息
    • 批处理模式
    • SHOW 语句汇总
    • FLUSH 与 RESET 语句
    • my.cnf 核心参数
    • 字符集与排序规则
  • 第2章 SQL基础查询

    • SELECT
    • WHERE
    • ORDER BY
    • LIMIT
    • COUNT
    • 聚合函数
    • 比较运算符
    • 逻辑运算符
    • 算术运算符
    • 模式匹配
    • NULL 值处理
    • UPDATE
    • DELETE
    • REPLACE
    • SELECT INTO
  • 第3章 数据类型与运算符

    • 数值类型
    • 字符串类型
    • 日期时间类型
    • BIT 类型
    • ENUM 类型
    • SET 类型
    • JSON 类型
    • 类型转换
  • 第4章 函数与表达式

    • 字符串函数
    • 数值函数
    • 日期函数
    • 全文检索函数
  • 第5章 高级查询与子查询

    • JOIN
    • 子查询
    • UNION
    • GROUP BY
    • HAVING
    • DISTINCT
  • 第6章 表与索引

    • 数据定义语言
    • 修改表结构
    • 视图
    • 修改视图与检查选项
    • 外键
    • 索引
    • 唯一索引
    • 复合索引
    • 存储引擎对比
    • 分区表
    • 第一范式与第二范式
    • 第三范式与 BC 范式
    • 反范式设计
  • 第7章 存储过程与函数

    • 存储过程
    • 存储函数
    • 变量
    • 流程控制
    • 游标
    • 预处理语句
  • 第8章 事务与锁

    • 事务
    • 事务隔离级别
    • 锁机制
    • MVCC
    • 死锁专题分析
    • LOCK TABLES
    • XA 事务
  • 第9章 用户管理与安全

    • 用户管理
    • 权限管理
    • 角色
    • SQL 注入防范
  • 第10章 性能优化入门

    • 执行计划
    • 索引优化
    • 查询优化
    • 查询优化器提示
    • 慢查询日志
    • InnoDB 深入机制
    • InnoDB 专项优化
    • Performance Schema
    • sys Schema
  • 第11章 复制与高可用

    • 主从复制原理
    • 半同步复制配置
    • binlog 开启与 point-in-time 恢复
    • mysqldump 全库备份
    • mysqldump 单表与条件备份
    • mysqldump 恢复与导入
    • xtrabackup 全量热备
    • xtrabackup 准备与恢复
    • xtrabackup 增量与流式备份
  • 第12章 触发器与事件

    • 触发器
    • 事件调度器
  • 参考

    • MySQL 5.7 专业术语大全
    • MySQL 5.7 关键字与保留字大全

半同步复制配置

导学

异步复制是 MySQL 主从的默认模式——主库写完 binlog 就返回成功,不等待从库。如果主库在从库收到数据前崩溃,这部分数据就永久丢失。半同步复制(Semi-Synchronous Replication)让主库至少等待一个从库确认收到 binlog 后才返回成功,在性能和数据安全之间取得平衡。

定义

半同步复制:主库在执行事务提交后,等待至少一个从库将 binlog 写入其 relay log 并返回 ACK 确认,才向客户端返回提交成功。如果等待超时,自动降级为异步复制,不阻塞业务。

安装半同步插件

MySQL 5.7 的半同步复制通过插件实现,主库和从库都需要安装。

主库安装

-- 安装主库半同步插件
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

-- 验证安装
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS 
WHERE PLUGIN_NAME LIKE '%semi%';
PLUGIN_NAMEPLUGIN_STATUS
rpl_semi_sync_masterACTIVE

从库安装

-- 安装从库半同步插件
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

-- 验证安装
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS 
WHERE PLUGIN_NAME LIKE '%semi%';
PLUGIN_NAMEPLUGIN_STATUS
rpl_semi_sync_slaveACTIVE

结果解读:

  • semisync_master.so 和 semisync_slave.so 是 MySQL 5.7 自带的插件文件,位于 plugin_dir 目录下
  • 验证 plugin_dir:SHOW VARIABLES LIKE 'plugin_dir';
  • 插件安装后持久化到 mysql.plugin 表,重启后自动加载

场景一:基础半同步配置(一主一从)

主库配置

-- 开启半同步复制
SET GLOBAL rpl_semi_sync_master_enabled = ON;

-- 查看主库半同步状态
SHOW STATUS LIKE 'Rpl_semi_sync_master%';
Variable_nameValue
Rpl_semi_sync_master_statusON
Rpl_semi_sync_master_no_tx0
Rpl_semi_sync_master_yes_tx0
Rpl_semi_sync_master_wait_pos_backtraverse0
Rpl_semi_sync_master_wait_sessions0
Rpl_semi_sync_master_tx_avg_wait_time0

结果解读:

  • Rpl_semi_sync_master_status = ON:主库半同步模式已激活
  • Rpl_semi_sync_master_yes_tx:成功通过半同步提交的事务数
  • Rpl_semi_sync_master_no_tx:降级为异步提交的事务数

从库配置

-- 开启半同步复制
SET GLOBAL rpl_semi_sync_slave_enabled = ON;

-- 重启从库 IO 线程使配置生效(必须)
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

-- 查看从库半同步状态
SHOW STATUS LIKE 'Rpl_semi_sync_slave%';
Variable_nameValue
Rpl_semi_sync_slave_statusON

结果解读:

  • 从库必须重启 IO 线程,半同步插件才能与主库建立半同步连接
  • Rpl_semi_sync_slave_status = ON 表示从库当前正以半同步方式连接主库

场景二:超时降级机制

核心参数:rpl_semi_sync_master_timeout

-- 查看默认超时时间(毫秒)
SELECT @@rpl_semi_sync_master_timeout;
@@rpl_semi_sync_master_timeout
10000

默认 10000 毫秒 = 10 秒。如果从库在 10 秒内未返回 ACK,主库自动降级为异步复制。

操作语句:调整超时时间。

-- 设为 2 秒(2000 毫秒),更敏感地降级
SET GLOBAL rpl_semi_sync_master_timeout = 2000;

-- 或设为 1 秒
SET GLOBAL rpl_semi_sync_master_timeout = 1000;

结果解读:

  • 超时时间越短,主库越快地降级为异步,业务延迟越小,但数据丢失风险越大
  • 超时时间越长,主库等待从库越久,数据安全性越高,但事务提交延迟越大
  • 生产环境推荐:根据网络延迟设置。同城机房建议 1~2 秒,跨城建议 3~5 秒。如果超过 5 秒从库仍无响应,说明从库已严重延迟或网络故障,降级为异步是合理选择。

场景三:等待多个从库确认

核心参数:rpl_semi_sync_master_wait_for_slave_count

-- 查看默认等待从库数量
SELECT @@rpl_semi_sync_master_wait_for_slave_count;
@@rpl_semi_sync_master_wait_for_slave_count
1

默认只等待1 个从库确认。如果有一主两从架构,可以要求等待 2 个从库都确认。

操作语句:

-- 要求至少 2 个从库确认后才返回成功
SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = 2;

结果解读:

  • 等待从库数越多,数据安全性越高(多个副本确认),但事务提交延迟越大
  • 如果实际从库数 < 配置的等待数(如只有 1 个从库但要求 2 个),主库会永远等不到足够 ACK,最终超时降级为异步
  • 生产环境推荐:一主两从时设为 1(默认),一主三从时可考虑设为 2,形成"多数派"确认

场景四:等待点控制(After Commit vs After Sync)

MySQL 5.7 引入了更安全的半同步模式。

核心参数:rpl_semi_sync_master_wait_point

-- 查看当前等待点
SELECT @@rpl_semi_sync_master_wait_point;
@@rpl_semi_sync_master_wait_point
AFTER_SYNC
等待点行为数据安全性性能
AFTER_COMMIT(5.6 默认)主库先提交事务,再等待从库 ACK低。如果主库提交后崩溃,从库未收到数据,主库已提交的数据无法找回稍好
AFTER_SYNC(5.7 默认)主库先写 binlog 并等待从库 ACK,收到 ACK 后才提交事务高。如果等待期间主库崩溃,事务未提交,可回滚,数据不会不一致稍差

结果解读:

  • 5.7 默认 AFTER_SYNC 是重大改进。在 AFTER_COMMIT 模式下,存在"主库已提交、从库未收到"的窗口期,如果此时主库崩溃且无法恢复,已提交的数据就丢失了(因为 binlog 可能也未持久化到从库)。
  • AFTER_SYNC 下,主库收到从库 ACK 后才真正提交,崩溃时事务未提交,可安全回滚,然后从库提升为主库继续服务。
  • 不要改回 AFTER_COMMIT,除非有极其特殊的兼容性需求。

场景五:监控半同步降级频率

操作语句:

-- 主库查看半同步统计
SHOW STATUS LIKE 'Rpl_semi_sync_master%';

关键指标:

Variable_nameValue含义
Rpl_semi_sync_master_statusON当前是否处于半同步模式
Rpl_semi_sync_master_yes_tx1500成功半同步提交的事务数
Rpl_semi_sync_master_no_tx23降级为异步提交的事务数
Rpl_semi_sync_master_tx_avg_wait_time520平均等待从库 ACK 的时间(微秒)
Rpl_semi_sync_master_net_avg_wait_time480平均网络等待时间(微秒)
Rpl_semi_sync_master_trx_wait_time780000总等待时间(微秒)

结果解读:

  • no_tx / (yes_tx + no_tx) 的比例反映降级频率。如果比例 > 5%,说明从库延迟严重或网络不稳定,需排查
  • tx_avg_wait_time 持续 > 超时时间的 50%,说明从库响应慢,考虑优化从库性能或降低超时阈值
  • 如果 Rpl_semi_sync_master_status 频繁在 ON/OFF 之间切换,说明网络抖动或从库不稳定

场景六:持久化配置到 my.cnf

上述 SET GLOBAL 重启后失效,生产环境应写入配置文件。

主库 my.cnf:

[mysqld]
# 半同步插件
plugin-load = rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 2000
rpl_semi_sync_master_wait_for_slave_count = 1
rpl_semi_sync_master_wait_point = AFTER_SYNC

从库 my.cnf:

[mysqld]
# 半同步插件
plugin-load = rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled = 1

结果解读:

  • plugin-load 在启动时加载插件,避免 INSTALL PLUGIN 的手动步骤
  • 半同步配置应在主从架构搭建时就规划好,而不是事后补丁式添加

常见误区

误区正解
"半同步复制不会丢数据"不是。半同步只保证 binlog 到达从库的 relay log,不保证从库已执行(apply)。如果主库崩溃,从库可能还有未执行的 relay log。且超时降级为异步后仍有丢失窗口。
"半同步比异步慢很多"不一定。如果网络延迟 < 1ms(同城机房),等待 ACK 的开销通常 < 1ms,对业务几乎无感。跨城或从库压力大时才会明显延迟。
"半同步需要所有从库确认"不是。默认只等 1 个,可通过 wait_for_slave_count 调整。
"从库开启半同步后不用重启 IO 线程"必须重启。rpl_semi_sync_slave_enabled 只在 IO 线程建立连接时生效,不重启不会切换为半同步协议。
"AFTER_COMMIT 和 AFTER_SYNC 没区别"区别很大。AFTER_COMMIT 有"提交后崩溃丢数据"的窗口;AFTER_SYNC 在收到 ACK 后才提交,更安全。5.7 默认 AFTER_SYNC 不要改。

面试考点

Q:半同步复制和异步复制的区别?

异步复制:主库写完 binlog 即返回成功,不等待从库。最快但主库崩溃时可能丢失未同步的数据。半同步复制:主库等待至少 N 个从库将 binlog 写入 relay log 并返回 ACK 后才返回成功。数据安全性更高,但有等待延迟。超时后自动降级为异步。

Q:rpl_semi_sync_master_timeout 怎么设?

根据网络延迟和从库性能设置。同城低延迟环境建议 1~2 秒;跨城或从库压力大建议 3~5 秒。太短会频繁降级失去半同步意义;太长会阻塞主库事务提交,影响业务。

Q:AFTER_COMMIT 和 AFTER_SYNC 的区别?

AFTER_COMMIT:主库先提交事务,再等待从库 ACK。如果提交后主库崩溃、从库未收到,数据丢失且无法找回。AFTER_SYNC:主库先写 binlog,等待从库 ACK 收到后才提交事务。崩溃时事务未提交,可安全回滚,数据不会不一致。5.7 默认 AFTER_SYNC,更安全。

Q:半同步复制能替代全同步(如 Paxos/Raft)吗?

不能。半同步只保证 binlog 到达从库 relay log,不保证从库已执行,也不处理脑裂。全同步要求多数派确认且已执行,一致性更强。MySQL 5.7 的 Group Replication(MGR)才是基于 Paxos 的全同步方案。

小结

  • 半同步复制在主库等待从库 ACK 后返回成功,超时自动降级为异步
  • 主库安装 rpl_semi_sync_master,从库安装 rpl_semi_sync_slave,从库必须重启 IO 线程生效
  • rpl_semi_sync_master_timeout 控制降级阈值,推荐 1~5 秒根据网络调整
  • rpl_semi_sync_master_wait_for_slave_count 控制等待从库数,默认 1,多从时可提高
  • AFTER_SYNC(5.7 默认)比 AFTER_COMMIT 更安全,崩溃时未提交事务可回滚
  • 监控 Rpl_semi_sync_master_yes_tx 和 no_tx 比例,评估半同步有效性

下一章引子:半同步复制提升了主从架构的数据安全性,但如果需要多主多从、自动故障切换和全同步一致性,MySQL 5.7.17+ 引入的 Group Replication(MGR)是更高级的解决方案。

上一页
主从复制原理
下一页
binlog 开启与 point-in-time 恢复