MySQL高可用与集群之：`GTID`（`Global Transaction ID`）：其在主从切换和故障恢复中的作用。

admin
Thu, 28 Aug 2025 08:42:22 +0000
Mysql, global, gtid, mysql

MySQL高可用与集群之：GTID在主从切换和故障恢复中的作用 大家好，今天我们来深入探讨MySQL高可用与集群中一个至关重要的概念：GTID（Global Transaction ID），以及它在主从切换和故障恢复中的作用。GTID为MySQL复制提供了一种更加可靠和易于管理的方式，极大地简化了高可用集群的维护工作。 1. 什么是GTID？ 传统基于binlog文件和position的复制方式，在主从切换和故障恢复时，需要手动查找合适的binlog文件和position点，容易出错且耗时。GTID的出现，就是为了解决这个问题。 GTID（Global Transaction ID）是一个全局唯一的事务ID。它由两部分组成： source_id: 产生该事务的服务器的UUID。每个MySQL服务器都有一个唯一的UUID。 transaction_id: 在该服务器上产生的事务序列号。 因此，GTID的格式为 source_id:transaction_id， 例如：3E11FA47-71CA-11E1-9E33-C80AA9429562:12345。 2. GTID的工作原理 当开启G …

继续阅读“MySQL高可用与集群之：`GTID`（`Global Transaction ID`）：其在主从切换和故障恢复中的作用。”

The post MySQL高可用与集群之：`GTID`（`Global Transaction ID`）：其在主从切换和故障恢复中的作用。 first appeared on 智猿学院-前后端，数据库，人工智能，云计算等领域前沿技术讲座.

MySQL高可用与集群之：GTID在主从切换和故障恢复中的作用

大家好，今天我们来深入探讨MySQL高可用与集群中一个至关重要的概念：GTID（Global Transaction ID），以及它在主从切换和故障恢复中的作用。GTID为MySQL复制提供了一种更加可靠和易于管理的方式，极大地简化了高可用集群的维护工作。

1. 什么是GTID？

传统基于binlog文件和position的复制方式，在主从切换和故障恢复时，需要手动查找合适的binlog文件和position点，容易出错且耗时。GTID的出现，就是为了解决这个问题。

GTID（Global Transaction ID）是一个全局唯一的事务ID。它由两部分组成：

source_id: 产生该事务的服务器的UUID。每个MySQL服务器都有一个唯一的UUID。

transaction_id: 在该服务器上产生的事务序列号。

因此，GTID的格式为 source_id:transaction_id， 例如：3E11FA47-71CA-11E1-9E33-C80AA9429562:12345。

2. GTID的工作原理

当开启GTID后，每个在主服务器上执行的事务都会被分配一个唯一的GTID。这个GTID会被记录在binlog中，并随着binlog传输到从服务器。从服务器在执行该事务时，也会记录下该GTID。

这样，每个事务都被唯一标识，无论它在哪个服务器上执行。从服务器可以根据GTID来判断是否已经执行过某个事务，从而避免重复执行。

3. GTID的优势

相比于传统的基于binlog文件和position的复制方式，GTID具有以下优势：

简化主从切换和故障恢复： 不需要手动查找binlog文件和position，只需要指定新的主服务器即可。

提高复制的可靠性： 避免重复执行事务，保证数据的一致性。

简化复制拓扑管理： 更容易构建复杂的复制拓扑，例如多主复制和环形复制。

自动跳过已执行的事务： 从服务器可以自动跳过已经执行过的事务，例如在主服务器上执行了某些事务后，从服务器宕机，恢复后可以自动从上次中断的位置继续复制。

4. 如何启用GTID

要启用GTID，需要在MySQL的配置文件(通常是my.cnf或my.ini)中添加以下配置：

[mysqld]
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON
server_id = 1  # 主服务器的server_id，确保唯一
binlog_format = ROW # 推荐使用ROW格式
relay_log_recovery = ON # 建议开启，保证relay log的一致性

解释一下这些参数：

gtid_mode = ON: 启用GTID。

enforce_gtid_consistency = ON: 强制GTID一致性，防止在没有GTID的情况下执行事务。这是非常重要的设置，可以保证数据的一致性。

