灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL

    • MySQL 运维知识地图:从入门配置到高可用排障
    • MySQL8 配置文件 my.cnf 重要参数解读
    • MySQL 导出 CSV 中文乱码:字符集链路从头讲一遍
    • MySQL 角色管理
    • MySQL网络抓包审计
    • MySQL 性能压测:Sysbench 1.0 实战
    • MySQL Router 实现读写分离
    • Gh-ost重建表,清除表碎片率
    • MySQL MGR配合MySQL-router实现innodb-cluster
      • 0. 先满足前置条件,否则 START GROUP_REPLICATION 一定失败
      • MGR 部署
        • my.cnf配置参数
        • 1.先创建一个用户
        • 再进行授权
        • 2.安装插件
        • 3.配置master实例
      • 验证
      • 坑与边界
    • MySQL 快速分析binlog定位问题
    • MySQL执行计划分析
    • DBA常用SQL和命令整理备查
    • 单表数据同步方案选型:为什么不该用 mysqldump 做「实时同步」
    • MySQL的事务隔离级别
    • MySQL存储过程批量生成数据
    • MySQL insert on duplicate key update,replace into , insert ignore的理解
    • MySQL不同字符集之间的区别和选择
    • MySQL为什么有时候会选错索引
    • MySQL死锁问题
    • MySQL使用SQL语句查重去重
    • MySQLdump逻辑备份
    • MySQL 基于 GTID 主从复制:跳过异常事务的正确姿势
    • MySQL8快速克隆插件使用指南
    • MySQL8双1设置保障安全
    • MySQL锁
    • innodb cluster安装
    • OPTIMIZE TABLE 和 ANALYZE TABLE 的区别:用实测数据说话
    • MySQLReplicaSet 安装
    • MySQL 的 Left join、Right join 和 Inner join 的区别
    • ORDER BY 配合 LIMIT 触发的索引选择陷阱
  • Redis

  • 高性能KV

  • TiDB

  • Elasticsearch

  • 数据管道

  • 其他数据库

  • 数据库
  • MySQL
灯下哥谭
2022-03-10
目录

MySQL MGR配合MySQL-router实现innodb-cluster原创

# 0. 先满足前置条件,否则 START GROUP_REPLICATION 一定失败

MGR 有一组硬性前提,不满足时报错信息往往指向别处,很容易排查半天。建集群前逐条确认:

版本说明

本文写于 2022-03,基于 MySQL 8.0 Group Replication。
MGR 的核心机制(Paxos 协议、单主/多主模式)未变,经 2026-07 复核仍适用;8.0 后续小版本对 MGR 的自动化运维(如 group_replication_communication_stack 参数、Clone 插件配合分布式恢复)有增强,新部署建议一并核对官方最新文档。

[mysqld]
server_id                 = 1        # 组内每个节点必须唯一
gtid_mode                 = ON
enforce_gtid_consistency  = ON
binlog_format             = ROW
log_bin                   = mysql-bin
log_replica_updates       = ON       # 8.0.26 前叫 log_slave_updates,必须开
1
2
3
4
5
6
7

还有一条配置检查不出来、只会在运行时炸的:所有表必须有主键或非空唯一键。无主键表在 MGR 下写入直接失败,先扫一遍:

SELECT t.TABLE_SCHEMA, t.TABLE_NAME
FROM information_schema.TABLES t
LEFT JOIN information_schema.TABLE_CONSTRAINTS c
  ON c.TABLE_SCHEMA = t.TABLE_SCHEMA AND c.TABLE_NAME = t.TABLE_NAME AND c.CONSTRAINT_TYPE = 'PRIMARY KEY'
WHERE c.CONSTRAINT_NAME IS NULL
  AND t.TABLE_SCHEMA NOT IN ('sys','mysql','performance_schema','information_schema')
  AND t.TABLE_TYPE = 'BASE TABLE';
1
2
3
4
5
6
7

预期输出:空集。

# MGR 部署

# my.cnf配置参数

单主配置

