Skip to content

MySQL 组复制部署

环境准备

硬件要求

  • CPU:至少4核CPU
  • 内存:至少8GB RAM
  • 磁盘:SSD磁盘,至少100GB可用空间
  • 网络:高性能网络,低延迟

软件要求

  • MySQL版本:MySQL 5.7.17或更高版本,推荐使用MySQL 8.0
  • 操作系统:Linux(推荐CentOS 7/8,Ubuntu 18.04/20.04)
  • Java环境:MySQL Shell需要Java 8或更高版本

网络配置

  • 所有节点必须能够相互通信
  • 开放以下端口:
    • MySQL服务端口:3306
    • 组复制通信端口:33061
    • MySQL Shell端口:33062(可选)

节点规划

以3节点组复制为例,节点规划如下:

节点名称IP地址角色
node1192.168.1.101主节点/成员节点
node2192.168.1.102主节点/成员节点
node3192.168.1.103主节点/成员节点

配置步骤

1. 安装MySQL

在所有节点上安装MySQL 8.0:

bash
# CentOS 7/8
sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
sudo yum install mysql-community-server

# Ubuntu 18.04/20.04
sudo apt update
sudo apt install mysql-server

2. 基础配置

在所有节点上修改MySQL配置文件 /etc/my.cnf/etc/mysql/mysql.conf.d/mysqld.cnf

ini
# 基本配置
server-id = 101  # 每个节点必须唯一,建议使用IP地址的最后一段
port = 3306
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid

# 二进制日志配置
log-bin = mysql-bin
binlog-format = ROW
binlog-row-image = FULL
expire_logs_days = 7

# 复制配置
gtid-mode = ON
enforce-gtid-consistency = ON
master-info-repository = TABLE
relay-log-info-repository = TABLE
relay-log-recovery = ON
slave-preserve-commit-order = ON
slave-parallel-type = LOGICAL_CLOCK
slave-parallel-workers = 4

# 组复制配置
transaction-write-set-extraction = XXHASH64
loose-group-replication-group-name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group-replication-start-on-boot = OFF
loose-group-replication-local-address = "192.168.1.101:33061"  # 每个节点使用自己的IP地址
loose-group-replication-group-seeds = "192.168.1.101:33061,192.168.1.102:33061,192.168.1.103:33061"
loose-group-replication-single-primary-mode = OFF  # 0表示多主模式,1表示单主模式
loose-group-replication-enforce-update-everywhere-checks = ON
loose-group-replication-autorejoin-tries = 3

3. 启动MySQL服务

在所有节点上启动MySQL服务:

bash
# CentOS 7/8
sudo systemctl start mysqld
sudo systemctl enable mysqld

# Ubuntu 18.04/20.04
sudo systemctl start mysql
sudo systemctl enable mysql

4. 初始化MySQL

在所有节点上执行MySQL初始化:

bash
# 获取临时密码
sudo grep 'temporary password' /var/log/mysqld.log

# 安全初始化
mysql_secure_installation

5. 创建复制用户

在所有节点上创建用于组复制的用户:

sql
# 登录MySQL
mysql -u root -p

# 创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'ReplicationPass123!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

6. 配置组复制通信用户

在所有节点上配置组复制通信用户:

sql
# 登录MySQL
mysql -u root -p

# 配置复制通道
CHANGE REPLICATION SOURCE TO 
    SOURCE_USER='repl', 
    SOURCE_PASSWORD='ReplicationPass123!' 
    FOR CHANNEL 'group_replication_recovery';

7. 安装组复制插件

在所有节点上安装组复制插件:

sql
# 登录MySQL
mysql -u root -p

# 安装组复制插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

# 验证插件是否安装成功
SHOW PLUGINS LIKE 'group_replication';

启动组复制

1. 启动第一个节点

在第一个节点(node1)上启动组复制:

sql
# 登录MySQL
mysql -u root -p

# 启动组复制(第一个节点使用bootstrap组)
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;

# 查看组复制状态
SELECT * FROM performance_schema.replication_group_members;

2. 启动其他节点

在其他节点(node2、node3)上启动组复制:

