news 2026/10/20 1:53:12

MySQL主从复制与组复制实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL主从复制与组复制实战

MySQL 8.0.36 实战:主从复制 · GTID · 半同步 · 组复制

关键词:MySQL 8.0.36 / 主从复制 / GTID / 半同步复制 / 组复制 MGR

本文基于 MySQL 8.0.36,在三节点环境下从零开始,按难度递进依次搭建四种复制架构,
最终完成组复制(MGR)。每一步都有完整配置与验证命令,可直接照做。


目录

  1. 前言

  2. 环境规划

  3. 传统主从复制(基于 binlog 文件 + 位点)

  4. 升级为 GTID 模式

  5. 开启半同步复制

  6. 组复制(MGR)

  7. 四种复制方式对比


1. 前言

MySQL复制(Replication)是实现数据库多实例同步的核心方案,广泛用于读写分离、数据备份、故障容灾,异地多活等场景,传统主从采用主库推送变更日志,从库放回日志的思路实现数据同步。

整体工作流程,主库(MASTER)执行增删改与DDL操作,事务提交时将数据变更事件记录到二进制日binlog。从库启动IO线程,使用复制用户主动连接主库请求binlog;主库通过Binlog Dump线程持续推送日志事件,从库的IO线程接收后写入本地中继日志relay log。随后从库的SQL线程读取中继日志,串行或并行的执行日志内的事件,在本地复现主库的数据修改,最终实现主从数据一致。

MYSQL的三种复制模式:

  • 异步复制(默认):主库写入binlog后直接响应客户端,不会等待从接收日志。优势是性能高,风险为主库宕机时,未同步到从库的日志可能会丢失。
  • 半同步复制:以插件形式开启,主库提交事务后,需要等待至少一台从库接收binlog成功并写入中继日志,才向客户端返回执行结果,用户甚至可以设置死等。若从库响应超时,会自动降级为异步复制,兼顾性能和数据安全。
  • 组复制 MGR使用独立的XCom Paxos协议,区别于传统一主多从架构,支持多节点并发写入,内置冲突检测、自动选主,故障隔离,是MYSQL原生高可用方案。

MGR组复制具有单主模式和多主模式,节点间相互通信,消息组内广播,独立的XCom(33061)端口完成集群内协商通信,网络开销更高,对网络稳定性要求严苛;多主模式下多节点同时写入同一行,会检测冲突并回滚失败业务。

本博客按照真实学习路径,从最简单的主从复制起步,一步步进化到组复制:

传统主从(文件+位点) → GTID 模式 → 半同步 → 组复制 MGR ① ② ③ ④

每一步都在上一节的基础上叠加,配置可平滑升级,不需要从头重搭。

前置知识:掌握基本 SQL 与 MySQL 日常运维(启动/停止、配置文件、查看日志);
了解 InnoDB 引擎与 binlog 的概念更佳。本文不展开 MySQL 安装细节(tar 包解压、初始化、
systemd 管理),只聚焦复制架构本身。


2. 环境规划

centos7系统三台节点,同局域网,/etc/hosts已互相解析(强烈建议配置,避免主机名解析问题):

节点主机名IP第一阶段角色最终角色
node1server1192.168.40.131Master(主库)组复制成员 1
ndoe2server2192.168.40.132Slave1(从库)组复制成员 2
node3server3192.168.40.133Slave2(从库)组复制成员 3

规划说明:

  • MySQL 版本统一为8.0.36(Linux 二进制或 tar 包安装均可,本文用 systemd 管理)本文的程序的默认路径/usr/local/mysql,并且添加到环境变量,并且配置文件的存放位置统一为/etc/mysql/my.cnf。
  • 主从复制使用3306;组复制额外使用33061作为成员内部通信端口
    (group_replication_local_address)。
  • 复制账号统一用repl,密码示例repl,生产环境请替换为强密码。
  • 每台节点上都创建mysql用户,确保ID一致。本文中UID与GIID均为1002。
