Skip to content

MySQL GTID 基于逻辑复制

什么是 GTID

GTID(Global Transaction Identifier,全局事务标识符)是MySQL 5.6引入的一项重要特性,用于唯一标识数据库中的每个事务。GTID由两部分组成:

GTID = source_id:transaction_id
  • source_id:通常是执行事务的MySQL实例的server_uuid
  • transaction_id:事务在源实例上的唯一序列号

GTID 逻辑复制的优势

1. 简化复制管理

  • 不再需要手动管理二进制日志文件和位置
  • 可以轻松地添加新的从库
  • 简化故障转移和主从切换

2. 提高复制可靠性

  • 每个事务都有唯一的标识符
  • 确保事务只被执行一次
  • 避免重复执行事务导致的数据不一致

3. 支持多源复制

  • 可以从多个主库复制数据到一个从库
  • 每个主库的事务都有唯一的GTID

4. 便于监控和故障诊断

  • 可以通过GTID快速定位事务
  • 便于监控复制进度
  • 便于诊断复制错误

配置 GTID 逻辑复制

1. 主库配置

bash
# 在主库的my.cnf中添加以下配置
[mysqld]
# 启用GTID
gtid_mode = ON
enforce_gtid_consistency = ON

# 启用二进制日志
log_bin = mysql-bin
server_id = 1

# 配置二进制日志格式
binlog_format = ROW

# 启用从库更新日志(可选,用于级联复制)
log_slave_updates = ON

2. 从库配置

bash
# 在从库的my.cnf中添加以下配置
[mysqld]
# 启用GTID
gtid_mode = ON
enforce_gtid_consistency = ON

server_id = 2
relay_log = relay-bin
read_only = ON

# 启用从库更新日志(可选,用于级联复制)
log_slave_updates = ON

3. 重启 MySQL 服务

bash
# 重启主库和从库的MySQL服务
systemctl restart mysql

4. 在主库上创建复制用户

sql
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

5. 配置从库复制

sql
-- 停止现有的复制(如果存在)
STOP SLAVE;

-- 重置复制配置
RESET SLAVE ALL;

-- 配置基于GTID的复制
CHANGE MASTER TO
    MASTER_HOST = 'master_host',
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'password',
    MASTER_AUTO_POSITION = 1;

-- 启动复制
START SLAVE;

-- 检查复制状态
SHOW SLAVE STATUS\G

监控 GTID 复制

1. 检查复制状态

sql
SHOW SLAVE STATUS\G

关键字段说明:

  • Slave_IO_Running:IO线程状态
  • Slave_SQL_Running:SQL线程状态
  • Seconds_Behind_Master:复制延迟
  • Retrieved_Gtid_Set:已接收的GTID集合
  • Executed_Gtid_Set:已执行的GTID集合

2. 检查主库GTID状态

sql
-- 查看主库已执行的GTID集合
SHOW MASTER STATUS;

-- 查看主库当前的GTID执行情况
SHOW GLOBAL VARIABLES LIKE 'gtid_executed';

3. 监控GTID复制进度

sql
-- 计算复制延迟的GTID数量
SELECT 
    @@global.gtid_executed AS executed_gtid,
    @@global.gtid_purged AS purged_gtid,
    (SELECT Received_Gtid_Set FROM performance_schema.replication_connection_status) AS received_gtid

GTID 复制管理

1. 跳过事务

在某些情况下,可能需要跳过特定的GTID事务:

sql
-- 跳过单个GTID事务
STOP SLAVE;
SET GTID_NEXT = 'source_id:transaction_id';
BEGIN;
COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START SLAVE;

2. 重置GTID

sql
-- 重置主库GTID(谨慎使用)
RESET MASTER;

-- 重置从库GTID(谨慎使用)
RESET SLAVE ALL;

3. 克隆GTID复制

sql
-- 从现有从库克隆新的从库
-- 1. 在现有从库上执行
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
-- 记录输出的File和Position
-- 2. 创建数据备份
-- 3. 在新从库上恢复备份
-- 4. 在新从库上配置复制
CHANGE MASTER TO
    MASTER_HOST = 'master_host',
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'password',
    MASTER_AUTO_POSITION = 1;
