6.6.4 GTID复制与故障切换

GTID(Global Transaction ID)复制为每个事务分配全局唯一ID,使复制位点可自动定位并支持跨链路对齐,减少手工找 binlog/position 的风险,适合多级复制与跨机房拓扑。故障切换时通过 GTID 集合判断“最新”从库,提升自动化切换成功率。

原理草图(事务生成、复制、自动定位):

文章图片

一、前置条件与配置示例(含安装与关键参数解释)
- MySQL 5.7/8.0 均支持 GTID;建议 binlog_format=ROW。
- 所有实例:server_id 唯一、开启 log_bin、统一 gtid_mode。
- 从库启用 log_slave_updates,保证向下游继续传播 GTID。

安装示例(基于 Ubuntu/Debian):

# 安装 MySQL(示例 8.0)
apt-get update
apt-get install -y mysql-server

# 确认版本
mysql -uroot -p -e "SELECT VERSION();"

主库配置(/etc/mysql/mysql.conf.d/mysqld.cnf):

[mysqld]
server_id=1
log_bin=/var/lib/mysql/mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
skip_name_resolve=ON

从库配置(/etc/mysql/mysql.conf.d/mysqld.cnf):

[mysqld]
server_id=2
log_bin=/var/lib/mysql/mysql-bin
binlog_format=ROW
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
read_only=ON
super_read_only=ON

配置生效:

systemctl restart mysql

关键参数解释:
- gtid_mode=ON:启用 GTID。
- enforce_gtid_consistency=ON:阻止不兼容 GTID 的事务。
- log_slave_updates=ON:从库应用事务后写 binlog,供下游复制。

二、GTID 复制搭建(含完整命令与预期结果)
1)在主库创建复制用户:

CREATE USER 'repl'@'10.%' IDENTIFIED BY 'Repl@123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.%';
FLUSH PRIVILEGES;

2)主库查看 GTID 与状态:

SHOW MASTER STATUS\G
SHOW VARIABLES LIKE 'gtid_mode';

预期关键字段:
- Executed_Gtid_Set 有值
- gtid_mode = ON

3)从库设置自动定位并启动复制:

STOP REPLICA;
CHANGE MASTER TO
  MASTER_HOST='10.0.0.1',
  MASTER_USER='repl',
  MASTER_PASSWORD='Repl@123',
  MASTER_PORT=3306,
  MASTER_AUTO_POSITION=1;
START REPLICA;

4)从库检查复制状态:

SHOW REPLICA STATUS\G

预期结果:
- Replica_IO_Running: Yes
- Replica_SQL_Running: Yes
- Retrieved_Gtid_Set 与 Executed_Gtid_Set 不断增长

三、故障切换(人工流程示例)
目标:选择 GTID 最完整的从库为新主库,避免事务丢失。

1)确认旧主库不可用,停止对外写入(代理层/应用侧)
2)候选从库评估:

SHOW REPLICA STATUS\G
-- 关注 Executed_Gtid_Set 与 Seconds_Behind_Source

3)提升候选从库为新主库:

STOP REPLICA;
RESET REPLICA ALL;
SET GLOBAL read_only=OFF;
SET GLOBAL super_read_only=OFF;

4)其他从库指向新主库:

STOP REPLICA;
CHANGE MASTER TO
  MASTER_HOST='10.0.0.2',
  MASTER_USER='repl',
  MASTER_PASSWORD='Repl@123',
  MASTER_PORT=3306,
  MASTER_AUTO_POSITION=1;
START REPLICA;

5)更新应用连接/VIP/代理(如 Keepalived/ProxySQL),确保单主写入。

四、排错与常见问题定位
1)GTID 相关错误:
- 报错示例:ERROR 1782 (HY000): GTID inconsistent
排查与处理:

SHOW VARIABLES LIKE 'gtid_mode';
SHOW VARIABLES LIKE 'enforce_gtid_consistency';

确认所有实例一致为 ON。

2)复制中断(IO/SQL 线程):

SHOW REPLICA STATUS\G
-- 重点字段:Last_IO_Error、Last_SQL_Error
  • 权限问题:检查复制用户权限
  • 网络问题:telnet/3306 或检查防火墙
  • binlog 缺失:确认主库 binlog 保留期限 expire_logs_days
  • 数据冲突:定位冲突事务后谨慎跳过
SET GLOBAL sql_slave_skip_counter=1;  -- 仅用于 position 复制
-- GTID复制不要随意跳过,可使用 GTID 正确修复或重建

3)延迟过高:

SHOW REPLICA STATUS\G
-- Seconds_Behind_Source

优化建议:提升硬件 IO、并行复制(slave_parallel_workers)、检查长事务。

五、练习(含命令与检查点)
1)练习一:搭建一主一从 GTID 复制
- 要求:gtid_mode=ON,MASTER_AUTO_POSITION=1
- 检查点:SHOW REPLICA STATUS\G 线程均为 Yes

2)练习二:模拟主库宕机切换
- 操作:停止主库 MySQL 服务

systemctl stop mysql
  • 在从库提升为主库并改写只读
  • 检查点:新主库可写,新从库已同步

3)练习三:查看 GTID 集合并比对

SHOW GLOBAL VARIABLES LIKE 'gtid_executed';
SHOW REPLICA STATUS\G
  • 检查点:Executed_Gtid_Set 是否包含 Retrieved_Gtid_Set

六、运维建议与脚本示例(简化切换)
切换脚本示例(候选从库提升为主库):

#!/bin/bash
mysql -uroot -p'Passw0rd' -e "
STOP REPLICA;
RESET REPLICA ALL;
SET GLOBAL read_only=OFF;
SET GLOBAL super_read_only=OFF;
"
echo "Promoted to new primary."

结合 ProxySQL/Keepalived 可实现入口自动切换;定期执行 GTID 一致性检查与演练,确保故障切换路径可用。