groupadd-g1002mysql#指定创建GID为1002的mysql组useradd-u1002-gmysql-M-d/usr/local/mysql/-s/sbin/nologin mysql#指定mysql用户家目录idmysqluid=1002(mysql)gid=1002(mysql)groups=1002(mysql)
  • 严格执行生产环境中程序盘和数据盘分离原则,数据盘位于/data/mysql下。

  • 确保每台节点的地址解析,所有主机添加hosts解析。

环境相关的三个易漏项:

  • 时间同步:组复制成员间的消息带时间戳,时钟偏差过大会影响事务排序与日志一致性,
    三台节点务必启用chrony或ntp保持时钟一致(timedatectl set-ntp true)。
  • 防火墙 / SELinux:放通3306(SQL 连接)与33061(组复制内部通信)两个端口;
    若开启 SELinux 还需放行 mysqld 相应端口,否则复制/组通信会莫名失败。
  • 账号安全:复制账号repl建议限定来源网段(如'repl'@'192.168.40.%')并使用强密码,
    避免弱口令账号裸露在整个网段内。

3. 传统主从复制(基于 binlog 文件 + 位点)

3.1 原理

主从复制核心是binlog:

Master Slave 事务提交 ──> binlog ──拉取──> IO_Thread 写入本地 relay_log └─> SQL_Thread 重放到自身库
  • Binlog Dump 线程(主库侧):主库为每个从库连接维护一个 dump 线程,持续把 binlog
    事件推送给从库的 IO 线程;没有从库连接时该线程处于休眠。
  • IO_Thread(从库侧):连接主库、拉取 binlog,并顺序写入从库的relay_log(中继日志)。
  • SQL_Thread(从库侧):读取 relay_log,把其中的事务在本地重放一遍,完成数据同步。
  • **默认异步:**主库写完binlog就返回客户端,不等待从库接收。
  • 传统模式靠文件名 + 位点(File / Position)定位复制到哪了:IO 线程记录"已经拉到哪个
    位置",SQL 线程记录"已经执行到哪个位置",两者都由主库的 binlog 文件名 + 偏移量表示。

从库写入 relay_log 的事务并不会自动转存进自己的 binlog——这正是"从库要当主库时必须开
log_slave_updates"的原因,见 3.3 的补充说明。

3.2 主库配置(server1)

以 node1 为例,主库核心配置项(node2/node3 只需把server_id改成 2、3):

[mysqld] server_id = 1 # 全局唯一,所有节点不能重复 log_bin = /data/mysql/binlog/mysql-bin # 开启二进制日志(主库必须) binlog_format = ROW # 8.0 默认即 ROW sync_binlog = 1 # 每提交一个事务就 fsync binlog,防止丢日志 binlog_expire_logs_seconds = 2592000 # binlog 保留 30 天 max_binlog_size = 256M
参数作用说明
server_id节点唯一标识复制链路上所有节点都不能重复
log_bin开启二进制日志主库必开;从库按需决定(见 3.3)
binlog_formatbinlog 记录格式8.0 默认 ROW,记录"每一行怎么变",最安全
sync_binlogbinlog 落盘策略=1每事务同步刷盘,配合innodb_flush_log_at_trx_commit=1可做到主库零丢失
binlog_expire_logs_secondsbinlog 保留时长从库掉线太久可能发现所需 binlog 已被清理,需权衡设置

binlog_format三种取值的取舍:

  • ROW(8.0 默认):记录每行的变更结果,不受NOW()、UUID()等非确定性函数影响,
    恢复最准确,也是组复制 MGR 的硬性要求。
  • STATEMENT:只记录执行过的 SQL,日志量小,但非确定性函数、触发器可能造成主从不一致。
  • MIXED:让 MySQL 自动在两者间切换,行为更难预测,生产环境不推荐。

3.3 从库配置(server2 / server3)

节点内的server-id不能一致,server3上的server-id的值为3,这是从库的配置文件之间唯一的差别。从库可以开启只读功能,防止误读;同时关闭二进制日志功能,以减少性能损失。