START SLAVE;

GTID 复制最佳实践

1. 配置建议

  • 始终使用ROW格式的二进制日志
  • 启用log_slave_updates以支持级联复制
  • 确保gtid_mode和enforce_gtid_consistency在所有实例上都设置为ON
  • 定期备份GTID相关的元数据

2. 迁移到GTID复制

从传统复制迁移到GTID复制

sql
-- 1. 在主库和从库上启用GTID(保持传统复制运行)
SET GLOBAL gtid_mode = OFF_PERMISSIVE;
SET GLOBAL gtid_mode = ON_PERMISSIVE;

-- 2. 等待所有传统事务完成
SELECT @@global.gtid_owned;

-- 3. 切换到完全GTID模式
SET GLOBAL enforce_gtid_consistency = ON;
SET GLOBAL gtid_mode = ON;

-- 4. 更新从库复制配置
STOP SLAVE;
CHANGE MASTER TO
    MASTER_AUTO_POSITION = 1;
START SLAVE;

3. 故障处理

主库故障处理

sql
-- 1. 选择一个从库作为新的主库
-- 2. 在新主库上执行
STOP SLAVE;
RESET MASTER;

-- 3. 在其他从库上重新配置复制
STOP SLAVE;
CHANGE MASTER TO
    MASTER_HOST = 'new_master_host',
    MASTER_AUTO_POSITION = 1;
START SLAVE;

GTID复制错误处理

sql
-- 查看复制错误
SHOW SLAVE STATUS\G

-- 根据错误类型采取相应的处理措施
-- 1. 如果是主键冲突等可跳过的错误,可以使用GTID跳过
-- 2. 如果是数据不一致,可能需要重新初始化从库

GTID 复制限制

1. 事务限制

  • 不支持CREATE TABLE ... SELECT语句
  • 不支持CREATE TEMPORARY TABLE和DROP TEMPORARY TABLE语句
  • 不支持在同一个事务中同时更新InnoDB和MyISAM表

2. 性能考虑

  • GTID会带来一定的性能开销
  • 在高并发场景下,GTID可能会影响主库的写入性能
  • 建议在启用GTID前进行充分的性能测试

3. 兼容性

  • GTID只支持MySQL 5.6及以上版本
  • 不同版本之间的GTID实现可能存在差异
  • 建议在生产环境中使用相同版本的MySQL

常见问题(FAQ)

Q1: 如何检查GTID是否已启用?

A1: 可以通过以下命令检查GTID状态:

sql
SHOW GLOBAL VARIABLES LIKE 'gtid_mode';
SHOW GLOBAL VARIABLES LIKE 'enforce_gtid_consistency';

Q2: GTID复制和传统复制有什么区别?

A2: 主要区别在于:

  • GTID复制使用全局事务标识符,不需要手动管理二进制日志文件和位置
  • GTID确保每个事务只被执行一次
  • GTID简化了复制管理和故障转移

Q3: 如何将传统复制转换为GTID复制?

A3: 可以通过逐步迁移的方式,先将GTID模式设置为OFF_PERMISSIVE,然后切换到ON_PERMISSIVE,最后切换到ON模式。

Q4: GTID复制是否支持多源复制?

A4: 是的,MySQL 5.7及以上版本支持基于GTID的多源复制。

Q5: 如何处理GTID复制中的冲突?

A5: 可以使用以下方法处理冲突:

  • 跳过冲突的GTID事务
  • 重新初始化从库
  • 修复数据不一致后重新启动复制

Q6: GTID复制的性能如何?

A6: GTID复制会带来一定的性能开销,主要体现在主库的写入性能上。在高并发场景下,建议进行充分的性能测试,评估GTID对系统的影响。

Q7: 如何备份和恢复GTID复制?

A7: 可以使用常规的备份方法(如mysqldump、xtrabackup)备份GTID复制的数据库。恢复时,需要确保GTID相关的元数据也被正确恢复。

Q8: GTID复制是否支持跨版本复制?

A8: 支持,但需要注意不同版本之间的GTID实现可能存在差异。建议在生产环境中使用相同版本的MySQL,或者进行充分的测试。