log_slave_updates = ON: 允许从服务器将接收到的更新写入自己的binlog。这对于级联复制非常重要。

server_id = 1: 设置服务器ID，每个服务器的ID必须唯一。

binlog_format = ROW: 推荐使用ROW格式的binlog，可以更准确地记录数据的变化。

relay_log_recovery = ON: 启用中继日志恢复，防止从服务器崩溃后数据丢失。

重要提示：

在启用GTID之前，建议备份数据。

在启用GTID后，需要重启MySQL服务器。

从MySQL 5.7版本开始， gtid_mode=ON 隐含地设置了 log_bin=ON，也就是说，启用GTID必须启用二进制日志。在MySQL 8.0版本中，log_bin默认开启。

5. 主从切换中的GTID

假设我们有一个主服务器（A）和一个从服务器（B），我们要将从服务器（B）切换为主服务器。

以下是使用GTID进行主从切换的步骤：

1. 停止主服务器（A）的写入操作： 避免在切换过程中产生新的事务。

FLUSH TABLES WITH READ LOCK;

2. 确定从服务器（B）已经同步了所有来自主服务器（A）的事务： 可以通过查看 SHOW SLAVE STATUS 的输出来确认。 关键指标是 Seconds_Behind_Master 是否为0。

SHOW SLAVE STATUSG

注意 Executed_Gtid_Set 字段，这个字段表示从服务器已经执行过的GTID集合。我们需要确保这个集合包含了主服务器上所有已经提交的GTID。
也可以通过查询：

SELECT GTID_SUBSET( ( SELECT @@GLOBAL.GTID_EXECUTED ), ( SELECT @@GLOBAL.GTID_EXECUTED FROM performance_schema.replication_connection_status WHERE CHANNEL_NAME='channel_0' ) );

如果返回 1, 则表示从库已经同步了主库的所有事务.

3. 停止从服务器（B）的复制线程：

STOP SLAVE;

4. 将从服务器（B）提升为主服务器： 不需要进行任何特殊的操作，因为GTID已经记录了所有的事务信息。

5. 配置原来的主服务器（A）成为新的从服务器：

修改原来的主服务器（A）的配置文件，设置 server_id 为一个新的值，例如 2。

启动原来的主服务器（A）。

在原来的主服务器（A）上执行以下命令，将其配置为新的从服务器：

STOP SLAVE;
RESET SLAVE ALL; -- 非常重要，清空之前的复制信息
CHANGE MASTER TO
    MASTER_HOST='new_master_ip',
    MASTER_USER='replication_user',
    MASTER_PASSWORD='replication_password',
    MASTER_AUTO_POSITION=1; -- 启用GTID自动定位
START SLAVE;

MASTER_AUTO_POSITION=1：这是GTID的关键，它告诉从服务器使用GTID自动定位复制的起始位置，不需要手动指定binlog文件和position。

代码示例：主从切换脚本（简化版）

#!/bin/bash

# 主服务器信息
OLD_MASTER_HOST="192.168.1.100"
OLD_MASTER_USER="root"
OLD_MASTER_PASSWORD="password"

# 新的主服务器信息 (原从服务器)
NEW_MASTER_HOST="192.168.1.101"
NEW_MASTER_USER="root"
NEW_MASTER_PASSWORD="password"

# 新的从服务器信息 (原主服务器)
NEW_SLAVE_HOST="192.168.1.100"
NEW_SLAVE_USER="root"
NEW_SLAVE_PASSWORD="password"
NEW_SLAVE_SERVER_ID="2"

# 1. 停止旧主服务器的写入
echo "Stopping writes on old master..."
mysql -h $OLD_MASTER_HOST -u $OLD_MASTER_USER -p$OLD_MASTER_PASSWORD -e "FLUSH TABLES WITH READ LOCK;"

# 2. 检查新主服务器的同步状态 (简化版，需要手动确认)
echo "Checking replication status on new master (was slave)..."
mysql -h $NEW_MASTER_HOST -u $NEW_MASTER_USER -p$NEW_MASTER_PASSWORD -e "SHOW SLAVE STATUSG"