"从库要不要开 binlog"再展开一点:

  • 单纯做只读/备份的从库,关闭 binlog 确实能省一点 I/O;
  • 但若从库未来要级联复制(作为更下游节点的主库),或参与主从切换,则必须
    log_bin = ON且log_slave_updates = ON,否则从库的 binlog 里不会包含
    “从主库同步来的事务”,下游和接替方就拿不到数据。
  • 后面的GTID 升级与组复制 MGR都强制要求log_slave_updates = ON,
    建议从库直接一并配上,避免以后再改配置重启。
  • 从库建议同时加read_only = ON(超级账号仍可写,防止业务误写从库)与
    skip_replica_start = ON(重启后不自动复制,便于人工确认后再启动)。

改完配置后三台节点都初始化数据、开启mysql,并通过临时密码登录 MySQL:

在每个节点初始化之前一定要确保/data/mysql/文件夹下为空,否则会出现启动失败,数据不同步等错误。

3.4 创建复制账号

复制账号用于从库登陆主库做身份验证,并且凭借REPLICATN SLAVE权限,让主库开启dump线程,向从库推送binlog日志。
在主库 server1 上执行:

复制账号遵循最小权限原则,只需复制相关权限,不要授予超级权限:

CREATEUSER'repl'@'%'IDENTIFIEDBY'repl';-- 生产请用强密码并限定来源网段GRANTREPLICATIONSLAVE,REPLICATIONCLIENTON*.*TO'repl'@'%';FLUSHPRIVILEGES;
  • REPLICATION SLAVE:允许从库用该账号拉取 binlog(8.0.22+ 也可写作REPLICATION REPLICA)。
  • REPLICATION CLIENT:允许执行SHOW MASTER STATUS等复制状态命令,便于排查,非必需。

由MASTER状态可以看出,从二进制日志文件binlog.000002的偏移位点1299开始从库同步。

3.5 配置从库

⚠️ 若主库已有业务数据,请先mysqldump --master-data全量备份并恢复到从库,
再执行下面的CHANGE MASTER TO;本文假设数据为空或已处理。

从库上执行:

CHANGE MASTER TO各参数含义(8.0.23+ 官方推荐CHANGE REPLICATION SOURCE TO,二者等价):

参数含义
MASTER_HOST主库 IP,必须能从从库网络访问到
MASTER_PORT主库端口,默认 3306
MASTER_USER/MASTER_PASSWORD3.4 创建的复制账号repl
MASTER_LOG_FILE/MASTER_LOG_POS主库SHOW MASTER STATUS给出的文件 + 位点
MASTER_AUTO_POSITION设为 1 即启用 GTID 自动定位(第 4 节)

位点从哪来?在主库执行SHOW MASTER STATUS\G查看File与Position两列。
若主库已有业务数据,用mysqldump --single-transaction --master-data=2导出时,dump 文件
头部会自动携带一条CHANGE MASTER TO ...(--master-data=2是注释形式,人工确认后放开;
若主库已开 GTID 还会附带SET @@GLOBAL.GTID_PURGED=...)。

(8.0.23 开始官方推荐写法为CHANGE REPLICATION SOURCE TO与START REPLICA,
二者等价,下文为可读性沿用MASTER/SLAVE关键字。)

3.6 验证

在SHOW SLAVE STATUS\G输出中确认两个关键项:

读写验证:主库建表插入数据,从库立即能查到:

-- 主库CREATEDATABASEtestdb;CREATETABLEtestdb.t1(idINTPRIMARYKEY,nameVARCHAR(50));INSERTINTOtestdb.t1VALUES(1,'hello');
-- 从库SELECT*FROMtestdb.t1;-- 能查到 (1, 'hello') 即成功

日常监控命令(从库执行):

SHOWSLAVESTATUS\G
输出项含义
Slave_IO_RunningIO 线程是否连上主库、正常拉取 binlog
Slave_SQL_RunningSQL 线程是否正常执行 relay log 中的事务
Seconds_Behind_Master主从延迟秒数(估算值,0 表示已追上)
Master_Log_File/Read_Master_Log_PosIO 线程已拉取到的位置
Relay_Master_Log_File/Exec_Master_Log_PosSQL 线程已执行到的位置