sql
# 登录MySQL
mysql -u root -p

# 启动组复制
START GROUP_REPLICATION;

# 查看组复制状态
SELECT * FROM performance_schema.replication_group_members;

验证组复制

1. 查看组复制成员状态

在任意节点上执行:

sql
SELECT * FROM performance_schema.replication_group_members;

2. 查看组复制状态

在任意节点上执行:

sql
SHOW STATUS LIKE 'group_replication%';

3. 测试数据一致性

在任意节点上创建测试数据库和表:

sql
CREATE DATABASE test_db;
USE test_db;
CREATE TABLE test_table (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50));
INSERT INTO test_table (name) VALUES ('test1'), ('test2'), ('test3');

在其他节点上验证数据是否同步:

sql
USE test_db;
SELECT * FROM test_table;

组复制管理

1. 查看组复制成员状态

sql
SELECT * FROM performance_schema.replication_group_members;
SELECT * FROM performance_schema.replication_group_member_stats;

2. 添加新节点

按照前面的配置步骤配置新节点,然后启动组复制:

sql
START GROUP_REPLICATION;

3. 移除节点

在要移除的节点上执行:

sql
STOP GROUP_REPLICATION;

或者在任意节点上执行:

sql
SELECT group_replication_remove_member('member_uuid');

4. 切换单主/多主模式

从多主模式切换到单主模式

sql
# 在所有节点上执行
SET GLOBAL group_replication_single_primary_mode = ON;
SET GLOBAL group_replication_enforce_update_everywhere_checks = OFF;

# 重启组复制
STOP GROUP_REPLICATION;
START GROUP_REPLICATION;

从单主模式切换到多主模式

sql
# 在所有节点上执行
SET GLOBAL group_replication_single_primary_mode = OFF;
SET GLOBAL group_replication_enforce_update_everywhere_checks = ON;

# 重启组复制
STOP GROUP_REPLICATION;
START GROUP_REPLICATION;

5. 手动选择主节点

在单主模式下,可以手动选择主节点:

sql
SELECT group_replication_set_as_primary('member_uuid');

6. 监控组复制

监控组复制状态

sql
SHOW STATUS LIKE 'group_replication%';
SELECT * FROM performance_schema.replication_group_members;
SELECT * FROM performance_schema.replication_group_member_stats;
SELECT * FROM performance_schema.replication_transaction_incoming;

使用Performance Schema监控

sql
SELECT * FROM performance_schema.replication_group_member_stats;
SELECT * FROM performance_schema.replication_applier_status_by_worker;
SELECT * FROM performance_schema.replication_connection_status;

常见问题与解决方案

1. 节点无法加入组

问题现象

ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log.

解决方案

  • 检查server-id是否唯一
  • 检查group-replication-group-name是否一致
  • 检查网络连接和端口开放情况
  • 检查二进制日志配置是否正确
  • 检查GTID配置是否正确

2. 组复制停止工作

问题现象

ERROR 3096 (HY000): The server was automatically set into read only mode after an error was detected.

解决方案

  • 查看错误日志,定位具体问题
  • 检查节点间网络连接
  • 检查数据一致性
  • 尝试重新启动组复制:
    sql
    STOP GROUP_REPLICATION;
    START GROUP_REPLICATION;

3. 脑裂问题

问题现象:组分裂成多个子组,每个子组都认为自己是主组。

解决方案

  • 确保网络稳定
  • 使用至少3个节点,避免偶数节点
  • 配置合适的group_replication_autorejoin_tries参数
  • 定期监控组状态

4. 性能问题

问题现象:组复制性能低于预期。

解决方案

  • 确保使用SSD磁盘
  • 增加slave-parallel-workers参数值
  • 优化应用程序,减少大事务
  • 考虑使用单主模式

版本差异

