MySQL基于XtraBackup物理备份搭建GTID主从复制操作手册

一、环境示例

复制代码
主库IP:192.168.1.1
从库IP:192.168.1.2
MySQL端口:3306

从库服务名:mysql_3306
主库备份目录:/data/xtrabackup/
从库备份目录:/data/xtrabackup/

本文采用 GTID 自动定位方式搭建主从复制。

主从 MySQL 版本应保持一致,XtraBackup 版本必须与 MySQL 版本兼容。


二、总体流程

复制代码
【主库】检查GTID、Binlog及server_id
                     ↓
【从库】查询datadir、Socket及server_id
                     ↓
【主库】创建专用复制用户
                     ↓
【主库】执行XtraBackup全量备份
                     ↓
【主库→从库】传输备份文件
  ├─ 不超过100GB:直接传输
  └─ 超过100GB:压缩后传输
                     ↓
【从库】执行xtrabackup --prepare
                     ↓
【从库】停止MySQL并备份原数据目录
                     ↓
【从库】执行xtrabackup --copy-back
                     ↓
【从库】修改权限并删除auto.cnf
                     ↓
【从库】启动MySQL并检查实例信息
                     ↓
【从库】配置GTID主从复制
                     ↓
【从库】检查双Yes及GTID推进

100GB 是本文为了方便现场操作采用的参考分界,并非 XtraBackup 的强制要求。


三、【主库执行】检查主库配置

登录主库:

复制代码
mysql -uroot -p

执行:

复制代码
SHOW VARIABLES
WHERE Variable_name IN (
  'server_id',
  'server_uuid',
  'log_bin',
  'gtid_mode',
  'enforce_gtid_consistency'
);

应满足:

复制代码
server_id:非0
log_bin:ON
gtid_mode:ON
enforce_gtid_consistency:ON

记录主库的 server_idserver_uuid,后续与从库进行对比。


四、【从库执行】查询数据目录和 Socket

从库 MySQL 正常运行时执行:

复制代码
mysql -h127.0.0.1 -P3306 -uroot -p -e "
SHOW VARIABLES
WHERE Variable_name IN ('datadir','socket');
"

返回示例:

复制代码
datadir    /app/data/mysql/3306/data/
socket     /app/data/mysql/3306/run/mysql.sock

根据实际查询结果设置变量:

复制代码
SLAVE_DATADIR="/app/data/mysql/3306/data"
SLAVE_SOCKET="/app/data/mysql/3306/run/mysql.sock"

检查变量:

复制代码
echo "$SLAVE_DATADIR"
echo "$SLAVE_SOCKET"

如果数据库无法登录,可查询配置文件:

复制代码
my_print_defaults mysqld | grep -E '^--(datadir|socket)='

或者:

复制代码
grep -RniE '^[[:space:]]*(datadir|socket)[[:space:]]*=' \
  /etc/my.cnf /etc/mysql 2>/dev/null

五、【从库执行】检查从库配置

从库配置文件建议包含:

复制代码
[mysqld]
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
read_only=ON
super_read_only=ON

注意:

  • 从库 server_id 必须与主库不同;

  • 每个 MySQL 实例必须使用唯一的 server_id

  • 从库端口、数据目录和 Socket 必须与实际环境一致。


六、【主库执行】创建复制用户

在主库执行:

复制代码
CREATE USER IF NOT EXISTS
'repl'@'192.168.1.2'
IDENTIFIED BY '<复制用户密码>';

GRANT REPLICATION SLAVE
ON *.*
TO 'repl'@'192.168.1.2';

SHOW GRANTS FOR 'repl'@'192.168.1.2';

在从库服务器测试连接:

复制代码
mysql -h192.168.1.1 -P3306 -urepl -p -e "SELECT 1;"

确认网络、端口、用户名和密码均正常。


七、【主库执行】执行物理备份

7.1 创建备份目录

复制代码
mkdir -p /data/xtrabackup

BACKUP_DIR="/data/xtrabackup/bk"

if [ -e "$BACKUP_DIR" ]; then
  mv "$BACKUP_DIR" \
     "${BACKUP_DIR}_old_$(date +%Y%m%d_%H%M%S)"
fi

mkdir -p "$BACKUP_DIR"

7.2 执行全量备份

复制代码
xtrabackup \
  --defaults-file=/etc/my.cnf \
  --user=root \
  --password='<主库密码>' \
  --backup \
  --target-dir=/data/xtrabackup/bk

确认命令结尾出现:

复制代码
completed OK!

检查备份状态:

复制代码
cat /data/xtrabackup/bk/xtrabackup_checkpoints

应包含:

复制代码
backup_type = full-backuped

查看备份大小:

复制代码
du -sh /data/xtrabackup/bk

八、【主库→从库】传输备份文件

情况一:备份不超过100GB,直接传输

1.【从库执行】准备接收目录
复制代码
mkdir -p /data/xtrabackup

if [ -e /data/xtrabackup/bk ]; then
  mv /data/xtrabackup/bk \
     /data/xtrabackup/bk_old_$(date +%Y%m%d_%H%M%S)