Seconds_Behind_Master是估算值:只有 SQL 线程正在执行时才反映真实延迟,空闲时归零,
只能作参考;精确对账应对比主从的 binlog 位点或 GTID 集合(第 4 节)。

提升从库吞吐(8.0 多线程并行复制,可选):

[mysqld] replica_parallel_workers = 4 # 并行应用线程数(旧名 slave_parallel_workers) replica_parallel_type = LOGICAL_CLOCK # 基于事务时间戳/写集并行,8.0 默认即此值 binlog_transaction_dependency_tracking = WRITESET # 主库为并行复制打标,写集并行效果最好

大事务(一次性删除/更新几十万行)在从库重放是最常见的延迟来源,除调大并行度外,
更彻底的办法是业务侧把大事务拆小。

传统模式的局限:从库无法精确回答"主库已经执行到哪个事务",位点信息割裂在
各从库的 relay 日志里,主库 crash 后切换极难找准恢复点。这就是 GTID 要解决的问题。


4. 升级为 GTID 模式

4.1 什么是 GTID

GTID(Global Transaction Identifier,全局事务标识符)格式为:

<server_uuid>:<事务序号> 例如 3a3f0c18-9d7a-11ee-a9c8-005056a02b12:1-10
  • server_uuid是每台实例在初始化时生成的 UUID,保存在数据目录的auto.cnf中,
    唯一标识"这个事务诞生于哪台机器"。
  • 事务序号是本实例生成的单调递增整数,多个连续序号可缩写为区间,如1-10;
    多个来源用逗号连接,形成GTID Set,例如3a3f0c18-...:1-10, b2c9d1f4-...:1-5。

特点:

  • 每个事务有全局唯一的编号,由"在哪台机器上生成 + 序号"组成。
  • 从库能精确知道"我执行到哪些 GTID",主从数据状态可对比、可追踪。
  • 主从切换时无需手动寻找位点,MASTER_AUTO_POSITION=1自动协商同步点。

4.2 升级步骤(主库、从库都要做)

确保主库上的没有任何创建的库,即没有创建的内容。

随后将以下配置写入三台节点的/etc/my.cnf并重启:

[mysqld] gtid_mode = ON enforce_gtid_consistency = ON

4.3 从库切换为 GTID 自动定位

STOP SLAVE;CHANGE MASTERTOMASTER_AUTO_POSITION=1;STARTSLAVE;SHOWSLAVESTATUS\G-- 依然要求 Slave_IO_Running / Slave_SQL_Running = Yes

现在不需要再关心File / Position了。验证 GTID 已生效:

SELECT@@GLOBAL.GTID_EXECUTED;

主从两台机器上看到的GTID_EXECUTED集合应当一致(或从库是主库的子集)。

4.4 GTID 的价值

  • 主库宕机后,选出事务最完整的从库,直接CHANGE MASTER TO MASTER_AUTO_POSITION=1
    即可接管,不再需要翻 binlog 找位点。
  • 同一台从库换主(级联切换)非常顺滑。
  • 排查数据不一致时,直接对比GTID_EXECUTED与gtid_purged。

GTID 模式下手动切换示例(主库宕机,提升从库为新主):

-- 在候选从库(如 server2)上,把复制指向新主STOP SLAVE;CHANGE MASTERTOMASTER_HOST='新主IP',MASTER_AUTO_POSITION=1;-- 无需再填位点STARTSLAVE;

要点:

  • 选哪台从库当新主,可对比各从库的@@GLOBAL.GTID_EXECUTED,选包含事务最全的那台;
  • 切换后新主继续生成事务,server_uuid不变,事务序号自动延续,不会与旧主冲突;
  • 旧主恢复后若想重新挂回集群,需清空数据重新全量同步——旧主上有新主没有的 GTID 时
    直接挂会报ER_GTID_NEXT_TYPE_UNDEFINED_GROUP之类的错误(详见 FAQ)。

