mysql主从复制GTID模式
mysql主从复制GTID模式
MySQL 主从复制使用 GTID 模式(Global Transaction Identifier) 是现代 MySQL 高可用架构中的推荐方式。相比传统的基于 binlog file + position
的复制,GTID 提供了 更强的一致性、自动定位同步点、简化故障切换 等优势。
✅ 一、什么是 GTID?
GTID(全局事务标识符)是一个全局唯一的事务 ID,格式为:
GTID = source_id:transaction_id
source_id
:主库的server_uuid
transaction_id
:该主库上第几个事务
每个事务在提交时都会生成一个唯一的 GTID。
✅ 二、GTID 复制的优势
传统复制(File/Pos) | GTID 复制 |
---|---|
手动指定 MASTER_LOG_FILE 和 MASTER_LOG_POS | 自动定位同步点 |
容易因 binlog 被清理导致 ERROR 1236 | 自动跳过已执行事务 |
故障切换复杂 | 支持自动 failover |
数据一致性难保证 | 强一致性(每个事务只执行一次) |
✅三、GTID 复制配置步骤
- 主库(Master):
192.168.1.10
- 从库(Slave):
192.168.1.11
- MySQL 版本: 8.0.29
步骤 1:主库和从库配置 my.cnf
主库配置(/etc/my.cnf
)
[mysqld]
# 基础配置
server-id = 1
log-bin = mysql-bin
binlog-format = ROW# 启用 GTID(关键)
gtid-mode = ON
enforce-gtid-consistency = ON# 可选:开启 binlog 压缩(MySQL 8.0+)
# binlog_transaction_compression = ON
从库配置
[mysqld]
server-id = 2
relay-log = mysql-relay-bin# 启用 GTID
gtid-mode = ON
enforce-gtid-consistency = ON# 从库只读(防止误写)
read-only = 1
✅ 主从都需配置 GTID,否则无法复制。
重启 MySQL 服务:
#这里采用容器部署mysql实例
docker restart mysql
步骤 2:主库创建复制用户
CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'Passwd123!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
FLUSH PRIVILEGES;
步骤 3:备份主库数据(启用 GTID)
使用 mysqldump
并自动记录 GTID 位置:
mysqldump \--single-transaction \--source-data=2 \ #mysql8.0 采用source --routines \--triggers \--all-databases \--set-gtid-purged=ON \ # 包含 GTID 信息-u root -p > gtid_backup.sql
步骤 4:恢复备份到从库
scp gtid_backup.sql slave:/home/data
mysql -u root -p < /home/data/gtid_backup.sql
步骤 5:在从库配置复制(使用 GTID)
CHANGE MASTER TOMASTER_HOST='192.168.1.10',MASTER_USER='repl',MASTER_PASSWORD='Passwd123!',MASTER_PORT=3306,MASTER_AUTO_POSITION = 1; -- 关键:启用 GTID 自动定位
⚠️ 不再需要 MASTER_LOG_FILE
和 MASTER_LOG_POS
!
启动复制:
START SLAVE;
停止复制:
STOP SLAVE;
重置元素复制
resst slave all
步骤 6:验证复制状态
SHOW SLAVE STATUS\G
检查:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Using_Gtid: Slave_Pos
或Master_Pos
Retrieved_Gtid_Set
: 从主库获取的 GTID 集合Executed_Gtid_Set
: 已执行的 GTID 集合
✅ 如果
Retrieved_Gtid_Set
是Executed_Gtid_Set
的子集,说明同步正常。
✅ 四、测试 GTID 复制
1. 在主库插入数据
INSERT INTO db1.users(name) VALUES ('Alice');
2. 在从库查询
SELECT * FROM db1.users;
3. 查看 GTID 执行情况
-- 主库
SHOW MASTER STATUS;-- 从库
SELECT @@GLOBAL.GTID_EXECUTED;
✅ 五、GTID 相关常用命令
命令 | 说明 |
---|---|
SHOW MASTER STATUS; | 查看当前 GTID 执行到哪 |
SHOW SLAVE STATUS\G | 查看从库 GTID 同步状态 |
SELECT @@GLOBAL.GTID_EXECUTED; | 当前实例已执行的 GTID 集合 |
SELECT @@GLOBAL.GTID_PURGED; | 已清理(Purged)的 GTID 集合 |
RESET MASTER; | 清空 binlog 和 GTID_EXECUTED (慎用!) |
SET GLOBAL GTID_PURGED='...'; | 手动设置已清理的 GTID(用于搭建从库) |
✅ 六、GTID 复制的注意事项
1. gtid_mode
必须为 ON
- 所有参与复制的节点都必须开启 GTID
- 修改
gtid_mode
需重启,且需按步骤操作(不能直接从 OFF 切到 ON)
2. enforce-gtid-consistency = ON
- 确保所有语句都兼容 GTID
- 禁止使用
CREATE TABLE ... SELECT
、INSERT INTO ... SELECT
等非安全语句
3. 备份时使用 --set-gtid-purged=ON
- 确保从库知道哪些事务已执行
- 如果不想导出 GTID 信息(如用于开发环境),可用
--set-gtid-purged=OFF
4. 避免 RESET MASTER
- 会清空
GTID_EXECUTED
,导致从库无法同步 - 如必须执行,需重新全量备份恢复从库
✅ 七、GTID 故障排查
❌ 错误:ERROR 1837 (HY000): When @@SESSION.GTID_NEXT is set to a GTID...
原因:在会话中手动设置了 GTID_NEXT
,但未正确提交。
解决:
SET SESSION GTID_NEXT = AUTOMATIC;
❌ 错误:The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1...
原因:主库未开启 GTID。
解决:检查主库 my.cnf
是否启用 gtid-mode=ON
。
✅ 八、GTID 与传统复制的对比
特性 | 传统复制 | GTID 复制 |
---|---|---|
配置复杂度 | 高(需记 file/pos) | 低(MASTER_AUTO_POSITION=1 ) |
故障切换 | 手动定位 pos | 自动定位 |
数据一致性 | 依赖人工 | 强保证 |
支持多主 | 否 | 是(需配合 MGR) |
推荐程度 | ❌ 不推荐新架构 | ✅ 强烈推荐 |
✅ 总结
步骤 | 关键点 |
---|---|
1. 配置 my.cnf | gtid-mode=ON , enforce-gtid-consistency=ON |
2. 备份 | --set-gtid-purged=ON |
3. 恢复 | 直接导入 SQL |
4. 配置复制 | MASTER_AUTO_POSITION=1 |
5. 验证 | SHOW SLAVE STATUS\G 看 GTID 状态 |