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 一致性检查与演练,确保故障切换路径可用。