5. 开启半同步复制

5.1 为什么需要半同步

传统复制是异步的:主库写完binlog,返回客户端成功,不等待从库接收binlog就返回。
**半同步复制(semi-sync)😗*主库提交事务写入binlog后,至少等待一台从库确认收到binlog事件,才给客户端返回提交成功。

注意:只等从库收到日志,不等从库执行回放事务!

核心流程:

  1. 主库执行事务,写入binlog;
  2. 主库等待从库回复:已收到binlog日志;
  3. 收到ACK确认->返回客户端事务成功;
  4. 超时没收到从库ACK,自动降级为异步复制(保证业务不卡死)。

5.2 安装插件(8.0.26+ 新命名)

8.0.26 起插件名由 master/slave 改为 source/replica,老名字仍作别名可用:

** 主库 **

** 在主库查看半同步的配置状态及参数 **

** 从库 **

用状态变量确认半同步是否真正生效:

SHOWSTATUSLIKE'Rpl_semi_sync%';
状态变量含义
Rpl_semi_sync_source_status主库半同步是否处于 ON(1=生效中)
Rpl_semi_sync_source_clients当前处于半同步连接的从库数量
Rpl_semi_sync_source_yes_tx已收到从库 ACK 的事务数
Rpl_semi_sync_source_no_tx因超时降级、未收到 ACK 的事务数
Rpl_semi_sync_replica_status从库半同步是否 ON

只要yes_tx在增长,说明链路是真正半同步;若no_tx持续增长,说明在频繁降级为异步,
应排查网络 RTT 与rpl_semi_sync_source_timeout的设置是否过小。

5.3 配置参数(写入 my.cnf 以便持久化)

# node1(主库) [mysqld] plugin_load_add = "rpl_semi_sync_source.so" rpl_semi_sync_source_enabled = 1 rpl_semi_sync_source_timeout = 1000 # 单位 ms(8.0.26+),超时后降级异步 rpl_semi_sync_source_wait_for_replica_count = 1 rpl_semi_sync_source_wait_point = AFTER_SYNC # node2 / node3(从库) [mysqld] plugin_load_add = "rpl_semi_sync_replica.so" rpl_semi_sync_replica_enabled = 1

rpl_semi_sync_source_timeout的行为:主库提交事务后最多等待这么久收 ACK,超时就把
当前事务按异步放行,并临时降级为异步(无需人工复位,从库恢复 ACK 后自动回到半同步)。
权衡:timeout设大 → 更不容易丢事务,但主库故障时阻塞窗口更大;设小 → 主库更稳,
但更容易频繁降级。生产常见取值 1000~5000ms。

5.4 超时降级验证

把一个从库停掉 IO 线程(模拟无 ACK)STOP SLAVE IO_THREAD;,在主库设置必须接收至少两个从库ACKSET GLOBAL rpl_semi_sync_master_wait_for_slave_count=2,主库写入新数据后观察状态:

(降级为异步期间主库照常工作,不会阻塞业务;等从库恢复后自动回到半同步。)

半同步的局限:主库与从库仍是"一个主、多个从"的星型拓扑,主库是单点;
没有自动选主能力,故障切换仍需手动或借助中间件。组复制在此基础上实现了
自动选举 + 多数派确认。


6. 组复制(MGR)

6.1 组复制是什么

组复制(Group Replication)是 MySQL 官方的高可用方案,核心是XCOM Paxos 共识:

  • 成员之间通过group_replication_local_address(如 33061)互相通信。
  • 多数派(quorum)机制:只有超过半数的成员确认某个事务,事务才算提交。
    因此 3 节点组可容忍 1 台宕机,5 节点可容忍 2 台。
  • 自动选主:单主模式下主库宕机,组内自动选举出新的主,无需人工干预。
  • 支持单主(默认)与多主(所有成员都可写)两种模式。

它和普通主从复制在"内部结构"上的差别:

