xtrabackup 备份与恢复实验手册
实验目标
通过本实验,学生将理解:
- 全量备份的过程和文件结构
--prepare的作用和前后变化- 备份后数据变化对 LSN 的影响
- 完整的数据恢复流程
实验环境准备
1. 确认 MySQL 已安装并运行
bash
systemctl status mysqld
mysql -uroot -p -e "SELECT VERSION();"
2. 确认 xtrabackup 已安装
bash
xtrabackup --version
3. 创建实验目录
bash
mkdir -p /data/backup/exp
cd /data/backup/exp
4. 确认 MySQL 连接参数
bash
# 查看 socket 路径
grep socket /etc/my.cnf
# 预期输出:socket=/data/mysql/mysql.sock
实验一:全量备份与 prepare 前后对比
步骤 1:执行全量备份
bash
xtrabackup --backup \
--user=root \
--password=123456 \
--socket=/data/mysql/mysql.sock \
--target-dir=/data/backup/exp/full_backup
预期输出: 最后一行显示 completed OK!
步骤 2:查看备份文件结构
bash
ls -la /data/backup/exp/full_backup
学生需要认识的文件:
| 文件 | 作用 |
|---|---|
xtrabackup_checkpoints |
备份的 LSN 位置信息(核心) |
xtrabackup_logfile |
备份期间的 redo 日志 |
ibdata1 |
系统表空间 |
mysql.ibd |
mysql 系统库 |
undo_001 / undo_002 |
undo 表空间 |
backup-my.cnf |
MySQL 配置备份 |
步骤 3:查看 prepare 前的检查点
bash
cat /data/backup/exp/full_backup/xtrabackup_checkpoints
记录输出:
backup_type = full-backuped
from_lsn = 0
to_lsn = xxxxx
last_lsn = xxxxx
步骤 4:查看 prepare 前的 redo 日志大小
bash
ls -lh /data/backup/exp/full_backup/xtrabackup_logfile
步骤 5:执行 prepare
bash
xtrabackup --prepare --target-dir=/data/backup/exp/full_backup
步骤 6:查看 prepare 后的检查点
bash
cat /data/backup/exp/full_backup/xtrabackup_checkpoints
对比变化:
backup_type从full-backuped变为full-preparedlast_lsn不变
步骤 7:查看 prepare 后的 redo 日志
bash
ls -lh /data/backup/exp/full_backup/xtrabackup_logfile
观察: 文件应该消失或大小为 0
实验一总结表
| 项目 | prepare 前 | prepare 后 |
|---|---|---|
backup_type |
full-backuped | full-prepared |
last_lsn |
固定值 L | 不变(L) |
xtrabackup_logfile |
存在(有大小) | 消失/空 |
| 数据一致性 | 不一致 | 一致 |
实验二:备份后写入数据,观察 LSN 变化
步骤 1:记录当前 LSN
bash
mysql -uroot -p123456 -e "SHOW ENGINE INNODB STATUS\G" | grep "Log sequence number"
步骤 2:写入测试数据
bash
mysql -uroot -p123456 -e "
CREATE DATABASE IF NOT EXISTS test;
USE test;
CREATE TABLE users (id INT, name VARCHAR(50));
INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob');
"
步骤 3:再次查看 LSN(应该变大了)
bash
mysql -uroot -p123456 -e "SHOW ENGINE INNODB STATUS\G" | grep "Log sequence number"
步骤 4:重新备份
bash
xtrabackup --backup \
--user=root \
--password=123456 \
--socket=/data/mysql/mysql.sock \
--target-dir=/data/backup/exp/full_backup2
步骤 5:查看新备份的 LSN(比第一次大)
bash
cat /data/backup/exp/full_backup2/xtrabackup_checkpoints
实验二结论
LSN 随着数据修改而增长
备份记录的 LSN = 备份完成那一刻的位置
备份之间的 LSN 差异 = 期间数据变化的量
实验三:完整恢复演练
步骤 1:模拟故障(删除数据)
bash
# 停止 MySQL
systemctl stop mysqld
# 备份原数据目录
mv /data/mysql/data /data/mysql/data.bak.$(date +%Y%m%d_%H%M%S)
# 创建新的空数据目录
mkdir -p /data/mysql/data
步骤 2:恢复数据
bash
xtrabackup --copy-back --target-dir=/data/backup/exp/full_backup
步骤 3:修复权限
bash
chown -R mysql:mysql /data/mysql/data
步骤 4:启动 MySQL
bash
systemctl start mysqld
systemctl status mysqld
步骤 5:验证数据
bash
mysql -uroot -p123456 -e "SHOW DATABASES;"
mysql -uroot -p123456 -e "SELECT * FROM test.users;"
预期输出: 恢复后的数据与备份时一致(实验二写入的数据不会出现)
实验三结论
恢复的数据 = 备份时刻的数据状态
备份后写入的数据会丢失(除非使用增量备份)
实验四:增量备份(扩展实验)
步骤 1:基于全量备份做增量
bash
# 先写入一些数据
mysql -uroot -p123456 -e "INSERT INTO test.users VALUES (3, 'Charlie');"
# 执行增量备份
xtrabackup --backup \
--user=root \
--password=123456 \
--socket=/data/mysql/mysql.sock \
--target-dir=/data/backup/exp/incr_backup1 \
--incremental-basedir=/data/backup/exp/full_backup
步骤 2:查看增量备份的 LSN
bash
cat /data/backup/exp/incr_backup1/xtrabackup_checkpoints
观察: backup_type = incremental,from_lsn 等于全量备份的 last_lsn
步骤 3:准备恢复(需要合并全量+增量)
bash
# 先 prepare 全量
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/exp/full_backup
# 合并增量
xtrabackup --prepare --apply-log-only \
--target-dir=/data/backup/exp/full_backup \
--incremental-dir=/data/backup/exp/incr_backup1
# 最后执行完整 prepare
xtrabackup --prepare --target-dir=/data/backup/exp/full_backup
快速验证脚本(一键测试)
bash
#!/bin/bash
# 完整实验验证脚本
echo "========== 1. 执行全量备份 =========="
xtrabackup --backup --user=root --password=123456 \
--socket=/data/mysql/mysql.sock \
--target-dir=/data/backup/exp/full_backup
echo "========== 2. 查看 prepare 前检查点 =========="
cat /data/backup/exp/full_backup/xtrabackup_checkpoints
echo "========== 3. 执行 prepare =========="
xtrabackup --prepare --target-dir=/data/backup/exp/full_backup
echo "========== 4. 查看 prepare 后检查点 =========="
cat /data/backup/exp/full_backup/xtrabackup_checkpoints
echo "========== 5. 写入测试数据 =========="
mysql -uroot -p123456 -e "CREATE DATABASE IF NOT EXISTS test; CREATE TABLE test.t1(id INT); INSERT INTO test.t1 VALUES(1);"
echo "========== 6. 重新备份(观察 LSN 变大) =========="
xtrabackup --backup --user=root --password=123456 \
--socket=/data/mysql/mysql.sock \
--target-dir=/data/backup/exp/full_backup2
cat /data/backup/exp/full_backup2/xtrabackup_checkpoints
echo "========== 7. 模拟故障并恢复 =========="
systemctl stop mysqld
mv /data/mysql/data /data/mysql/data.bak
mkdir -p /data/mysql/data
xtrabackup --copy-back --target-dir=/data/backup/exp/full_backup
chown -R mysql:mysql /data/mysql/data
systemctl start mysqld
echo "========== 8. 验证恢复结果 =========="
mysql -uroot -p123456 -e "SHOW DATABASES;"
mysql -uroot -p123456 -e "SELECT * FROM test.t1;" 2>/dev/null || echo "test.t1 不存在(正确,因为备份时还没创建)"
echo "========== 实验完成 =========="
核心知识点总结
| 概念 | 解释 |
|---|---|
| LSN | 日志序列号,MySQL 每次数据修改都会递增 |
| 全量备份 | 复制所有数据文件 + 记录备份期间的 redo |
| --prepare | 应用 redo 使数据一致,相当于崩溃恢复 |
| --copy-back | 把 prepare 后的备份复制回数据目录 |
| 增量备份 | 只记录上次备份以来的变化,需要基于全量 |
| backup_type | full-backuped → full-prepared(标记已准备) |
这个实验手册,大家最好亲手操作并观察每个步骤的变化,真正理解 xtrabackup 的工作原理。