Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL8-SOP

  • MySQL实战45讲学习笔记

    • MySQL45讲学习笔记
    • MySQL基础架构
    • MySQL日志系统 (Redo Log 与 Binlog)
    • MySQL字符串字段索引优化
    • MySQL索引原理与优化
    • MySQL锁机制详解
    • MySQL事务与MVCC机制
    • MySQL普通索引与唯一索引的选择
    • MySQL优化器如何选择索引
    • MySQL抖动刷脏页
    • 表空间管理与回收
    • count函数详解
    • 日志索引
    • orderby工作原理
    • 随机排序实现
    • SQL性能差异函数与转换
    • 慢查询分析锁与版本
    • 幻读与间隙锁
    • 加锁规则分析
    • 应急性能优化方法
    • 数据持久化保证
    • 主备一致性原理
    • 高可用架构与切换
    • 备库延迟分析与优化
    • 主备切换GTID
      • 1. GTID基础概念
        • 1.1 GTID的定义
        • 1.2 GTID的工作原理
        • 1.3 GTID的优势
      • 2. GTID在主备切换中的作用
        • 2.1 GTID切换流程
        • 2.2 GTID切换的优势
      • 3. GTID切换的具体步骤
        • 3.1 故障切换准备
        • 3.2 从库提升为主库
        • 3.3 重新配置其他从库
      • 4. GTID切换的高级技巧
        • 4.1 GTID集合操作
        • 4.2 GTID一致性检查
        • 4.3 GTID故障恢复
      • 5. GTID切换常见问题及解决方案
        • 5.1 GTID冲突问题
        • 5.2 GTID不一致问题
        • 5.3 GTID切换后数据丢失
      • 6. GTID切换的最佳实践
        • 6.1 切换前准备工作
        • 6.2 安全切换流程
        • 6.3 切换后验证
      • 7. GTID与不同架构的适配
        • 7.1 一主一备架构
        • 7.2 一主多从架构
        • 7.3 双主架构
      • 8. GTID监控与告警
        • 8.1 GTID状态监控
        • 8.2 GTID异常告警
      • 9. GTID切换的性能考虑
        • 9.1 切换时间优化
        • 9.2 内存和IO优化
      • 10. 总结
    • 读写分离实践与问题
    • 数据库健康检查
    • 锁与死锁
    • 数据误删恢复
    • Kill命令详解
    • 查询与内存使用分析
    • Join原理与选择
    • 临时表原理与应用
    • 内部临时表详解
    • Memory引擎详解
    • 自增ID详解
    • Insert加锁分析
    • 表复制方法比较
    • Grant与权限管理
    • 分区表详解
    • SQL语句中的Join问题
    • 自增ID用尽问题
  • 专题系列
  • MySQL实战45讲学习笔记
Carry の Blog
2024-07-27
目录

主备切换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

其中:

  • 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

# 1.3 GTID的优势

  1. 简化主备切换:无需手动查找位点
  2. 自动处理重复:避免重复应用事务
  3. 增强可靠性:提供更强的数据一致性保障
  4. 简化故障恢复:快速定位缺失的事务

# 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.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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 7. GTID与不同架构的适配

# 7.1 一主一备架构

-- 一主一备切换示例
-- 主库故障时
STOP SLAVE ON slave;
SET GLOBAL read_only = OFF;  -- 提升从库为主库
-- 重新配置其他从库指向新主库
1
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

# 7.3 双主架构

-- 双主切换示例
-- 需要更复杂的协调机制
-- 1. 确保两个主库数据一致性
-- 2. 选择一个主库作为新的主库
-- 3. 重新配置另一个主库
1
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

# 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

# 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

# 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

# 10. 总结

GTID技术的引入极大简化了MySQL主备切换的复杂性,提供了更可靠的事务一致性保障。通过合理使用GTID,可以:

  1. 简化切换流程:无需手动查找和定位位点
  2. 提高切换效率:自动处理事务重复和缺失
  3. 增强可靠性:提供更强的数据一致性保障
  4. 降低维护成本:减少人为操作错误

在实际应用中,应该:

  • 在生产环境启用GTID
  • 建立完善的监控体系
  • 制定详细的切换预案
  • 定期演练切换流程
  • 做好数据备份和恢复准备

通过这些措施,可以确保在主备切换过程中最小化业务影响,保障系统的高可用性和数据安全性。

#MySQL#GTID#主备切换#高可用#学习笔记
上次更新: 3/4/2026

← 备库延迟分析与优化 读写分离实践与问题→

最近更新
01
表空间管理与回收
03-04
02
MySQL抖动刷脏页
03-04
03
count函数详解
03-04
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式