普通复制:1 条 binlog 单向流,从库只有 IO / SQL 两个线程 组复制:每个成员"既是主也是从"——各自保留 binlog,通过 group_replication_applier 通道接收并应用组内广播的事务
  • 成员收到事务后先做Certification(认证 / 冲突检测):把事务涉及的写集(write set)
    与组内其他未决事务比对。写集由transaction_write_set_extraction = XXHASH64生成,
    这正是 6.3 前置条件里必须开启它的原因。
  • 认证通过的事务才会被 apply 并写进本机 binlog;认证冲突的会被回滚(多主模式见 6.11)。
┌────────────────────┐ │ 组内成员 (Paxos) │ node1 node2 node3 │ │ │ │ │ │ 33061 内网通信 └────────────────────┘

6.2 与主从复制的本质区别

对比项主从复制组复制
数据同步方式binlog 单向拉取事务在成员间广播 + 多数派确认
主库固定一个单主模式自动选举 / 多主全可写
故障转移手动自动
数据一致性异步(或半同步降级)强一致(多数派 ACK)
节点加入手动指定位点/GTID分布式恢复自动追赶

6.3 前置条件(必须全部满足)

组复制对配置有硬性要求,缺一项START GROUP_REPLICATION就会失败:

  • gtid_mode = ON、enforce_gtid_consistency = ON
  • binlog_format = ROW
  • log_slave_updates = ON
  • transaction_write_set_extraction = XXHASH64
  • disabled_storage_engines排除非 InnoDB 引擎
  • server-id唯一

将数据目录清空,重新初始化数据,防止组间数据开始同步前就不一致

几个容易踩坑的配置细节:

  • group_replication_local_address的端口(33061)不要复用SQL 端口(3306),两者职责不同。
  • 每张业务表必须有主键(原因见 6.11),否则 MGR 会拒绝写入。
  • 每个节点的复制账号和密码必须一致,否则新节点加入时很可能在已有的节点中同步不到数据。
  • 防火墙放通3306与33061,并确认 SELinux 不拦截 mysqld 的网络访问。

6.4 关键:为什么要"分两次启动"(重点)

在搭建组复制时,第一次用基础配置启动,第二次再补上组复制配置。
原因有四个,任何一个都会让"一次全配"失败:

  1. group_replication_start_on_boot默认是 ON。
    一旦plugin_load_add加载了插件,它就会在启动时尝试自动启动组复制。而此刻
    数据目录刚初始化、恢复账号还没建、组还不存在 → 直接报错:
    [ERROR] Plugin group_replication reported: 'The group name option is mandatory'
    或'Unable to start Group Replication on boot'。所以配置期必须显式
    group_replication_start_on_boot = OFF。

  2. group_replication_bootstrap_group绝不能写进配置文件。
    官方文档明确警告:若把bootstrap_group=ON写进 my.cnf,每次重启都会自动
    引导出一个同名新组
    ,制造出两个互相独立的组(脑裂)。引导必须只在运行时、
    只由第一个成员、只执行一次。

  3. 恢复通道账号必须手工创建。
    节点间分布式恢复依赖group_replication_recovery通道的复制账号,而账号只能用
    SQL 在建好的实例上创建——这就要求实例先能正常启动一次。

  4. 插件加载需要重启。
    plugin_load_add只在启动时生效,天然把流程拆成"先启动建账号 → 重启加载插件"。

正确流程(本章全程按此执行):

第 1 次启动:基础配置(无任何 group_replication_* 项) → 建恢复账号 → 停机 第 2 次启动:追加组复制配置(加载插件、start_on_boot=OFF) → 运行时引导/加入

6.5 第一次启动:基础配置

启动并进入 MySQL,创建组复制恢复账号(三台节点都要做,账号密码一致):

账号需要BACKUP_ADMIN:8.0 组复制做分布式恢复时可能用到 clone 插件,
没有该权限节点会卡在 RECOVERING。
每个节点的复制账号和密码必须一致,否则新节点加入时可能会数据拉取失败。

之后 退出 进入第二次配置。

6.6 第二次启动:追加组复制配置

