Percona XtraBackup 热备份教程
Percona XtraBackup 是一款开源的 MySQL 物理热备份工具,可以在不锁表、不停服的情况下完成 InnoDB 数据库的完整备份。相比 mysqldump 等逻辑备份工具,XtraBackup 的备份和恢复速度更快,尤其适合数据量较大的生产环境。本文将在搬瓦工 VPS 上演示 XtraBackup 的安装配置、全量备份、增量备份以及自动化备份策略。
一、XtraBackup 与 mysqldump 对比
- 备份方式:XtraBackup 直接复制数据文件(物理备份),mysqldump 生成 SQL 语句(逻辑备份)。
- 备份速度:XtraBackup 速度远超 mysqldump,尤其在 50GB 以上的数据库。
- 恢复速度:XtraBackup 恢复只需复制文件,mysqldump 需要重新执行 SQL。
- 锁表影响:XtraBackup 对 InnoDB 表不锁表,mysqldump 使用
--single-transaction也可以不锁 InnoDB 表。 - 增量备份:XtraBackup 原生支持增量备份,mysqldump 不支持。
二、安装 Percona XtraBackup
2.1 Ubuntu/Debian 安装
# 安装 Percona 仓库
wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
apt update
# 启用工具仓库
percona-release enable-only tools release
# 安装 XtraBackup 8.0(对应 MySQL 8.0)
apt install percona-xtrabackup-80 -y
# 验证安装
xtrabackup --version
2.2 CentOS/RHEL 安装
# 安装 Percona 仓库
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm -y
percona-release enable-only tools release
# 安装 XtraBackup
yum install percona-xtrabackup-80 -y
xtrabackup --version
2.3 创建备份专用账号
为 XtraBackup 创建一个权限最小化的 MySQL 账号:
mysql -u root -p
CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY 'BackupPass123!';
GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'bkpuser'@'localhost';
GRANT SELECT ON performance_schema.log_status TO 'bkpuser'@'localhost';
FLUSH PRIVILEGES;
三、全量备份
3.1 执行全量备份
# 创建备份目录
mkdir -p /data/backups/full
# 执行全量备份
xtrabackup --backup --user=bkpuser --password='BackupPass123!' --target-dir=/data/backups/full/$(date +%Y%m%d)
备份过程中 XtraBackup 会复制 InnoDB 数据文件,同时记录备份期间的 redo log 变更,确保数据一致性。
3.2 准备备份(Prepare)
备份完成后需要执行 prepare 操作,将备份中未提交的事务回滚、已提交的事务前滚:
xtrabackup --prepare --target-dir=/data/backups/full/20260328
prepare 完成后备份才处于一致性状态,可以用于恢复。
3.3 恢复全量备份
# 停止 MySQL
systemctl stop mysql
# 清空数据目录(谨慎操作!)
rm -rf /var/lib/mysql/*
# 恢复备份
xtrabackup --copy-back --target-dir=/data/backups/full/20260328
# 修正权限
chown -R mysql:mysql /var/lib/mysql
# 启动 MySQL
systemctl start mysql
四、增量备份
增量备份只备份自上次备份以来变更的数据页,大幅减少备份时间和空间占用。
4.1 创建增量备份
# 基于全量备份创建第一次增量
xtrabackup --backup --user=bkpuser --password='BackupPass123!' \
--target-dir=/data/backups/inc1 \
--incremental-basedir=/data/backups/full/20260328
# 基于第一次增量创建第二次增量
xtrabackup --backup --user=bkpuser --password='BackupPass123!' \
--target-dir=/data/backups/inc2 \
--incremental-basedir=/data/backups/inc1
4.2 恢复增量备份
恢复增量备份需要按顺序合并:
# 第一步:准备全量备份(不回滚未提交事务)
xtrabackup --prepare --apply-log-only --target-dir=/data/backups/full/20260328
# 第二步:合并第一次增量
xtrabackup --prepare --apply-log-only --target-dir=/data/backups/full/20260328 \
--incremental-dir=/data/backups/inc1
# 第三步:合并最后一次增量(不加 --apply-log-only)
xtrabackup --prepare --target-dir=/data/backups/full/20260328 \
--incremental-dir=/data/backups/inc2
# 第四步:恢复
systemctl stop mysql
rm -rf /var/lib/mysql/*
xtrabackup --copy-back --target-dir=/data/backups/full/20260328
chown -R mysql:mysql /var/lib/mysql
systemctl start mysql
注意:中间的增量合并必须加 --apply-log-only,只有最后一次合并不加,否则会导致数据不一致。
五、压缩与流式备份
5.1 压缩备份
xtrabackup --backup --user=bkpuser --password='BackupPass123!' \
--compress --compress-threads=4 \
--target-dir=/data/backups/compressed
恢复前需要先解压:
xtrabackup --decompress --target-dir=/data/backups/compressed
5.2 流式备份到远程服务器
# 通过 SSH 传输到远程服务器
xtrabackup --backup --user=bkpuser --password='BackupPass123!' \
--stream=xbstream | ssh user@remote-server "cat > /data/backups/backup.xbstream"
# 在远程服务器上解包
xbstream -x < /data/backups/backup.xbstream -C /data/backups/restored
六、自动化备份脚本
创建备份脚本 /usr/local/bin/mysql-backup.sh:
#!/bin/bash
BACKUP_BASE="/data/backups"
DATE=$(date +%Y%m%d_%H%M%S)
DAY_OF_WEEK=$(date +%u)
USER="bkpuser"
PASS="BackupPass123!"
RETENTION_DAYS=14
# 每周日执行全量备份,其他天执行增量备份
if [ "$DAY_OF_WEEK" -eq 7 ]; then
FULL_DIR="$BACKUP_BASE/full_$DATE"
xtrabackup --backup --user=$USER --password=$PASS \
--compress --compress-threads=2 \
--target-dir=$FULL_DIR
echo "$FULL_DIR" > "$BACKUP_BASE/last_full.txt"
echo "[$(date)] Full backup completed: $FULL_DIR"
else
LAST_FULL=$(cat "$BACKUP_BASE/last_full.txt" 2>/dev/null)
if [ -z "$LAST_FULL" ]; then
echo "[$(date)] Error: No full backup found. Run full backup first."
exit 1
fi
INC_DIR="$BACKUP_BASE/inc_$DATE"
xtrabackup --backup --user=$USER --password=$PASS \
--compress --compress-threads=2 \
--target-dir=$INC_DIR \
--incremental-basedir=$LAST_FULL
echo "[$(date)] Incremental backup completed: $INC_DIR"
fi
# 清理过期备份
find $BACKUP_BASE -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
echo "[$(date)] Old backups cleaned up (retention: $RETENTION_DAYS days)"
chmod +x /usr/local/bin/mysql-backup.sh
添加 crontab 定时任务,每天凌晨 2 点执行:
crontab -e
# 添加以下行
0 2 * * * /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1
七、备份验证
备份如果不验证等于没有备份。建议定期在测试环境恢复备份并验证数据完整性:
# 检查备份文件完整性
xtrabackup --validate --target-dir=/data/backups/full/20260328
# 查看备份信息
cat /data/backups/full/20260328/xtrabackup_info
其中 xtrabackup_info 文件记录了备份的 LSN、binlog 位置等关键信息,可以用于 主从复制 的从库初始化。
八、常见问题
- 权限不足错误:确保备份账号拥有 BACKUP_ADMIN、PROCESS、RELOAD 等权限。
- 磁盘空间不足:备份目录需要足够空间,全量备份大小约等于数据目录大小。使用压缩可减少 50-70% 的空间占用。
- 版本不匹配:XtraBackup 8.0 对应 MySQL 8.0,XtraBackup 2.4 对应 MySQL 5.6/5.7,不可混用。
- 备份过程中 MySQL 崩溃:备份文件损坏,需要重新执行备份。
总结
Percona XtraBackup 是 MySQL 生产环境中不可或缺的备份工具,热备份能力让你在不影响业务的情况下完成数据保护。结合全量和增量备份策略,可以在搬瓦工 VPS 有限的磁盘空间内实现高效的数据备份。更多数据库相关教程可参考 MySQL 主从复制 和 慢查询日志分析。选购搬瓦工 VPS 请查看 全部方案,使用优惠码 NODESEEK2026 享受 6.77% 折扣,通过 bwh81.net 进入官网购买。