主备切换GTID
# 主备切换GTID
全球事务标识(GTID)是MySQL 5.6引入的重要特性,它极大地简化了主备复制架构中的主备切换过程。本文将深入探讨GTID在主备切换中的应用和最佳实践。
# 1. GTID基础概念
# 1.1 GTID的定义
全局事务标识(Global Transaction Identifier)是MySQL中用于唯一标识事务的标识符,格式为:
GTID = server_uuid:gno
-- 例如:GTID=12345678-1234-1234-1234-123456789012:100
1
2
2
其中:
server_uuid:服务器唯一标识符gno:事务编号(全局序号)
# 1.2 GTID的工作原理
-- 启用GTID
SET GLOBAL gtid_mode = ON;
SET GLOBAL enforce_gtid_consistency = ON;
-- 查看GTID状态
SHOW GLOBAL VARIABLES LIKE 'gtid_mode';
SHOW MASTER STATUS;
SHOW SLAVE STATUS\G
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 1.3 GTID的优势
- 简化主备切换:无需手动查找位点
- 自动处理重复:避免重复应用事务
- 增强可靠性:提供更强的数据一致性保障
- 简化故障恢复:快速定位缺失的事务
# 2. GTID在主备切换中的作用
# 2.1 GTID切换流程
-- 主备切换基本流程
1. 停止从库复制
STOP SLAVE;
2. 检查从库状态
SHOW SLAVE STATUS\G
3. 确认主备同步状态
SELECT @@gtid_executed;
SELECT @@gtid_purged;
4. 提升从库为主库
SET GLOBAL read_only = OFF;
5. 重新配置其他从库
CHANGE MASTER TO
MASTER_HOST='new_master_host',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='repl_password',
MASTER_AUTO_POSITION=1;
6. 启动复制
START SLAVE;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 2.2 GTID切换的优势
-- 传统切换方式(基于位点)
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='repl_password',
MASTER_LOG_FILE='master-bin.000001',
MASTER_LOG_POS=12345;
-- GTID切换方式(简化)
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='repl_password',
MASTER_AUTO_POSITION=1;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 3. GTID切换的具体步骤
# 3.1 故障切换准备
-- 1. 检查当前状态
SHOW MASTER STATUS\G
SHOW SLAVE STATUS\G
-- 2. 查看GTID信息
SELECT @@gtid_executed;
SELECT @@gtid_purged;
SELECT @@gtid_mode;
-- 3. 确保主库状态稳定
FLUSH TABLES WITH READ LOCK;
-- 确保所有事务都已提交
UNLOCK TABLES;
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 3.2 从库提升为主库
-- 1. 停止从库复制
STOP SLAVE;
-- 2. 检查从库同步状态
SHOW SLAVE STATUS\G
-- 3. 确认从库已完全同步
SELECT Seconds_Behind_Master FROM INFORMATION_SCHEMA.SLAVE_STATUS;
-- 4. 提升从库为主库
SET GLOBAL read_only = OFF;
SET GLOBAL super_read_only = OFF;
-- 5. 验证主库状态
SELECT @@read_only;
SELECT @@super_read_only;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 3.3 重新配置其他从库
-- 1. 停止从库复制
STOP SLAVE;
-- 2. 清理复制配置
RESET SLAVE ALL;
-- 3. 使用GTID重新配置
CHANGE MASTER TO
MASTER_HOST='new_master_host',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='repl_password',
MASTER_AUTO_POSITION=1;
-- 4. 启动复制
START SLAVE;
-- 5. 检查复制状态
SHOW SLAVE STATUS\G
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 4. GTID切换的高级技巧
# 4.1 GTID集合操作
-- 查看GTID集合
SELECT @@gtid_executed;
SELECT @@gtid_purged;
-- GTID集合的比较
SELECT GTID_SUBSET('12345678-1234-1234-1234-123456789012:1-100',
'12345678-1234-1234-1234-123456789012:1-50');
-- GTID集合的差集计算
SELECT GTID_SUBTRACT('12345678-1234-1234-1234-123456789012:1-100',
'12345678-1234-1234-1234-123456789012:1-50');
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 4.2 GTID一致性检查
-- 检查主备GTID一致性
SELECT
@@gtid_executed as executed_gtid_set,
@@gtid_purged as purged_gtid_set;
-- 确保从库的GTID集合是主库的子集
SELECT GTID_SUBSET(@@gtid_executed, (SELECT @@gtid_executed FROM master));
1
2
3
4
5
6
7
2
3
4
5
6
7
# 4.3 GTID故障恢复
-- 1. 如果从库GTID丢失,需要重新初始化
STOP SLAVE;
RESET SLAVE ALL;
-- 2. 重新从主库获取数据
-- 可以使用mysqldump或物理备份
-- 3. 使用GTID重新配置
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='repl_password',
MASTER_AUTO_POSITION=1;
START SLAVE;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 5. GTID切换常见问题及解决方案
# 5.1 GTID冲突问题
-- 问题:GTID冲突
-- 解决方案1:跳过特定GTID
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
-- 解决方案2:使用GTID跳过
SELECT @@gtid_executed;
-- 手动跳过特定GTID
SELECT GTID_SUBTRACT(@@gtid_executed, '12345678-1234-1234-1234-123456789012:100');
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 5.2 GTID不一致问题
-- 问题:主备GTID不一致
-- 解决方案:使用purge清理
SET GLOBAL gtid_purged = '12345678-1234-1234-1234-123456789012:1-50';
-- 或者重新初始化
STOP SLAVE;
RESET SLAVE ALL;
-- 重新进行数据同步
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 5.3 GTID切换后数据丢失
-- 预防措施:在切换前检查数据完整性
SELECT COUNT(*) FROM important_table;
-- 切换后验证数据
SELECT COUNT(*) FROM important_table;
-- 检查GTID执行情况
SELECT @@gtid_executed;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 6. GTID切换的最佳实践
# 6.1 切换前准备工作
-- 1. 检查系统状态
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Questions';
SHOW STATUS LIKE 'Com_select';
-- 2. 检查GTID配置
SHOW VARIABLES LIKE 'gtid_mode';
SHOW VARIABLES LIKE 'enforce_gtid_consistency';
-- 3. 检查复制状态
SHOW SLAVE STATUS\G
SELECT Seconds_Behind_Master FROM INFORMATION_SCHEMA.SLAVE_STATUS;
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 6.2 安全切换流程
-- 安全切换流程
BEGIN;
-- 1. 停止应用层写入
-- 2. 确认当前事务提交
SELECT @@autocommit;
-- 3. 停止从库复制
STOP SLAVE;
-- 4. 检查从库状态
SHOW SLAVE STATUS\G
-- 5. 提升从库为主库
SET GLOBAL read_only = OFF;
-- 6. 重新配置其他从库
CHANGE MASTER TO
MASTER_AUTO_POSITION=1;
-- 7. 验证新主库状态
SELECT @@read_only;
SHOW MASTER STATUS\G
COMMIT;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 6.3 切换后验证
-- 1. 验证复制状态
SHOW SLAVE STATUS\G
SELECT Seconds_Behind_Master FROM INFORMATION_SCHEMA.SLAVE_STATUS;
-- 2. 验证数据一致性
SELECT COUNT(*) FROM test_table;
SELECT @@gtid_executed;
-- 3. 测试基本功能
INSERT INTO test_table (name) VALUES ('test');
SELECT * FROM test_table WHERE name = 'test';
DELETE FROM test_table WHERE name = 'test';
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 7. GTID与不同架构的适配
# 7.1 一主一备架构
-- 一主一备切换示例
-- 主库故障时
STOP SLAVE ON slave;
SET GLOBAL read_only = OFF; -- 提升从库为主库
-- 重新配置其他从库指向新主库
1
2
3
4
5
2
3
4
5
# 7.2 一主多从架构
-- 一主多从切换示例
-- 1. 选择一个从库提升为主库
STOP SLAVE ON slave;
SET GLOBAL read_only = OFF;
-- 2. 重新配置其他从库
CHANGE MASTER TO MASTER_AUTO_POSITION=1;
START SLAVE;
-- 3. 更新应用连接配置
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 7.3 双主架构
-- 双主切换示例
-- 需要更复杂的协调机制
-- 1. 确保两个主库数据一致性
-- 2. 选择一个主库作为新的主库
-- 3. 重新配置另一个主库
1
2
3
4
5
2
3
4
5
# 8. GTID监控与告警
# 8.1 GTID状态监控
-- 创建GTID监控脚本
DELIMITER //
CREATE PROCEDURE monitor_gtid_status()
BEGIN
DECLARE executed_gtid VARCHAR(1000);
DECLARE purged_gtid VARCHAR(1000);
DECLARE delay_seconds INT;
SELECT @@gtid_executed INTO executed_gtid;
SELECT @@gtid_purged INTO purged_gtid;
SELECT Seconds_Behind_Master INTO delay_seconds
FROM INFORMATION_SCHEMA.SLAVE_STATUS;
-- 记录监控信息
INSERT INTO gtid_monitor_log (timestamp, executed_gtid, purged_gtid, delay_seconds)
VALUES (NOW(), executed_gtid, purged_gtid, delay_seconds);
END //
DELIMITER ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 8.2 GTID异常告警
-- GTID异常检测
SELECT
@@gtid_executed as executed_gtid,
@@gtid_purged as purged_gtid,
Seconds_Behind_Master as delay_seconds,
CASE
WHEN Seconds_Behind_Master > 30 THEN 'HIGH_DELAY'
WHEN Seconds_Behind_Master > 10 THEN 'MEDIUM_DELAY'
ELSE 'NORMAL'
END as delay_status
FROM INFORMATION_SCHEMA.SLAVE_STATUS;
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 9. GTID切换的性能考虑
# 9.1 切换时间优化
-- 优化切换时间的配置
SET GLOBAL slave_net_timeout = 60;
SET GLOBAL slave_parallel_workers = 8;
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
-- 查看并行复制状态
SHOW VARIABLES LIKE 'slave_parallel%';
1
2
3
4
5
6
7
2
3
4
5
6
7
# 9.2 内存和IO优化
-- 优化IO性能
SET GLOBAL innodb_flush_log_at_trx_commit = 2;
SET GLOBAL sync_binlog = 100;
SET GLOBAL innodb_io_capacity = 2000;
-- 优化内存使用
SET GLOBAL tmp_table_size = 256*1024*1024;
SET GLOBAL max_heap_table_size = 256*1024*1024;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 10. 总结
GTID技术的引入极大简化了MySQL主备切换的复杂性,提供了更可靠的事务一致性保障。通过合理使用GTID,可以:
- 简化切换流程:无需手动查找和定位位点
- 提高切换效率:自动处理事务重复和缺失
- 增强可靠性:提供更强的数据一致性保障
- 降低维护成本:减少人为操作错误
在实际应用中,应该:
- 在生产环境启用GTID
- 建立完善的监控体系
- 制定详细的切换预案
- 定期演练切换流程
- 做好数据备份和恢复准备
通过这些措施,可以确保在主备切换过程中最小化业务影响,保障系统的高可用性和数据安全性。
上次更新: 3/4/2026