fi

mkdir -p /data/xtrabackup/bk
2.【主库执行】使用 rsync 传输
复制代码
rsync -avh --progress --partial \
  /data/xtrabackup/bk/ \
  root@192.168.1.2:/data/xtrabackup/bk/

如果没有安装 rsync,可以使用:

复制代码
scp -r \
  /data/xtrabackup/bk \
  root@192.168.1.2:/data/xtrabackup/

传输完成后,在从库检查:

复制代码
ls -lh /data/xtrabackup/bk
cat /data/xtrabackup/bk/xtrabackup_checkpoints

情况二:备份超过100GB,压缩后传输

1.【主库执行】检查剩余空间
复制代码
df -h /data/xtrabackup
2.【主库执行】压缩并生成校验值
复制代码
cd /data/xtrabackup

tar -czf mysql_full_bk.tar.gz bk

sha256sum mysql_full_bk.tar.gz \
  > mysql_full_bk.tar.gz.sha256
3.【主库执行】传输至从库
复制代码
scp mysql_full_bk.tar.gz \
    mysql_full_bk.tar.gz.sha256 \
    root@192.168.1.2:/data/xtrabackup/
4.【从库执行】校验压缩包
复制代码
cd /data/xtrabackup

sha256sum -c mysql_full_bk.tar.gz.sha256

正常应显示:

复制代码
mysql_full_bk.tar.gz: OK
5.【从库执行】解压备份
复制代码
if [ -e /data/xtrabackup/bk ]; then
  mv /data/xtrabackup/bk \
     /data/xtrabackup/bk_old_$(date +%Y%m%d_%H%M%S)
fi

cd /data/xtrabackup

tar -xzf mysql_full_bk.tar.gz

无论采用哪种传输方式,从库最终都应存在:

复制代码
/data/xtrabackup/bk

九、【从库执行】应用备份日志

执行:

复制代码
xtrabackup \
  --prepare \
  --target-dir=/data/xtrabackup/bk

如果 XtraBackup 未加入环境变量,使用实际安装路径:

复制代码
/app/tools/xtrabackup/bin/xtrabackup \
  --prepare \
  --target-dir=/data/xtrabackup/bk

确认命令结尾出现:

复制代码
completed OK!

检查状态:

复制代码
cat /data/xtrabackup/bk/xtrabackup_checkpoints

应显示:

复制代码
backup_type = full-prepared

十、【从库执行】停止 MySQL

复制代码
systemctl stop mysql_3306
systemctl status mysql_3306

确认没有该实例对应的 MySQL 进程:

复制代码
ps -ef | grep '[m]ysqld'

如果服务器上存在多个 MySQL 实例,必须确认停止的是 mysql_3306 对应实例。


十一、【从库执行】备份原数据目录

再次确认数据目录:

复制代码
echo "$SLAVE_DATADIR"

备份原数据目录:

复制代码
mv "$SLAVE_DATADIR" \
   "${SLAVE_DATADIR}_bak_$(date +%Y%m%d_%H%M%S)"

创建新的空数据目录:

复制代码
mkdir -p "$SLAVE_DATADIR"
chown mysql:mysql "$SLAVE_DATADIR"

确认目录为空:

复制代码
ls -la "$SLAVE_DATADIR"

十二、【从库执行】恢复数据文件

执行:

复制代码
xtrabackup \
  --defaults-file=/etc/my.cnf \
  --copy-back \
  --target-dir=/data/xtrabackup/bk \
  --datadir="$SLAVE_DATADIR"

使用指定安装路径时:

复制代码
/app/tools/xtrabackup/bin/xtrabackup \
  --defaults-file=/etc/my.cnf \
  --copy-back \
  --target-dir=/data/xtrabackup/bk \
  --datadir="$SLAVE_DATADIR"

确认命令结尾出现:

复制代码
completed OK!

修改数据目录权限:

复制代码
chown -R mysql:mysql "$SLAVE_DATADIR"

检查:

复制代码
ls -ld "$SLAVE_DATADIR"
ls -l "$SLAVE_DATADIR" | head

十三、【从库执行】删除 auto.cnf

物理备份会将主库的 auto.cnf 一起复制到从库。

该文件保存主库的 server_uuid,因此首次启动从库前必须删除:

复制代码
rm -f "$SLAVE_DATADIR/auto.cnf"

确认已删除:

复制代码
test ! -e "$SLAVE_DATADIR/auto.cnf" && \
echo "auto.cnf已删除"

从库启动后会自动生成新的 server_uuid


十四、【从库执行】启动并检查数据库

启动从库:

复制代码
systemctl start mysql_3306
systemctl status mysql_3306

确认进程:

复制代码
ps -ef | grep '[m]ysqld'

登录从库:

复制代码
mysql -uroot -p -S "$SLAVE_SOCKET"

物理恢复后,应使用备份时间点主库的账号密码登录。

检查实例参数:

复制代码
SELECT
  @@hostname        AS hostname,
  @@server_id       AS server_id,
  @@server_uuid     AS server_uuid,
  @@gtid_mode       AS gtid_mode,
  @@read_only       AS read_only,
  @@super_read_only AS super_read_only;

