背景介绍:为什么选择 GTID 主从复制?
在 MySQL 高可用架构中,主从复制是实现数据备份、读写分离、故障转移的核心基础。传统主从复制依赖 “二进制日志文件 + 偏移量” 定位同步起点,存在明显痛点:
- 主从切换时需手动记录新主库的 binlog 文件名和位置,操作复杂且易出错;
- 复制中断后,需对比主从日志找到同步断点,排查效率低;
- 级联复制(主→从→从)场景下,拓扑管理和故障转移难度大。
GTID(Global Transaction Identifier,全局事务标识符) 作为 MySQL 5.6 + 引入的增强特性,为每个事务分配全局唯一 ID,彻底解决了传统复制的痛点:
- 自动定位同步起点,无需手动指定 binlog 文件和偏移量;
- 事务级别的一致性追踪,便于排查复制异常;
- 简化主从切换和拓扑管理,支持更灵活的复制架构(如多主复制、级联复制)。
本文适用于 CentOS/Ubuntu 等 Linux 系统,详细讲解 MySQL 5.7/8.0 环境下 GTID 主从复制的完整搭建流程,从前提准备到最终验证,每一步均附具体命令和实操注意事项,适合运维工程师和后端开发人员部署生产或测试环境。
核心关键词解释
- GTID(全局事务标识符):全局唯一的事务标识,格式为
UUID:事务序列号(如a1b2c3d4-1234-5678-90ab-cdef01234567:5),主库执行事务时生成,随 binlog 同步到从库,作为事务执行状态的唯一标识; - server-id:MySQL 服务器的唯一标识(主从库必须不同),用于在复制拓扑中区分节点,避免冲突;
- 二进制日志(binlog):记录数据库所有数据变更操作的日志文件,是主从复制的 “数据源”,GTID 模式下需开启并设置为 ROW 格式;
- enforce_gtid_consistency:强制 GTID 事务一致性,禁止执行不支持 GTID 的 SQL 语句(如
CREATE TABLE ... SELECT),确保所有事务均可被 GTID 追踪; - MASTER_AUTO_POSITION=1:GTID 模式下的核心参数,启用后从库自动通过 GTID 集合匹配同步起点,无需手动指定 binlog 文件和偏移量;
- Slave_IO_Running/Slave_SQL_Running:从库复制状态的核心指标,均为
Yes表示复制正常(IO 线程负责接收主库 binlog,SQL 线程负责执行中继日志)。
一、前提条件:这些准备工作必须做
在开始配置前,需确保满足以下基础条件,否则可能导致复制失败或不稳定:
- 服务器数量:至少 2 台 Linux 服务器(1 主库 Master + 1 从库 Slave),建议硬件配置相同(避免因硬件差异导致同步延迟);
- MySQL 版本:≥ 5.6(推荐 5.7 或 8.0,本文命令通用;5.6 需注意部分参数差异);
- 网络互通:主从服务器之间能 ping 通,且 MySQL 默认端口(3306)可通过防火墙(firewalld/ufw)或安全组(云服务器);
- 时间同步:主从服务器时间需一致(建议配置 NTP 服务,避免因时间差导致事务时序混乱),执行
timedatectl set-ntp on可快速开启 NTP; - 权限准备:拥有服务器
root权限(用于修改配置文件、重启服务)和 MySQLroot权限(用于创建复制用户、配置复制)。
二、第一步:配置主库(Master)
主库是复制的 “数据源”,需开启 GTID 模式、二进制日志,并创建用于复制的专用用户。
1. 编辑 MySQL 配置文件
MySQL 配置文件路径因系统和版本略有差异,常见路径:
- CentOS/RHEL:
/etc/my.cnf - Ubuntu/Debian:
/etc/mysql/mysql.conf.d/mysqld.cnf
使用vim编辑配置文件,在[mysqld]模块下添加以下参数:
ini
[mysqld]
# 1. 服务器唯一标识(必须!主库建议设为1,从库需不同)
server-id = 1
# 2. 启用GTID模式(核心参数,开启后事务将生成GTID)
gtid_mode = ON
# 3. 强制GTID一致性(禁止不支持GTID的SQL语句,避免复制异常)
enforce_gtid_consistency = ON
# 4. 启用二进制日志(复制的基础,日志文件前缀为mysql-bin)
log-bin = mysql-bin
# 5. 二进制日志格式(推荐ROW模式,仅记录数据变更,避免SQL_mode兼容问题)
binlog_format = ROW
⚠️ 注意:enforce_gtid_consistency = ON有严格的 SQL 限制,需避免使用以下语句(否则会报错):
CREATE TABLE ... SELECT- 事务中执行
CREATE TEMPORARY TABLE - 非事务表的 DDL 语句与事务语句混用
2. 重启 MySQL 服务使配置生效
配置修改后需重启 MySQL 服务,命令因系统而异:
bash
# CentOS/RHEL 系统
sudo systemctl restart mysqld
# Ubuntu/Debian 系统
sudo systemctl restart mysql
可通过sudo systemctl status mysqld(或mysql)验证服务是否正常启动,确保状态为active (running)。若启动失败,查看错误日志排查(CentOS:/var/log/mysqld.log;Ubuntu:/var/log/mysql/error.log)。
3. 创建复制专用用户
为了安全性,不建议使用root用户进行复制,需创建一个仅拥有 “复制权限” 的专用用户(如repl):
bash
# 登录主库MySQL(输入root密码)
mysql -u root -p
执行以下 SQL 创建用户并授权:
sql
-- 创建用户:repl(用户名),%(允许所有IP访问,生产环境建议替换为从库IP,如'192.168.1.102')
CREATE USER 'repl'@'%' IDENTIFIED BY 'StrongPassword123!';
-- 授予复制权限(仅允许REPLICATION SLAVE权限,最小权限原则,提升安全性)
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- 刷新权限使配置生效
FLUSH PRIVILEGES;
-- 验证权限(可选,确认用户权限配置正确)
SHOW GRANTS FOR 'repl'@'%';
三、第二步:配置从库(Slave)
从库是复制的 “接收端”,需与主库保持 GTID 模式一致,同时建议开启二进制日志(便于后续级联复制或主从切换)。
1. 编辑从库 MySQL 配置文件
找到从库的 MySQL 配置文件,在[mysqld]模块下添加以下参数(注意server-id需与主库不同):
ini
[mysqld]
# 1. 服务器唯一标识(必须!与主库不同,建议设为2)
server-id = 2
# 2. 启用GTID模式(与主库一致,确保复制兼容性)
gtid_mode = ON
# 3. 强制GTID一致性(与主库一致)
enforce_gtid_consistency = ON
# 4. 启用二进制日志(从库开启binlog,便于后续作为“主库”给其他从库复制,支持级联复制)
log-bin = mysql-bin
# 5. 可选:设置从库为只读(防止普通用户误写入,root用户不受限制)
read_only = ON
2. 重启从库 MySQL 服务
与主库操作一致,重启服务使配置生效:
bash
# CentOS/RHEL 系统
sudo systemctl restart mysqld
# Ubuntu/Debian 系统
sudo systemctl restart mysql
四、第三步:初始化从库数据(可选但推荐)
如果主库已有业务数据,必须先将主库数据全量同步到从库,否则主从数据不一致会导致复制启动失败。若主库是新库(无数据),可跳过此步骤。
方法一:mysqldump(适用于数据量 ≤ 10GB 的场景)
mysqldump 是 MySQL 自带的逻辑备份工具,操作简单,适合中小数据量场景:
bash
# 主库执行:全量备份所有数据库(包含GTID信息)
mysqldump --all-databases \
--single-transaction \ # 无锁备份(仅适用于InnoDB表),不影响主库业务读写
--triggers \ # 备份触发器(确保从库触发器与主库一致)
--routines \ # 备份存储过程和函数
--set-gtid-purged=ON \ # 记录当前主库的GTID位置(核心!避免从库重复执行历史事务)
-u root -p > full_backup.sql
# 从库执行:将主库的备份文件复制到从库当前目录(替换主库IP和备份文件路径)
scp root@主库IP:/path/to/full_backup.sql ./
# 从库执行:导入备份数据(导入前确保无其他会话操作从库,避免数据冲突)
mysql -u root -p < full_backup.sql
方法二:XtraBackup(适用于数据量 ≥ 10GB 的场景)
若主库数据量大(如几十 GB 或 TB 级),mysqldump 效率低,推荐使用 Percona XtraBackup(物理备份工具,备份 / 恢复速度快,支持增量备份)。
此处简化步骤(详细步骤可参考 Percona 官方文档):
- 主库安装 XtraBackup:
bash
# CentOS系统 sudo yum install percona-xtrabackup-80 # Ubuntu系统 sudo apt install percona-xtrabackup-80 - 主库执行物理备份:
bash
xtrabackup --backup --target-dir=/backup --user=root --password=你的MySQL密码 - 将备份目录复制到从库:
bash
scp -r /backup root@从库IP:/backup - 从库恢复备份:
bash
# 准备备份(一致性校验) xtrabackup --prepare --target-dir=/backup # 复制备份到MySQL数据目录(需先停止从库MySQL) sudo systemctl stop mysqld xtrabackup --copy-back --target-dir=/backup - 调整数据目录权限(确保 MySQL 用户可访问):
bash
chown -R mysql:mysql /var/lib/mysql # 根据你的MySQL数据目录路径调整 - 启动从库 MySQL:
bash
sudo systemctl start mysqld
五、第四步:配置从库连接主库并启动复制
这是 GTID 复制的核心步骤 —— 通过CHANGE MASTER TO命令让从库关联主库,GTID 模式下无需指定 binlog 文件和偏移量,由系统自动定位同步起点。
1. 从库执行复制配置命令
登录从库 MySQL(mysql -u root -p),执行以下 SQL:
sql
CHANGE MASTER TO
MASTER_HOST='主库IP', -- 替换为你的主库服务器IP(如192.168.1.101)
MASTER_PORT=3306, -- MySQL端口(默认3306,若主库修改过端口需对应调整)
MASTER_USER='repl', -- 主库创建的复制用户(之前配置的repl)
MASTER_PASSWORD='StrongPassword123!', -- 复制用户的密码(与主库一致)
MASTER_AUTO_POSITION = 1; -- 关键!启用GTID自动定位(无需手动指定file:pos)
⚠️ MySQL 8.0 特殊注意:若主库是 MySQL 8.0,默认认证插件为caching_sha2_password,而 MySQL 5.7 及以下版本的从库不支持此插件,会导致从库连接主库失败。解决方案:主库创建复制用户时指定旧版认证插件:
sql
CREATE USER 'repl'@'从库IP' IDENTIFIED WITH mysql_native_password BY 'StrongPassword123!';
2. 启动从库复制进程
执行以下命令启动从库的 IO 线程(接收主库 binlog)和 SQL 线程(执行中继日志):
sql
START SLAVE;
⚠️ 若之前启动过复制(如配置错误后重新配置),需先执行以下命令清理旧配置:
sql
STOP SLAVE; # 停止现有复制进程
RESET SLAVE ALL; # 重置复制配置(清空主库连接信息和同步状态)
3. 检查复制状态(关键!)
执行SHOW SLAVE STATUS\G查看复制状态(\G用于纵向格式化输出,便于查看关键参数),需重点关注以下 4 个核心检查项:
sql
SHOW SLAVE STATUS\G
核心检查项(必须全部满足,否则复制异常):
Slave_IO_Running: Yes→ IO 线程正常(从库能成功连接主库并接收 binlog);Slave_SQL_Running: Yes→ SQL 线程正常(从库能成功执行中继日志中的事务);Seconds_Behind_Master: 0→ 从库无同步延迟(若大于 0,需排查延迟原因,如从库性能不足、网络延迟等);Auto_Position: 1→ GTID 自动定位已启用(确认 GTID 模式配置生效)。
常见异常排查:
- 若
Slave_IO_Running为Connecting:- 检查主库 IP、端口是否正确;
- 确认复制用户密码正确;
- 主库防火墙是否开放 3306 端口;
- MySQL 8.0 认证插件不兼容(参考步骤 5.1 的解决方案)。
六、第五步:验证 GTID 复制是否正常
配置完成后,需通过实际数据操作验证复制是否生效 —— 主库写入数据,从库能同步则说明搭建成功。
1. 主库创建测试数据
登录主库 MySQL,执行以下 SQL 创建测试库、表并插入数据:
sql
-- 创建测试库
CREATE DATABASE test_gtid;
-- 使用测试库
USE test_gtid;
-- 创建测试表(InnoDB引擎,支持事务)
CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20));
-- 插入测试数据(触发2个GTID事务)
INSERT INTO t1 VALUES (1, 'GTID Test'), (2, 'MySQL Replication');
2. 从库查询数据是否同步
登录从库 MySQL,执行以下 SQL 查看数据是否同步:
sql
-- 查看测试库是否存在(应显示test_gtid)
SHOW DATABASES LIKE 'test_gtid';
-- 使用测试库并查询数据
USE test_gtid;
SELECT * FROM t1;
预期输出(说明复制成功):
plaintext
+----+-------------------+
| id | name |
+----+-------------------+
| 1 | GTID Test |
| 2 | MySQL Replication |
+----+-------------------+
七、补充建议:让 GTID 复制更稳定
搭建完成后,需注意以下运维细节,避免复制中断或数据丢失:
1. 复制状态监控
- 简单监控:编写 Shell 脚本定期执行
SHOW SLAVE STATUS\G,若Slave_IO_Running或Slave_SQL_Running为No,触发邮件 / 短信告警; - 专业监控:使用 Prometheus + mysqld_exporter + Grafana,可视化展示复制延迟、binlog 大小、线程状态等指标,实时监控复制健康度。
2. 数据备份策略
- 即使有从库,主库仍需定期备份(如每日全量备份 + 增量备份),防止主从同时故障导致数据丢失;
- 备份时建议包含 GTID 信息(如 mysqldump 的
--set-gtid-purged=ON),便于后续恢复时快速定位同步起点。
3. 从库只读限制
- 从库建议开启
read_only = ON(仅限制普通用户),防止误写入导致主从数据不一致; - 若需在从库执行维护操作(如数据校验),需先执行
SET GLOBAL read_only = OFF;,操作完成后立即改回ON; - 禁止直接修改从库业务数据,否则会触发
Slave_SQL_Running: No,需手动修复数据一致性后重启复制。
4. 版本升级注意事项
- 若从 MySQL 5.7 升级到 8.0,需先确保主从复制正常,再按 “先升级从库,最后升级主库” 的顺序操作,避免版本差异导致复制失败;
- 升级后需重新验证 GTID 配置和复制状态,确保
gtid_mode、enforce_gtid_consistency等参数正常生效。
总结
GTID 主从复制是 MySQL 高可用架构的基础,相比传统复制,其核心优势在于:
- 自动定位同步起点,简化主从切换和故障恢复;
- 事务级别的全局唯一标识,便于追踪和排查复制问题;
- 支持更灵活的复制拓扑(如级联复制、多主复制)。
本文从前提准备、主从库配置、数据初始化、复制启动到最终验证,覆盖了 MySQL 5.7/8.0 环境下的完整搭建流程。实操中若遇到问题,可重点检查配置文件参数(如server-id、GTID 相关参数)和复制状态中的Slave_IO_Running、Slave_SQL_Running指标,快速定位异常原因。
1217

被折叠的 条评论
为什么被折叠?



