
一、环境示例
主库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_id 和 server_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推进
十八、注意事项
-
主从 MySQL 版本应保持一致。
-
XtraBackup 版本必须与 MySQL 版本兼容。
-
从库原数据目录必须确认可以覆盖,并保留回退目录。
-
copy-back前必须停止从库,且目标数据目录必须为空。 -
恢复完成后必须修改数据目录属主为
mysql:mysql。 -
首次启动从库前必须删除恢复过来的
auto.cnf。 -
主从
server_id和server_uuid均不能相同。 -
生产环境应使用专用复制用户,不要长期使用
root。 -
如果存在独立 Undo、Redo 或表空间目录,应额外核对文件路径。
-
不要只检查复制线程双 Yes,还要检查复制错误、延迟和 GTID 推进。