# 3. 停止新主服务器的复制
echo "Stopping slave on new master..."
mysql -h $NEW_MASTER_HOST -u $NEW_MASTER_USER -p$NEW_MASTER_PASSWORD -e "STOP SLAVE;"

# 4.  配置旧主服务器成为新的从服务器
echo "Configuring old master as new slave..."
mysql -h $NEW_SLAVE_HOST -u $NEW_SLAVE_USER -p$NEW_SLAVE_PASSWORD -e "
    STOP SLAVE;
    RESET SLAVE ALL;
    CHANGE MASTER TO
        MASTER_HOST='$NEW_MASTER_HOST',
        MASTER_USER='$NEW_MASTER_USER',
        MASTER_PASSWORD='$NEW_MASTER_PASSWORD',
        MASTER_AUTO_POSITION=1;
    START SLAVE;
"

# 5. 解锁旧的主服务器
echo "Unlocking old master..."
mysql -h $OLD_MASTER_HOST -u $OLD_MASTER_USER -p$OLD_MASTER_PASSWORD -e "UNLOCK TABLES;"

echo "主从切换完成!"

注意： 这个脚本只是一个简化版的示例，实际环境中需要进行更完善的错误处理和状态检查。 例如，需要检查 SHOW SLAVE STATUS 的输出，确认复制是否正常启动。 还应该添加重试机制，以应对网络故障等问题。

6. 故障恢复中的GTID

假设主服务器（A）发生故障，我们需要将从服务器（B）提升为主服务器。

以下是使用GTID进行故障恢复的步骤：

1. 确认主服务器（A）已经彻底宕机： 避免脑裂问题。

2. 将从服务器（B）提升为主服务器： 如前所述，不需要进行任何特殊的操作。

3. 修复原来的主服务器（A）：

修改原来的主服务器（A）的配置文件，设置 server_id 为一个新的值。

启动原来的主服务器（A）。

在原来的主服务器（A）上执行以下命令，将其配置为新的从服务器：

STOP SLAVE;
RESET SLAVE ALL;
CHANGE MASTER TO
    MASTER_HOST='new_master_ip',
    MASTER_USER='replication_user',
    MASTER_PASSWORD='replication_password',
    MASTER_AUTO_POSITION=1;
START SLAVE;

7. GTID的注意事项

GTID只能用于InnoDB存储引擎： 如果使用MyISAM等其他存储引擎，需要进行转换。

确保所有服务器的GTID模式一致： 所有服务器必须都启用GTID，并且 enforce_gtid_consistency 必须设置为 ON。

谨慎使用 RESET MASTER 命令： 在GTID模式下，RESET MASTER 会清除所有的GTID信息，可能导致数据不一致。 除非非常清楚其影响，否则不要使用该命令。 可以使用 RESET MASTER TO <N> 命令，将 auto_increment 的偏移量重置为指定值。

监控GTID状态： 定期检查GTID的状态，例如 gtid_executed 和 gtid_purged，确保复制正常运行。

处理遗留的非GTID事务： 如果之前未使用GTID，需要将所有事务转换为GTID事务。可以使用 SET GTID_NEXT = 'AUTOMATIC' 来让MySQL自动分配GTID。

8. GTID相关状态变量

以下是一些与GTID相关的重要的状态变量：

变量名 | 描述
gtid_mode | GTID模式的状态：OFF、ON、OFF_PERMISSIVE、ON_PERMISSIVE。
gtid_executed | 服务器已经执行的GTID集合。
gtid_purged | 服务器已经清除的GTID集合。
enforce_gtid_consistency | 是否强制GTID一致性。
slave_preserve_commit_order | 控制从库是否按照主库的提交顺序来执行事务，推荐开启，尤其是在多线程复制的情况下。

9. 总结：GTID让主从切换和故障恢复更简单

GTID通过全局唯一事务ID，极大地简化了MySQL主从切换和故障恢复的流程。它避免了手动查找binlog文件和position的繁琐操作，提高了复制的可靠性和易用性。 启用GTID后，主从切换和故障恢复变得更加自动化和可预测，降低了运维成本，提高了数据库系统的可用性。 务必按照最佳实践配置GTID，并定期监控其状态，以确保数据库集群的稳定运行。