目录
-
- [1. **备份阶段**](#1. 备份阶段)
-
- [获取 GTID 状态](#获取 GTID 状态)
- 备份命令示例
- [2. **恢复阶段**](#2. 恢复阶段)
- [3. **GTID 状态的变化**](#3. GTID 状态的变化)
-
- **恢复后首次启动前**
- [**从备份中提取 GTID 信息**](#从备份中提取 GTID 信息)
- [**设置 gtid_purged**](#设置 gtid_purged)
- **设置后的状态变化**
- [4. **配置复制**](#4. 配置复制)
- [5. **复制启动后的变化**](#5. 复制启动后的变化)
-
- [**gtid_executed 的变化**](#gtid_executed 的变化)
- [**gtid_purged 的变化**](#gtid_purged 的变化)
- [6. **自动化脚本示例**](#6. 自动化脚本示例)
- [7. **重要注意事项**](#7. 重要注意事项)
-
- [**gtid_purged 设置的前提条件**](#gtid_purged 设置的前提条件)
- **常见问题解决**
- **验证**
- 总结
在使用 Percona XtraBackup 物理备份工具来扩容 MySQL 从库时,GTID 相关的状态( gtid_executed 和 gtid_purged)会按照以下方式变化:
1. 备份阶段
获取 GTID 状态
- XtraBackup 在备份过程中会记录 备份结束点 的 GTID 信息
- 信息保存在备份目录的
xtrabackup_binlog_info文件中:
bash
# 文件内容示例
mysql-bin.000003 107 a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0:1-100,
b0b0b0b0-b0b0-b0b0-b0b0-b0b0b0b0b0b0:1-50
- 最后一列 就是备份结束时已执行的 GTID 集合
备份命令示例
bash
xtrabackup --backup \
--slave-info \
--target-dir=/backup \
--host=主库地址 \
--user=备份用户
2. 恢复阶段
准备备份
bash
xtrabackup --prepare --target-dir=/backup
恢复数据
bash
xtrabackup --copy-back --target-dir=/backup
3. GTID 状态的变化
恢复后首次启动前
- 从库的
gtid_executed为空 gtid_purged为空
从备份中提取 GTID 信息
sql
-- 查看备份中的 GTID 信息
cat /backup/xtrabackup_binlog_info
-- 输出:mysql-bin.000003 107 uuid1:1-100,uuid2:1-50
- 这个 GTID 集合表示 备份时已经提交的事务
设置 gtid_purged
在启动从库后,需要手动设置 gtid_purged:
sql
-- 重置 master,清空 GTID 状态
RESET MASTER;
-- 设置 gtid_purged 为备份中的 GTID 集合
SET GLOBAL gtid_purged = 'a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0:1-100,
b0b0b0b0-b0b0-b0b0-b0b0-b0b0b0b0b0b0:1-50';
设置后的状态变化
-
gtid_executed:
- 自动被设置为与
gtid_purged相同的值 - 因为 MySQL 会将
gtid_purged中的事务标记为已执行
- 自动被设置为与
-
gtid_purged:
- 包含备份时已提交但不在 binlog 中的事务
- 这些事务已应用到数据文件中,但二进制日志中不存在
sql
-- 查看设置后的状态
SHOW GLOBAL VARIABLES LIKE 'gtid_executed';
SHOW GLOBAL VARIABLES LIKE 'gtid_purged';
-- 两者应该相同
4. 配置复制
sql
-- 配置复制
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_AUTO_POSITION=1;
-- 启动复制
START SLAVE;
5. 复制启动后的变化
gtid_executed 的变化
- 从库应用新事务时,
gtid_executed会 逐渐增加 - 包含
gtid_purged中的事务 + 复制应用的新事务
gtid_purged 的变化
- 正常情况下
gtid_purged保持不变 - 只有当执行
PURGE BINARY LOGS或 binlog 自动清理时才会增长
6. 自动化脚本示例
bash
#!/bin/bash
# 恢复备份并自动设置 GTID
# 1. 准备备份
xtrabackup --prepare --target-dir=/backup
# 2. 恢复数据
xtrabackup --copy-back --target-dir=/backup
# 3. 启动 MySQL
systemctl start mysql
# 4. 获取备份中的 GTID
GTID_SET=$(awk '{print $3}' /backup/xtrabackup_binlog_info)
# 5. 设置 GTID(在 MySQL 中执行)
mysql -e "RESET MASTER;"
mysql -e "SET GLOBAL gtid_purged='$GTID_SET';"
7. 重要注意事项
gtid_purged 设置的前提条件
gtid_executed必须为空- MySQL 必须重启或执行
RESET MASTER后 - 不能有正在运行的复制
常见问题解决
如果遇到 "GTID_PURGED can only be set when GTID_EXECUTED is empty" 错误:
sql
-- 解决方案
STOP SLAVE; -- 停止复制
RESET SLAVE ALL; -- 重置复制信息
RESET MASTER; -- 重置 GTID 状态
-- 然后重新设置 gtid_purged
验证
恢复完成后验证:
sql
-- 检查 GTID 状态
SHOW GLOBAL VARIABLES LIKE 'gtid%';
-- 检查复制状态
SHOW SLAVE STATUS\G
-- 确保 Auto_Position=1 且没有复制错误
总结
使用 xtrabackup 扩容从库时,GTID的迁移流程是:
- 备份 时记录源实例的
gtid_executed - 恢复 后在新实例上设置相同的
gtid_purged - MySQL自动将
gtid_purged同步到gtid_executed - 配置复制 时使用
MASTER_AUTO_POSITION=1,从备份结束点之后的事务开始同步
这样确保了数据的一致性,新从库不会重复执行已经在备份中包含的事务。