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 推进。

相关推荐
whn197728 分钟前
oracle的节点2无法启动asm实例 提示PMON terminating the instance due to error 481
数据库·oracle·wpf
Mico1839 分钟前
MySQL 5.7.35 升级到 8.0.35 — 原地升级(主从架构方式)
mysql
AAA@峥1 小时前
Ceph 集群配置管理完整指南
运维·数据库·分布式·ceph
旺仔学长 哈哈1 小时前
基于SpringBoot的在线招聘测评系统的设计与实现----附源码35253+数据库文档
数据库·spring boot·后端·在线招聘
吴声子夜歌1 小时前
MongoDB 4.2——索引(二)
数据库·mongodb·索引
米码收割机2 小时前
【Python】Django恒达科技门户网站(源码+文档)【独一无二】
数据库·python·科技
万亿少女的梦1682 小时前
基于Spring Boot的乐助在线助农系统设计与实现
java·spring boot·mysql·敏感词过滤·助农系统
艾莉丝努力练剑2 小时前
【MYSQL】MYSQL学习的一大重点:基本查询(下)
android·数据库·学习·mysql·面试·八股文
冰暮流星2 小时前
mysql之数据库创建,查询,删除,启用
数据库·mysql·oracle
GIS数据转换器2 小时前
智慧灌区管理平台
大数据·服务器·网络·数据库·人工智能·生活