乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 数据库基础与安装

    • MySQL 简介
    • MySQL 5.6 到 5.7 到 8.0 关键差异速查
    • 安装 MySQL 5.7
    • 连接与断开服务器
    • 创建数据库
    • 创建数据表
    • 数据库与数据表
    • 加载数据
    • 获取数据库信息
    • 批处理模式
    • SHOW 语句汇总
    • FLUSH 与 RESET 语句
    • my.cnf 核心参数
    • 字符集与排序规则
  • 第2章 SQL基础查询

    • SELECT
    • WHERE
    • ORDER BY
    • LIMIT
    • COUNT
    • 聚合函数
    • 比较运算符
    • 逻辑运算符
    • 算术运算符
    • 模式匹配
    • NULL 值处理
    • UPDATE
    • DELETE
    • REPLACE
    • SELECT INTO
  • 第3章 数据类型与运算符

    • 数值类型
    • 字符串类型
    • 日期时间类型
    • BIT 类型
    • ENUM 类型
    • SET 类型
    • JSON 类型
    • 类型转换
  • 第4章 函数与表达式

    • 字符串函数
    • 数值函数
    • 日期函数
    • 全文检索函数
  • 第5章 高级查询与子查询

    • JOIN
    • 子查询
    • UNION
    • GROUP BY
    • HAVING
    • DISTINCT
  • 第6章 表与索引

    • 数据定义语言
    • 修改表结构
    • 视图
    • 修改视图与检查选项
    • 外键
    • 索引
    • 唯一索引
    • 复合索引
    • 存储引擎对比
    • 分区表
    • 第一范式与第二范式
    • 第三范式与 BC 范式
    • 反范式设计
  • 第7章 存储过程与函数

    • 存储过程
    • 存储函数
    • 变量
    • 流程控制
    • 游标
    • 预处理语句
  • 第8章 事务与锁

    • 事务
    • 事务隔离级别
    • 锁机制
    • MVCC
    • 死锁专题分析
    • LOCK TABLES
    • XA 事务
  • 第9章 用户管理与安全

    • 用户管理
    • 权限管理
    • 角色
    • SQL 注入防范
  • 第10章 性能优化入门

    • 执行计划
    • 索引优化
    • 查询优化
    • 查询优化器提示
    • 慢查询日志
    • InnoDB 深入机制
    • InnoDB 专项优化
    • Performance Schema
    • sys Schema
  • 第11章 复制与高可用

    • 主从复制原理
    • 半同步复制配置
    • binlog 开启与 point-in-time 恢复
    • mysqldump 全库备份
    • mysqldump 单表与条件备份
    • mysqldump 恢复与导入
    • xtrabackup 全量热备
    • xtrabackup 准备与恢复
    • xtrabackup 增量与流式备份
  • 第12章 触发器与事件

    • 触发器
    • 事件调度器
  • 参考

    • MySQL 5.7 专业术语大全
    • MySQL 5.7 关键字与保留字大全

xtrabackup 准备与恢复

导学

xtrabackup 备份出来的文件不是"立即可用"的状态——备份过程中数据文件可能正在被修改,redo log 记录了这些变更。prepare(准备)阶段就是模拟 InnoDB 崩溃恢复,将备份文件变为一致性状态。之后才能 copy-back 到 MySQL 数据目录启动。

定义

Prepare(准备):对 xtrabackup 备份文件应用 redo log,使数据文件恢复到备份结束时的一致状态。类似于 InnoDB 启动时的自动崩溃恢复。Copy-back(复制回):将准备完毕的备份文件复制到 MySQL 数据目录,替代原有文件。Move-back(移回):与 copy-back 类似,但使用移动而非复制,速度更快但会删除备份文件。

场景一:全备的 prepare

前置条件:已完成全量备份 /backup/full_backup。

ls /backup/full_backup/
# 包含 ibdata1、.ibd 文件、xtrabackup_logfile 等

操作语句:

xtrabackup --prepare --target-dir=/backup/full_backup

输出关键片段:

240115 02:10:00 Starting to apply log...
240115 02:10:01 xtrabackup: starting shutdown with innodb_fast_shutdown = 1
240115 02:10:02 InnoDB: Shutdown completed; log sequence number 12345678
240115 02:10:02 completed OK!

验证准备后的目录:

ls -la /backup/full_backup/

预期变化:

  • xtrabackup_logfile 被应用后可能变小或消失
  • 新增 xtrabackup_binlog_info(记录 binlog 位置)
  • ib_logfile0、ib_logfile1 被重建为正常大小

结果解读:

  • --prepare 读取 xtrabackup_logfile 中的 redo log,将其应用到数据文件
  • 同时回滚未提交的事务(如果这是最终恢复点)
  • 准备后的备份目录相当于 InnoDB 正常关闭后的数据目录,可以直接复制到 MySQL 数据目录启动
  • 注意:prepare 后的备份目录不能再用于增量备份的 base(因为 LSN 已推进)。如需保留原始备份,应先复制一份再 prepare。

场景二:全备 + 增量的 prepare

备份链:

/backup/sunday_full/      # 全备
/backup/monday_incr/      # 增量 1
/backup/tuesday_incr/     # 增量 2

操作语句:

# 步骤 1:prepare 全备(加 --redo-only,保留未提交事务,以便后续增量合并)
xtrabackup --prepare --apply-log-only --target-dir=/backup/sunday_full

# 步骤 2:合并周一增量到全备
xtrabackup --prepare --apply-log-only \
  --target-dir=/backup/sunday_full \
  --incremental-dir=/backup/monday_incr

# 步骤 3:合并周二增量到全备(最后一个增量不加 --apply-log-only)
xtrabackup --prepare \
  --target-dir=/backup/sunday_full \
  --incremental-dir=/backup/tuesday_incr