确认:

复制代码
从库server_id与主库不同
从库server_uuid与主库不同
gtid_mode为ON
read_only为1
super_read_only为1
业务库及数据恢复正常

不要随意执行 RESET MASTER,避免影响恢复后的 GTID 信息。


十五、【从库执行】配置 GTID 主从复制

MySQL 8.0.23及以上

如果从库此前配置过复制:

复制代码
STOP REPLICA;
RESET REPLICA ALL;

配置复制:

复制代码
CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='192.168.1.1',
  SOURCE_PORT=3306,
  SOURCE_USER='repl',
  SOURCE_PASSWORD='<复制用户密码>',
  SOURCE_AUTO_POSITION=1;

START REPLICA;

如果复制用户使用 caching_sha2_password,并出现公钥认证错误,可使用:

复制代码
CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='192.168.1.1',
  SOURCE_PORT=3306,
  SOURCE_USER='repl',
  SOURCE_PASSWORD='<复制用户密码>',
  SOURCE_AUTO_POSITION=1,
  GET_SOURCE_PUBLIC_KEY=1;

START REPLICA;

检查:

复制代码
SHOW REPLICA STATUS\G

MySQL 5.7或较早的 MySQL 8.0

如果从库此前配置过复制:

复制代码
STOP SLAVE;
RESET SLAVE ALL;

配置复制:

复制代码
CHANGE MASTER TO
  MASTER_HOST='192.168.1.1',
  MASTER_PORT=3306,
  MASTER_USER='repl',
  MASTER_PASSWORD='<复制用户密码>',
  MASTER_AUTO_POSITION=1;

START SLAVE;

检查:

复制代码
SHOW SLAVE STATUS\G

十六、【从库执行】确认复制正常

MySQL 8.0检查

复制代码
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Last_IO_Error: 空
Last_SQL_Error: 空
Auto_Position: 1

MySQL 5.7检查

复制代码
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_IO_Error: 空
Last_SQL_Error: 空
Auto_Position: 1

同时观察:

复制代码
Retrieved_Gtid_Set
Executed_Gtid_Set
Seconds_Behind_Master

满足以下条件即可判断主从复制正常:

复制代码
复制线程双Yes
无IO和SQL复制报错
GTID持续推进
复制延迟处于合理范围
主库新增数据能够同步至从库

十七、现场速查

复制代码
【主库】
1. 检查GTID、Binlog及server_id
2. 创建专用复制用户
3. 执行XtraBackup全量备份
4. 使用du -sh查看备份大小
5. 不超过100GB直接传输
6. 超过100GB压缩后传输

【从库】
7. 查询datadir、Socket及server_id
8. 接收或解压备份
9. 执行xtrabackup --prepare
10. 停止MySQL
11. 备份并重建空数据目录
12. 执行xtrabackup --copy-back
13. 修改mysql:mysql权限
14. 删除auto.cnf
15. 启动MySQL并检查server_uuid
16. 配置GTID自动定位复制
17. 检查双Yes、错误信息和GTID推进

十八、注意事项

  1. 主从 MySQL 版本应保持一致。

  2. XtraBackup 版本必须与 MySQL 版本兼容。

  3. 从库原数据目录必须确认可以覆盖,并保留回退目录。

  4. copy-back 前必须停止从库,且目标数据目录必须为空。

  5. 恢复完成后必须修改数据目录属主为 mysql:mysql

  6. 首次启动从库前必须删除恢复过来的 auto.cnf

  7. 主从 server_idserver_uuid 均不能相同。

  8. 生产环境应使用专用复制用户,不要长期使用 root

  9. 如果存在独立 Undo、Redo 或表空间目录,应额外核对文件路径。

  10. 不要只检查复制线程双 Yes,还要检查复制错误、延迟和 GTID 推进。

相关推荐
shushangyun_2 小时前
2026智能采购商城系统选型指南:如何引领企业数字化采购升级
java·大数据·数据库·人工智能·机器学习
华山令狐虫3 小时前
DBAPI AI 写 SQL:支持动态 SQL 与参数占位符,自然语言一键生成
数据库·人工智能·sql·dbapi
IvorySQL4 小时前
PG 技术日报|2026-07-04
数据库·人工智能·postgresql·开源
Hoxy.R4 小时前
KingbaseES读写分离高可用集群扩容、备库重建与故障切换实战
运维·数据库
IvorySQL4 小时前
IvorySQL HTAP 实时湖仓接入引擎
数据库·postgresql·开源·htap·ivorysql
忧郁的紫菜4 小时前
WCF+JSON+实体对象与WebService+DataSet效率大比拼
数据库·oracle·json
IvorySQL5 小时前
PostgreSQL 技术日报|2026-07-05
数据库·postgresql
万亿少女的梦1685 小时前
基于SpringBoot的考研学习交流系统设计与开发
spring boot·mysql·vue·系统设计·论坛系统
我会尽全力 乐观而坚强6 小时前
MySQL库与表的操作
linux·数据库·mysql