mysql基于GTID搭建复制集群

在 MySQL 中配置 GTID(全局事务标识符,Global Transaction Identifier)以支持主从切换和故障转移是一个常见的高可用性需求。


1. 什么是 GTID?

GTID 是一个全局唯一的事务标识符,用于标记每个事务。它在主从复制中简化了故障转移,因为从库可以根据 GTID 自动定位到主库的事务位置,避免了传统基于二进制日志文件和位置(binlog file + position)的手动定位。(1.简化定位主库binlog-file pos 2.第一次建立自动同步主库所有数据?如果主库binlog刷新了会同步吗?待确认)


2. 前提条件

  • MySQL 版本需要是 5.6 或更高(推荐 8.0+,GTID 支持更完善)。
  • 主库和从库的 MySQL 版本应尽量一致。
  • 主从之间的网络连接正常。
  • 主库已启用二进制日志(binlog)。

3. 配置步骤

步骤 1:修改主库和从库的配置文件

编辑 MySQL 的配置文件(通常是 /etc/my.cnf/etc/mysql/my.cnf,具体路径取决于系统)。

主库配置

[mysqld] 部分添加以下内容:

1
2
3
4
5
6
[mysqld]
server-id = 1 # 唯一标识,主库设为 1
log_bin = mysql-bin # 启用二进制日志
binlog_format = ROW # GTID 要求使用 ROW 格式
gtid_mode = ON # 启用 GTID
enforce_gtid_consistency = ON # 强制 GTID 一致性
从库配置

[mysqld] 部分添加以下内容(假设从库有两台,server-id 分别为 2 和 3):

1
2
3
4
5
6
7
8
[mysqld]
server-id = 2 # 唯一标识,从库设为不同于主库的值
log_bin = mysql-bin # 从库也启用 binlog,以便将来切换为主库
binlog_format = ROW # 保持与主库一致
gtid_mode = ON # 启用 GTID
enforce_gtid_consistency = ON # 强制 GTID 一致性
read_only = ON # 从库只读(可选)
relay_log = relay-log # 中继日志文件

注意:如果从库将来可能切换为主库,建议也启用 log_bin,否则从库无法生成新的 binlog。

步骤 2:重启主库和从库

修改配置文件后,重启 MySQL 服务以应用配置:

1
2
systemctl restart mysql       # CentOS/RHEL
service mysql restart # Debian/Ubuntu

步骤 3:检查 GTID 是否启用

在主库和从库上分别执行以下命令,确认 GTID 已启用:

1
SHOW VARIABLES LIKE 'gtid_mode';

输出应为:

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_mode     | ON    |
+---------------+-------+

步骤 4:配置主从复制

  1. 在主库上创建复制用户
    在主库上执行:

    1
    2
    3
    CREATE USER 'repl'@'%' IDENTIFIED BY 'your_password';
    GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
    FLUSH PRIVILEGES;
  2. 获取主库的 GTID 状态
    在主库上执行:

    1
    SHOW MASTER STATUS;

    输出类似:
    +——————+———-+————–+——————+——————-+
    | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +——————+———-+————–+——————+——————-+
    | mysql-bin.000001 | 154 | | | 123e4567-e89b-12d3-a456-426655440000:1-5 |
    +——————+———-+————–+——————+——————-+
    记录 Executed_Gtid_Set,它表示当前主库已执行的事务。(为后续slave 建立复制时比对)

  3. 在从库上配置复制
    在从库上执行以下命令:

    1
    2
    3
    4
    5
    6
    CHANGE MASTER TO
    MASTER_HOST = '主库IP地址',
    MASTER_PORT = 3306,
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'your_password',
    MASTER_AUTO_POSITION = 1; # 使用 GTID 自动定位
  4. 启动从库复制

    1
    START SLAVE;
  5. 检查从库状态

    1
    SHOW SLAVE STATUS\G

    确认以下字段:

    • Slave_IO_Running: Yes
    • Slave_SQL_Running: Yes
    • Last_Error 为空
    • Retrieved_Gtid_SetExecuted_Gtid_Set 逐步与主库一致

主库上日志,可以清晰看出建立复制后,master开始binlog_dump

2025-02-25T01:10:28.631994Z 4 [Note] Start binlog_dump to master_thread_id(4) slave_server(2), pos(, 4)
2025-02-25T01:10:33.235486Z 5 [Note] Start binlog_dump to master_thread_id(5) slave_server(1), pos(, 4)
2025-02-25T01:11:27.976348Z 1 [Note] Slave I/O thread for channel '': connected to master '[email protected]:3306',replication started in log 'mysql-bin.000003' at position 653

4. 主从切换和故障转移

场景:主库故障,需要切换到从库

  1. 停止从库的复制
    在目标从库(例如 server-id=2)上执行:

    1
    STOP SLAVE;
  2. 检查 GTID 一致性
    确保从库的 Executed_Gtid_Set 已追上主库(通过 SHOW SLAVE STATUS 查看)。

           Retrieved_Gtid_Set: 4dfe51b2-f2b7-11ef-8924-0242c0a8d704:1-5
            Executed_Gtid_Set: 4a308329-f2b7-11ef-97f0-0242c0a8d703:1-2,
4dfe51b2-f2b7-11ef-8924-0242c0a8d704:1-5
                Auto_Position: 1
  1. 将从库提升为主库
    在从库上执行:

    1
    2
    3
    RESET MASTER;  # 重置 GTID,生成新的 GTID 序列
    RESET SLAVE; # 重置历史复制信息
    SET GLOBAL read_only = OFF; # 取消只读模式
  2. 将其他从库指向新的主库
    在其他从库(例如 server-id=3)上执行:

    1
    2
    3
    4
    5
    6
    7
    STOP SLAVE;
    CHANGE MASTER TO
    MASTER_HOST = '新主库IP地址',
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'your_password',
    MASTER_AUTO_POSITION = 1;
    START SLAVE;
  3. 验证新架构
    在新主库写入数据,检查其他从库是否同步。


5. 注意事项

  • GTID 的限制:启用 enforce_gtid_consistency 后,不支持非事务引擎(如 MyISAM)或某些 DDL 操作(如 CREATE TABLE ... SELECT),建议所有表使用 InnoDB。
  • 备份与恢复:故障转移后,原主库恢复时需先清空其 GTID(RESET MASTER),然后作为从库加入新架构。
  • 监控:建议使用工具(如 MySQL Enterprise Monitor 或 Percona Monitoring)监控复制延迟和状态。
mysql> create table t4 select * from t3;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.

4501995397fb11d73a34eb8f028385aa.png


6. 测试

在主库插入测试数据:

1
2
3
4
5
6
CREATE DATABASE test_db;
USE test_db;

CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50));

INSERT INTO test_table (name) VALUES ('test1'), ('test2');

检查从库是否同步:

1
SELECT * FROM test_db.test_table;

如果数据一致,主从复制和 GTID 配置成功。