验证合并后的全备目录:

cat /backup/sunday_full/xtrabackup_checkpoints

预期 to_lsn 已推进到周二增量的结束 LSN:

backup_type = full-prepared
from_lsn = 0
to_lsn = 12347000

结果解读:

  • --apply-log-only 只应用 redo log,不回滚未提交事务。这是增量合并的中间步骤必须加的参数
  • 最后一个增量合并时不加 --apply-log-only,让 InnoDB 正常回滚未提交事务,完成崩溃恢复
  • 合并后 /backup/sunday_full 已包含所有增量数据,成为一个完整的全备
  • 增量备份目录(monday_incr、tuesday_incr)在合并后不再需要使用

场景三:copy-back 恢复

前置条件:

  • MySQL 已停止(systemctl stop mysqld)
  • 原数据目录已清空或备份(mv /var/lib/mysql /var/lib/mysql_old)
  • 新数据目录已创建并设置正确权限(mkdir /var/lib/mysql && chown mysql:mysql /var/lib/mysql)

操作语句:

# 将准备完毕的备份复制到数据目录
xtrabackup --copy-back --target-dir=/backup/sunday_full

# 设置权限(xtrabackup 复制后文件属主是 root)
chown -R mysql:mysql /var/lib/mysql

# 启动 MySQL
systemctl start mysqld

验证恢复:

mysql -u root -p -e "USE company; SELECT emp_name FROM employees;"

预期输出:

+----------+
| emp_name |
+----------+
| 大翔     |
| 白歌     |
| 孔蓝     |
+----------+

结果解读:

  • --copy-back 将备份目录中的所有文件复制到 my.cnf 中 datadir 指定的目录
  • 复制后必须 chown mysql:mysql,否则 MySQL 无法读写数据文件
  • 启动后数据应恢复到备份时的状态
  • 如需恢复到备份后的某个时间点,还需配合 binlog 做 point-in-time 恢复

场景四:move-back(快速恢复)

操作语句:

# 停止 MySQL
systemctl stop mysqld

# 清空数据目录
rm -rf /var/lib/mysql/*

# 直接移动备份文件到数据目录(比 copy 快,但会删除备份)
xtrabackup --move-back --target-dir=/backup/sunday_full

chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld

结果解读:

  • --move-back 用 mv 而非 cp,大库恢复时速度明显更快
  • 代价:备份目录被清空,无法再次用于恢复
  • 适合紧急恢复场景,或备份目录和数据目录在同一文件系统时(mv 只是改 inode,瞬间完成)

场景五:恢复到新实例(克隆)

操作语句:将备份恢复到另一台服务器,用于搭建从库或测试环境。

# 在目标服务器上
# 1. 安装相同版本 MySQL
# 2. 停止 MySQL
systemctl stop mysqld

# 3. 清空数据目录
rm -rf /var/lib/mysql/*

# 4. 从备份服务器 scp 备份目录(已 prepare 完毕)
scp -r backup_server:/backup/sunday_full /tmp/

# 5. copy-back
xtrabackup --copy-back --target-dir=/tmp/sunday_full
chown -R mysql:mysql /var/lib/mysql

# 6. 启动
systemctl start mysqld

# 7. 查看 binlog 位置(用于搭建从库)
cat /var/lib/mysql/xtrabackup_binlog_info

预期输出:

mysql-bin.000015	1234

结果解读:

  • 克隆后的实例数据与备份时完全一致
  • xtrabackup_binlog_info 记录了备份时的 binlog 文件名和位置
  • 如需搭建从库,执行 CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=1234;

常见误区

误区正解
"备份完直接 copy-back 就行"不行。必须先 prepare,否则数据文件不一致,MySQL 启动时会崩溃恢复失败或数据损坏。
"prepare 可以多次执行"可以,但第一次 prepare 后备份就不能再作为增量 base。多次 prepare 无意义,且可能损坏备份。
"copy-back 会覆盖现有数据目录"会。如果数据目录不为空,xtrabackup 会报错。必须先清空或移走原有数据。
"恢复后不需要改权限"必须改。xtrabackup 以 root 运行,copy-back 后的文件属主是 root,MySQL 无法启动。

面试考点

Q:xtrabackup 恢复的完整流程?

  1. 停止 MySQL;2. 清空数据目录;3. xtrabackup --prepare --target-dir=/backup(全备)或先合并增量再 prepare;4. xtrabackup --copy-back --target-dir=/backup;5. chown -R mysql:mysql /var/lib/mysql;6. 启动 MySQL。

Q:--apply-log-only 什么时候用?

增量备份合并的中间步骤必须用。它只应用 redo log 而不回滚未提交事务,保留事务状态以便下一个增量继续合并。最后一个增量合并时不加,让 InnoDB 正常回滚未提交事务。

Q:prepare 后的备份还能再做增量吗?

不能。prepare 会推进 LSN 并回滚事务,备份状态已改变。如需保留增量能力,应先复制一份备份再 prepare。

小结

  • 备份后必须经过 prepare 才能恢复,prepare 应用 redo log 使数据一致
  • 全备直接 prepare;全备 + 增量时,前几次加 --apply-log-only,最后一次不加
  • copy-back 复制到数据目录,move-back 移动(更快但删除备份)
  • 恢复后必须 chown mysql:mysql,否则 MySQL 无法启动
  • 克隆实例时利用 xtrabackup_binlog_info 快速搭建从库

下一章引子:xtrabackup 恢复到备份时刻的状态,但如果误操作发生在备份之后,还需要 binlog 来填补备份到误操作之间的数据空白。

上一页
xtrabackup 全量热备
下一页
xtrabackup 增量与流式备份