在/etc/my.cnf追加(node1 示例):

配置说明:

参数作用
plugin_load_add启动时加载组复制插件
group_replication_group_name组名,必须是合法 UUID,全组一致
group_replication_start_on_boot配置期必须 OFF,成功后可按需改 ON
group_replication_local_address本节点内部通信地址(33061)
group_replication_group_seeds组内全部成员的种子地址
group_replication_bootstrap_group引导开关,保持 OFF,运行时临时开
group_replication_single_primary_modeON=单主模式(默认)

node2 / node3 追加同样内容,仅将local_address改成各自 IP和各自的server-id。

三台节点依次systemctl restart mysqld启动。

6.7 引导第一个成员(node1)

SETGLOBALgroup_replication_bootstrap_group=ON;-- 只此一次!STARTGROUP_REPLICATION;SETGLOBALgroup_replication_bootstrap_group=OFF;-- 立刻关掉

查看成员状态:期望看到 server1 为ONLINE:

6.8 加入其余成员(node2 / node3)

node2、node3 上直接执行(不要引导):

CHANGE MASTERTOMASTER_USER='repl',MASTER_PASSWORD='repl'FORCHANNEL'group_replication_recovery';STARTGROUP_REPLICATION;

⚠️ 从节点加入要求数据一致:若从节点已有与组不一致的数据,会卡在RECOVERING。
最稳妥做法是从节点数据目录保持为空/全新,由组复制通过 binlog 或 clone 自动追赶。

全部加入后,在任意节点查询:

SELECT*FROMperformance_schema.replication_group_members;

三个成员都应为ONLINE。

6.9 验证组复制

单主模式下主库自动切换验证:杀掉 node1 的 mysqld 进程:

systemctl stop mysqld# 在 node1 上模拟主库宕机

在 node2 上观察:

SELECT*FROMperformance_schema.replication_group_members;-- node1 变为 UNREACHABLE / 数秒后被移出,node2 或 node3 自动变为 PRIMARYSHOWSTATUSLIKE'group_replication_primary_member';

剩余成员会自动选举新主,业务连接切到新主后继续读写,全程无需人工介入。
把 node1 重新启动后,它也会自动重新加入组并追平数据:

STARTGROUP_REPLICATION;-- 若 start_on_boot=OFF 需手动执行

组复制日常监控(任意成员执行):

SELECT*FROMperformance_schema.replication_group_members;-- 成员状态:ONLINE / RECOVERING ...SHOWSTATUSLIKE'group_replication_primary_member';-- 当前主节点SELECT*FROMperformance_schema.replication_group_member_stats;-- 各成员事务吞吐 / 冲突数
关注项含义
MEMBER_STATEONLINE正常;RECOVERING正在追赶;UNREACHABLE/ERROR异常
MEMBER_ROLE8.0 起显示PRIMARY(当前主)或SECONDARY
COUNT_TRANSACTIONS_CHECKED/COUNT_CONFLICTS_DETECTED认证事务数与冲突数,冲突数增长要警惕并发写同一行
group_replication_primary_member当前主节点的成员 ID,与MEMBER_ID对照

6.10 分布式恢复(Distributed Recovery)

新成员START GROUP_REPLICATION后,状态会先停在RECOVERING,通过分布式恢复追赶数据:

  • 方式一:基于 binlog 恢复。新成员向组内某个"捐助者(donor)"要 binlog,从它缺少的
    GTID 处继续拉取。前提是 donor 上对应的 binlog还没被 purge。
  • 方式二:基于 CLONE 插件。若新成员需要的 binlog 已被清理(所需 GTID 已被包含在
    gtid_purged中),无法增量恢复,就需要用CLONE插件全量克隆donor 数据再继续。
    这也是 6.5 中恢复账号要授BACKUP_ADMIN的原因。
-- 查看恢复通道的进度与报错SELECT*FROMperformance_schema.replication_connection_statusWHERECHANNEL_NAME='group_replication_recovery'\G

6.11 多主模式与冲突检测