#--- group replication settings ---
plugin-load = "group_replication.so"
transaction-write-set-extraction = XXHASH64
report_host = 192.0.2.11
binlog_checksum = NONE            # 仅 8.0.20 及更早需要;8.0.21+ MGR 已支持 CRC32,新版本可删掉这行
loose_slave_preserve_commit_order = on 
loose_group_replication = FORCE_PLUS_PERMANENT
loose_group_replication_group_name = "f0d9e877-661b-487c-a955-7fae37a5c2bd"
loose_group_replication_compression_threshold = 100000       # mysql8.0.11后默认值为1000000字节,1M
loose_group_replication_flow_control_mode = 0
loose_group_replication_single_primary_mode = 1
loose_group_replication_transaction_size_limit = 331350016
loose_group_replication_member_expel_timeout = 20
loose_group_replication_unreachable_majority_timeout = 20
loose_group_replication_start_on_boot = off
loose_group_replication_local_address = '192.0.2.11:23502' #端口跟mysql端口不同即可
loose_group_replication_group_seeds = '192.0.2.12:23501,192.0.2.11:23502,192.0.2.13:23503'
loose_group_replication_ip_allowlist = '192.0.2.0/24'   # 8.0.22 起 ip_whitelist 已弃用,改名 ip_allowlist
loose_group_replication_bootstrap_group = off		
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

多主配置

##--- group replication settings 多主模式---
plugin-load = "group_replication.so"
transaction-write-set-extraction = XXHASH64
report_host = 192.0.2.15
binlog_checksum = NONE            # 仅 8.0.20 及更早需要;8.0.21+ MGR 已支持 CRC32,新版本可删掉这行
loose_slave_preserve_commit_order = on 
loose_group_replication = FORCE_PLUS_PERMANENT
loose_group_replication_group_name = "b2c8d3e1-4f5a-11ee-9c11-0242ac120002"   # 必须是一个合法且组内一致的 UUID,用 SELECT UUID() 生成,不能填全零
loose_group_replication_compression_threshold = 100000       # mysql8.0.11后默认值为1000000字节,1M
loose_group_replication_flow_control_mode = 0
loose_group_replication_single_primary_mode = 0
loose_group_replication_enforce_update_everywhere_checks = ON # 比单主多了这一行
loose_group_replication_transaction_size_limit = 331350016
loose_group_replication_member_expel_timeout = 20
loose_group_replication_unreachable_majority_timeout = 20
loose_group_replication_start_on_boot = off
loose_group_replication_local_address = '192.0.2.15:23306'
loose_group_replication_group_seeds = '192.0.2.15:23306,192.0.2.16:23306,192.0.2.17:23306'
loose_group_replication_ip_allowlist = '192.0.2.0/24'   # 8.0.22 起改名;不要写 0.0.0.0/0,等于对全网开放组通信端口
loose_group_replication_bootstrap_group = off	
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 1.先创建一个用户

create user 'repl'@'172.16.0.%' identified by 'xxxxxxxxx';
1

# 再进行授权

grant REPLICATION SLAVE on *.* to 'repl'@'172.16.0.%' ;
1

# 2.安装插件

install plugin group_replication soname 'group_replication.so';
1
show plugins;
1
select * from INFORMATION_SCHEMA.PLUGINS where PLUGIN_NAME like '%group_replication%';
1
INSTALL PLUGIN clone SONAME 'mysql_clone.so';		#可选
1

# 3.配置master实例

1)查看当前的group replication相关参数是否配置有误

show global variables like 'group%';
1

2)启动 group_replication_bootstrap_group

SET GLOBAL group_replication_bootstrap_group=ON;
1

3)配置MGR

SET GLOBAL group_replication_ip_allowlist = '192.0.2.0/24';

-- 8.0.23 起 CHANGE MASTER TO 已弃用,用新语法:
CHANGE REPLICATION SOURCE TO
  SOURCE_USER     = 'repl',
  SOURCE_PASSWORD = '<password>'
  FOR CHANNEL 'group_replication_recovery';
1
2
3
4
5
6
7