MySQL 5.7 vs MySQL 8.0

  1. 组复制功能增强

    • MySQL 8.0引入了自动重新加入机制
    • MySQL 8.0支持更多的组复制状态监控指标
    • MySQL 8.0优化了组复制的性能
  2. 配置参数变化

    • MySQL 8.0中,部分参数名去掉了loose-前缀
    • MySQL 8.0新增了一些组复制相关参数
  3. 插件安装

    • MySQL 8.0中,组复制插件默认安装,但需要手动启用
  4. 监控增强

    • MySQL 8.0提供了更丰富的Performance Schema视图
    • MySQL 8.0支持通过JSON格式查看组复制状态

生产环境最佳实践

1. 节点数量

  • 建议使用奇数节点,至少3个节点
  • 最大建议不超过9个节点,节点过多会影响性能

2. 硬件配置

  • 使用高性能SSD磁盘
  • 每个节点至少8GB内存
  • 配置足够的CPU核心
  • 确保节点间网络低延迟、高带宽

3. 网络配置

  • 使用专用网络进行组复制通信
  • 配置合适的防火墙规则,只允许组内节点通信
  • 考虑使用bonding或teaming提高网络可用性

4. 监控与告警

  • 监控组复制成员状态
  • 监控组复制性能指标
  • 监控二进制日志和中继日志大小
  • 设置告警规则,当节点状态异常时及时通知

5. 备份策略

  • 定期备份组内至少一个节点的数据
  • 使用逻辑备份或物理备份
  • 测试备份恢复流程

6. 升级策略

  • 采用滚动升级方式,逐个升级节点
  • 升级前备份数据
  • 升级后验证组复制状态

常见问题(FAQ)

Q1: 组复制支持哪些存储引擎?

A1: 组复制只支持InnoDB存储引擎,因为它需要事务支持和行级锁。

Q2: 组复制的多主模式和单主模式有什么区别?

A2:

  • 单主模式:只有一个主节点可以写入,其他节点为只读节点,主节点故障时自动选举新的主节点。
  • 多主模式:所有节点都可以写入,需要确保应用程序能够处理写入冲突。

Q3: 如何处理组复制中的写入冲突?

A3: 在多主模式下,可能会发生写入冲突。MySQL组复制会自动检测冲突,并回滚冲突的事务。可以通过以下方式减少冲突:

  • 设计应用程序,避免在多个节点上同时修改同一行数据
  • 使用单主模式
  • 合理设计数据分片策略

Q4: 组复制需要多少带宽?

A4: 组复制的带宽需求取决于写入量和事务大小。一般建议每个节点至少1Gbps的网络带宽。

Q5: 如何备份组复制集群?

A5: 可以选择任意节点进行备份,建议:

  • 使用mysqldump或xtrabackup进行备份
  • 定期备份,建议每天至少一次
  • 备份二进制日志,以便进行时间点恢复

Q6: 如何从组复制集群中移除一个节点?

A6: 可以使用以下方法移除节点:

  1. 在要移除的节点上执行:STOP GROUP_REPLICATION;
  2. 或者在任意节点上执行:SELECT group_replication_remove_member('member_uuid');

Q7: 组复制支持跨数据中心部署吗?

A7: 组复制支持跨数据中心部署,但需要考虑网络延迟的影响。建议:

  • 使用至少3个数据中心
  • 确保数据中心间网络延迟较低
  • 考虑使用单主模式

Q8: 如何监控组复制的性能?

A8: 可以通过以下方式监控组复制性能:

  • 使用Performance Schema视图
  • 监控group_replication_transaction_size和group_replication_transaction_count指标
  • 监控复制延迟
  • 使用第三方监控工具,如Prometheus+Grafana

Q9: 组复制中的节点故障如何处理?

A9: 当节点故障时,组复制会自动检测并将其从组中移除。如果节点可以恢复,可以重新启动组复制使其重新加入组:START GROUP_REPLICATION;

Q10: 如何升级组复制集群?

A10: 建议采用滚动升级方式:

  1. 停止一个节点的组复制:STOP GROUP_REPLICATION;
  2. 停止MySQL服务:systemctl stop mysqld;
  3. 升级MySQL版本
  4. 启动MySQL服务:systemctl start mysqld;
  5. 启动组复制:START GROUP_REPLICATION;
  6. 验证节点状态:SELECT * FROM performance_schema.replication_group_members;
  7. 对其他节点重复上述步骤