MySQL 热备份实战:用 XtraBackup 建立可验证的备份与恢复流程
正片开始,我将围绕 Linux、systemd 管理的独立 MySQL 8.0 实例展开,使用普通 InnoDB 全量备份。
MySQL 8.0 应选择与具体服务器小版本兼容的 Percona XtraBackup 8.0;MySQL 8.4 需要另查对应分支的支持矩阵。同为“8.0”也不能推定任意小版本组合都兼容,安装前要核对所选版本的兼容说明。
在数据库所在节点做只读检查:
mysql --version
xtrabackup --version
systemctl show mysql -p FragmentPath -p User这里的 mysql 是服务名示例,实际可能叫 mysqld。客户端版本不能替代服务器版本;在已有的管理连接中再执行:
SELECT @@version, @@version_comment, @@datadir, @@socket;
SELECT ENGINE, COUNT(*) AS table_count
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN (
'information_schema', 'performance_schema', 'sys'
)
GROUP BY ENGINE;
SHOW VARIABLES
WHERE Variable_name IN (
'log_bin', 'binlog_expire_logs_seconds'
);
SHOW FULL PROCESSLIST;记录服务器版本、数据目录和 socket,确认用户表引擎。发现非事务表、长事务或正在执行的 DDL,就应重新评估备份窗口和锁影响。会话列表不能完整反映所有长事务,必要时还要结合事务监控继续核对。
热备允许数据库继续服务,但仍会消耗 I/O,也可能遇到备份锁等待,不能承诺对业务没有影响。
路径核实后,再看存储和服务日志:
df -h /var/lib/mysql /backup
df -i /var/lib/mysql /backup
journalctl -u mysql --since "1 hour ago" --no-pager -n 100数据目录和备份路径都要替换为实值。关注可用空间、inode、I/O 错误和数据库异常。容量预算应来自实际数据量、增长速度、保留份数和一次演练的峰值,不能套一个通用倍数。
若空间紧张或磁盘延迟正在上升,先处理容量或换窗口,再启动备份。
我会保存备份前后同一时间尺度的监控:请求耗时、数据库错误率、磁盘延迟和剩余空间。备份速度不能代表业务影响。出现异常先对照时间窗和基线,确认资源竞争后再调整时间或并行度。
会话信息可能包含完整 SQL,服务日志和备份日志也可能带业务数据、路径及主机信息。原始证据只保存在受限本地目录,对外共享时先脱敏。
XtraBackup 同时需要数据库授权和本机文件访问权限:备份账号能登录,并不意味着运行工具的系统账号能读取数据文件。专用账号的授权按所选版本和启用功能核对,避免直接授予所有权限。
把凭据保存在受限配置里。以下是 /etc/xtrabackup/backup.cnf 的示例:
!include /etc/mysql/my.cnf
[xtrabackup]
user=backup_user
password=替换为实际密码
socket=/run/mysqld/mysqld.sock
datadir=/var/lib/mysql!include 必须指向源实例实际生效的服务器配置,不能照抄路径;自定义存储设置也要随有效配置核对。
由受控账号持有此文件,设置权限为 600,父目录限制访问。不要把密码放在命令行、定时任务正文、日志或代码仓库里。
后续的 --defaults-file 必须紧接程序名,放在第一个选项位置。
备份完成与日志应用完成,是两道检查
备份会读取在线数据、写入备份目录,并消耗磁盘资源。先选低峰在一个实例验证,观察业务响应、磁盘延迟、备份耗时和锁等待。
超过事先约定的业务阈值时,停止本次备份,保留日志和未完成目录,不把它加入可恢复备份列表。
下面代码保存为 Bash 脚本执行,使用新建空目录,日志放在目录外。示例由具备文件权限的受控账号执行:
set -Eeuo pipefail
umask 077
mkdir -p /backup/mysql
B=$(mktemp -d "/backup/mysql/full-$(date +%Y%m%d-%H%M%S)-XXXXXX")
xtrabackup --defaults-file=/etc/xtrabackup/backup.cnf \
--backup --target-dir="$B" \
2>&1 | tee "${B}.backup.log"
xtrabackup --defaults-file=/etc/xtrabackup/backup.cnf \
--prepare --target-dir="$B" \
2>&1 | tee "${B}.prepare.log"
grep -Fq 'completed OK!' "${B}.backup.log"
grep -Fq 'completed OK!' "${B}.prepare.log"
grep -Eq '^backup_type[[:space:]]*=[[:space:]]*full-prepared[[:space:]]*