这一步在配什么:group_replication_recovery 是分布式恢复通道——新节点加入组时,靠这个通道从已有节点把落后的数据补齐。它和业务复制无关,但配错(用户名密码不对、账号没有 REPLICATION SLAVE 权限)会让节点永远停在 RECOVERING,而错误信息只会出现在错误日志里,replication_group_members 里看不出原因。

4)启动MGR

start group_replication;
1

5)关闭 group_replication_bootstrap_groups

SET GLOBAL group_replication_bootstrap_group=OFF;
1

# 验证

SELECT MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, MEMBER_ROLE
FROM performance_schema.replication_group_members;
1
2

预期输出(三个节点全部 ONLINE,单主模式下一个 PRIMARY 两个 SECONDARY):

+-------------+-------------+--------------+-------------+
| MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE |
+-------------+-------------+--------------+-------------+
| 192.0.2.11  |        3306 | ONLINE       | PRIMARY     |
| 192.0.2.12  |        3306 | ONLINE       | SECONDARY   |
| 192.0.2.13  |        3306 | ONLINE       | SECONDARY   |
+-------------+-------------+--------------+-------------+
1
2
3
4
5
6
7

MEMBER_STATE 的取值就是排障入口:

状态 含义 通常的原因
ONLINE 正常在组内服务 —
RECOVERING 正在补数据,还没进组 恢复通道账号/权限不对,或数据量大在正常追(看 replication_group_member_stats 的进度)
UNREACHABLE 其他节点认为它失联 组通信端口不通 / 网络抖动
ERROR 已被踢出组 数据分叉、执行了组不允许的操作(如无主键表写入)

写入能力确认(单主模式下 SECONDARY 应当是只读的):

SELECT @@super_read_only;   -- PRIMARY 返回 0,SECONDARY 返回 1
1

单主模式下确认谁是主:

SELECT MEMBER_HOST FROM performance_schema.replication_group_members
WHERE MEMBER_ROLE = 'PRIMARY';
1
2

# 坑与边界

  • 组通信端口(group_replication_local_address 里那个)必须单独放行,它和 MySQL 端口是两回事。只放行 3306 会让节点卡在 RECOVERING,是新搭 MGR 最高频的问题。
  • group_replication_start_on_boot = off 是刻意的。开成 on 之后,节点重启会自动尝试加入组;如果它重启前有未同步出去的事务,自动加入会导致数据分叉直接进 ERROR 状态。保持 off,重启后人工确认再 START GROUP_REPLICATION。
  • 多主模式(single_primary_mode = 0)不是「性能更好的单主」。它要求 enforce_update_everywhere_checks = ON,代价是:不支持外键级联、不支持 SERIALIZABLE、同一行的并发更新会在提交时被认证阶段直接回滚(乐观并发)。没有明确的多点写入需求就用单主。
  • 两种模式不能混:组内所有节点的 single_primary_mode 和 enforce_update_everywhere_checks 必须完全一致,不一致的节点会被拒绝加入。本文上面给的单主/多主两份配置是二选一,不是拼在一起用。
  • 多数派是硬约束:3 节点挂 2 个后,剩下的那个不会自动接管,整组不可写(ERROR 3101)。这是设计如此。确认另外两个确实回不来时才用 group_replication_force_members 强制重组——有脑裂风险,属最后手段。
  • 大事务会被直接拒绝:group_replication_transaction_size_limit(文中设的 331350016 ≈ 316MB,默认 150MB)超限的事务报错回滚。批量导数据前分批处理。
  • SET GLOBAL GTID_PURGED 是危险操作,不要当成常规修复手段。它直接改写「哪些事务算已执行」,用错会让节点跳过真实存在的数据变更,造成静默的数据不一致。只在明确知道要跳过什么、且已确认数据差异可接受时使用——处置思路见 MySQL 基于 GTID 主从复制:跳过异常事务的正确姿势。

集群化纳管(MySQL Shell + Router)见 innodb cluster 安装。

#高可用#MySQL
上次更新: 9/11/2026

← Gh-ost重建表,清除表碎片率 MySQL 快速分析binlog定位问题→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式