在MySQL中,使用物理备份工具 xtrabackup备份扩容从库,从库上的gtid_executed和gtid_purged变化过程

目录

    • [1. **备份阶段**](#1. 备份阶段)
    • [2. **恢复阶段**](#2. 恢复阶段)
    • [3. **GTID 状态的变化**](#3. GTID 状态的变化)
    • [4. **配置复制**](#4. 配置复制)
    • [5. **复制启动后的变化**](#5. 复制启动后的变化)
      • [**gtid_executed 的变化**](#gtid_executed 的变化)
      • [**gtid_purged 的变化**](#gtid_purged 的变化)
    • [6. **自动化脚本示例**](#6. 自动化脚本示例)
    • [7. **重要注意事项**](#7. 重要注意事项)
    • 总结

在使用 Percona XtraBackup 物理备份工具来扩容 MySQL 从库时,GTID 相关的状态( gtid_executedgtid_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';

设置后的状态变化

  1. gtid_executed

    • 自动被设置为与 gtid_purged 相同的值
    • 因为 MySQL 会将 gtid_purged 中的事务标记为已执行
  2. 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 设置的前提条件

  1. gtid_executed 必须为空
  2. MySQL 必须重启或执行 RESET MASTER
  3. 不能有正在运行的复制

常见问题解决

如果遇到 "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的迁移流程是:

  1. 备份 时记录源实例的 gtid_executed
  2. 恢复 后在新实例上设置相同的 gtid_purged
  3. MySQL自动将 gtid_purged 同步到 gtid_executed
  4. 配置复制 时使用 MASTER_AUTO_POSITION=1,从备份结束点之后的事务开始同步

这样确保了数据的一致性,新从库不会重复执行已经在备份中包含的事务。

相关推荐
liulilittle2 小时前
Linux shell 搜索指定后缀名文件,并复制到指定目录。
linux·服务器·数据库
必胜刻2 小时前
Redis哨兵模式(Linux)
linux·数据库·redis
dualven_in_csdn2 小时前
【数据库损坏】关于一次现场数据库损坏
数据库·mysql
锦衣夜行?3 小时前
oracle 未知长度从左到右截取某个字符串
数据库·oracle
han_hanker3 小时前
@JsonIgnore,@JsonProperty, @JsonInclude,@JsonFormat
数据库·oracle
hanyi_qwe3 小时前
MySQL事务基础
数据库·mysql
l1t3 小时前
三种用SQL解决Advent of Code 2022第8题 树顶木屋 的比较和分析
数据库·sql·oracle·duckdb·advent of code
如果未来,3 小时前
Oracle的Redo log和Undo log的区别
数据库·oracle
koping_wu3 小时前
【方案设计】Mysql相关场景
数据库·mysql