Mysql-经典实战案例(4):XtraBackup+binlog恢复实战
真实故事:一次惊心动魄的删库拯救战
7:00 AM:DBA小张给测试库插入最后一批数据
7:05 AM:误执行DROP DATABASE test
(手滑按错终端窗口)
7:06 AM:收到报警短信,后背发凉
7:15 AM:基于上周备份恢复,仍丢失5小时数据
7:17 AM:紧急启用XtraBackup恢复法
7:25 AM:数据毫发无损复活
这篇文章将用最真实的实验还原完整救援流程,手把手带你攻克数据恢复难题。
前言 初识XtraBackup
什么是数据库的热备份?
想象一下你正在给运行的汽车更换轮胎——这就是热备份的生动比喻。XtraBackup作为 Percona公司开源的神器 ,能在数据库正常运行的状态下实现:
- 零停机备份:业务持续运行不中断
- 高效率压缩:TB级数据备份只需传统方法1/3时间
- 智能增量备份:节省大量存储空间
- 精准时间点恢复:找回误删数据
为什么选择它?(与传统工具对比)
维度 | XtraBackup | mysqldump | 物理拷贝 |
---|---|---|---|
备份速度 | ⚡️ 10倍速 | 🐢 慢 | 🚀 最快但有锁 |
锁机制 | 无锁 | 全局读锁 | 需停机 |
恢复精度 | 秒级 | 分钟级 | 秒级但有风险 |
适用场景 | 生产环境首选 | 小数据导出 | 特殊场景 |
如何下载
访问官网地址 https://www.percona.com/downloads
第一章 解密数据恢复
1.1 三层保护结构解析
1.2 XtraBackup核心优势
- 热备份:像给行驶中的汽车换轮胎
- 压缩黑科技:1TB数据备份仅需5分钟
- 智能增量链:只备份变化的数据页
第二章 实战场:构建数据保护网
2.1 实验环境准备
# 创建数据样本
mysql> CREATE TABLE test.qy (
id INT PRIMARY KEY,
name VARCHAR(20)
) ENGINE=InnoDB;
INSERT INTO test.qy VALUES(1,'初始值');
2.2 全量备份实战
xtrabackup --backup --target-dir=/root/full_bak --user=root -p --host=127.0.0.1 --parallel=4
# 查看备份文件
ls /root/full_bak
# ibdata1 qy.ibd xtrabackup_checkpoints
关键文件解析:
xtrabackup_checkpoints
:备份备案(含LSN序列号)xtrabackup_binlog_info
:记录Binlog断点位置
2.3 增量备份操作
# 插入增量数据1(id=2)
mysql> INSERT INTO test.qy VALUES(2,'增量1');
# 首次增量备份(基于全量)
xtrabackup -uroot -p --incremental --incremental-basedir=/root/full_bak --backup --target-dir=/root/incr1
# 插入增量数据2(id=3)
mysql> INSERT VALUES(3,'增量2');
# 二次增量备份(基于前次增量)
xtrabackup -uroot -p --incremental --incremental-basedir=/root/incr1 --backup --target-dir=/root/incr2
备份链验证技巧:
# 对比LSN序列号
cat /root/full_bak/xtrabackup_checkpoints
# to_lsn = 2562568 (全量结束点)
cat /root/incr1/xtrabackup_checkpoints
# from_lsn = 2562568 (必须衔接)
第三章 灾难降临:误删数据库
3.1 模拟事故现场
-- 最后插入一条有效数据
INSERT INTO test.qy VALUES(4,'最后的倔强');
-- 删除数据库
DROP DATABASE test;
3.2 紧急收容处理
注意:恢复过程中,会继续写入语句到 binlog,最终导致增量恢复数据部分变得比较混乱,
# 立即停止数据库!!
systemctl stop mysqld
#备份数据
mv data data.bak
# 备份binlog
cp /mysq/binlog/mysql-bin* /binglogbak
第四章 恢复实战
4.1 恢复全量基底
# 预热基础备份
xtrabackup --prepare --apply-log-only --target-dir=/root/full_bak
4.2 叠增增量层
# 第一层增量融合
xtrabackup --prepare --apply-log-only --target-dir=/root/full_bak --incremental-dir=/root/incr1
# 第二层增量融合(关键区别)
xtrabackup --prepare --target-dir=/root/full_bak --incremental-dir=/root/incr2 # 注意去掉了--apply-log-only
原理揭秘:引用最后一次增量备份到全量时,不需要增加–apply-log-only参数。除了最后一个增备,所有的备份恢复都应该设置 apply-log-only 参数(only 指的就是只回放 redo log 阶段,跳过 undo 阶段),避免未完成事务的回滚
4.3 数据恢复
xtrabackup --copy-back --target-dir=/root/full_bak
# 调整文件归属
chown -R mysql:mysql /var/lib/mysql
# 启动检验
systemctl start mysqld
此时恢复结果:
SELECT * FROM test.qy;
| ID | Name |
|----|----------|
| 1 | 初始值 |
| 2 | 增量1 |
| 3 | 增量2 |
但数据仍不完整!缺失最新插入的id=4
第五章 Binlog精准补全
5.1 锁定事故现场
# 查找最后一次备份的binlog位置
[root@qiuyang1 add2_bak]# cat xtrabackup_info
binlog_pos = filename 'mysql-bin.000016', position '1679', GTID of the last change '169ceca2-482f-11ec-b3ed-b8599f498878:1-45846261
# 通过提前备份好的binlog,导出相关信息
mysqlbinlog /binglogbak/mysql-bin.000016 --start-position=1679 > recovery.sql
5.2 GTID过滤
# 查找危险操作记录(DROP DATABASE)
在recovery.sql中定位到:
# at 2060
# server id 1 end_log_pos 2152
# DROP DATABASE test
# 提取对应的GTID
SET @@SESSION.GTID_NEXT= '1fa292b0-ce64-11ef-bb71-005056b388fd:8'
# 将误操作的binlog的gitd排除掉
mysqlbinlog --exclude-gtids='1fa292b0-ce64-...:8' mysql-bin.000016 > clean.sql
5.3 最终数据缝合
mysql -uroot -p < clean.sql
# 验证结果
SELECT * FROM test.qy;
| ID | Name |
|----|--------------|
| 1 | 初始值 |
| 2 | 增量1 |
| 3 | 增量2 |
| 4 | 最后的倔强 |
恢复成功