把group_replication_single_primary_mode = OFF即进入多主模式,所有成员都可写。
多节点并发修改不同行没有问题;但两个成员同时改同一行时:

  • 后认证的事务检测到写集冲突,会被回滚并返回错误(提示事务冲突,业务需自行重试)。
  • 因此多主模式要求业务写入按行尽量分散(如按用户 ID 分片),且所有表必须有主键——
    没有主键的表无法生成写集,MGR 直接拒绝。
-- 切换多主模式需停组后所有节点改配置并重启,不是热切换SETGLOBALgroup_replication_single_primary_mode=OFF;

7. 四种复制方式对比

特性传统主从GTID半同步组复制 MGR
复制定位方式binlog 文件 + 位点全局事务 ID基于 GTID基于 GTID + Paxos
一致性级别异步(可能丢数据)异步(可精确定位)至少 1 个从库 ACK多数派 ACK,强一致
可写节点仅主仅主仅主单主 1 个 / 多主全部
自动选主否需借助工具需借助工具是(单主模式)
故障转移手动找位点手动但顺滑手动但顺滑自动
脑裂防护无无无quorum 多数派
架构复杂度低低中高
网络开销1 条 binlog 流1 条 binlog 流1 条流 + ACK 往返组内广播 + 认证
额外端口3306330633063306 + 33061
事务提交延迟低低每事务 +1 RTT更高(广播 + 认证)

选型建议:

  • 数据可少量丢失、切换可手动 → 传统主从 / GTID。
  • 追求"尽量不丢"且接受手动切换 → GTID + 半同步。
  • 要自动高可用、数据强一致 → 组复制(MGR)单主模式。

  • 主从复制解决"读写分离 + 备份容灾",是最基础的复制形态。
  • GTID给每个事务打上全局唯一编号,解决了主从切换"找位点难"的痛点。
  • 半同步通过至少一个从库 ACK,把"必然丢数据"压缩到极小概率,超时降级保可用。
  • 组复制用 Paxos 多数派共识实现了自动选主与强一致,是高可用的官方正解。

参考文档

  • MySQL 8.0 Reference Manual :: 20 Group Replication
  • MySQL 8.0 Reference Manual :: 20.2.1.5 Bootstrapping the Group
  • MySQL 8.0 Reference Manual :: START GROUP_REPLICATION
  • MySQL 8.0 Reference Manual :: Semi-Synchronous Replication
  • MySQL 8.0 Reference Manual :: GTID 相关章节
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 1:52:36

西班牙团队开源 AI 评分平台 EvaluAI:加评分标准反而更不准,但更稳定

批改开放式试题一直是高等教育最难啃的瓶颈之一。选择题可以秒级机评&#xff0c;但论文、证明题和算法设计题依赖人工判断&#xff0c;而人工判断慢、贵且不一致。西班牙埃斯特雷马杜拉大学团队近日开源了 EvaluAI——一个用大语言模型批改自由文本作业、生成反馈并交由教师审…

作者头像 李华
网站建设 2026/10/20 1:48:13

AI 换脸的伦理红线:FaceSwap_MiniMaxH3_REF2VA 合规使用与安全指南

【免费下载链接】FaceSwap_MiniMaxH3_REF2VA 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/UntMods/FaceSwap_MiniMaxH3_REF2VA 点击查看 免费下载 AI 换脸技术正以惊人的速度进化&#xff0c;基于 MiniMax-H3 模型的视频换脸 LoRA——FaceSwap_MiniMaxH3_REF2VA&…

作者头像 李华
网站建设 2026/10/20 1:47:37

C++中function的实现原理详解

前言 std::function 是 C11 引入的通用可调用对象包装器。它能把普通函数、函数指针、lambda、成员函数指针、重载了 operator() 的类对象&#xff0c;统统装进同一个类型里&#xff0c;于是容器、回调注册表、任务队列都可以用统一的方式保存和调用。它解决的问题是“类型擦除…

作者头像 李华
网站建设 2026/10/20 1:47:37

STM32+云平台+Qt:从零搭建智能家居控制系统全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华