MySQL 恢复策略与实战
恢复策略决定数据丢失范围和恢复时间,完善的恢复方案需覆盖多种故障场景。
恢复场景分类
| 场景 | 原因 | 恢复方式 |
|---|---|---|
| 误删数据 | 误操作DELETE/DROP | binlog精确恢复 |
| 表损坏 | 磁盘错误 | 修复或从备份恢复 |
| 库崩溃 | 系统故障 | 完全备份恢复 |
| 灾难恢复 | 硬件故障/机房故障 | 异地备份恢复 |
恢复策略制定
RPO与RTO
| 指标 | 说明 | 影响 |
|---|---|---|
| RPO | Recovery Point Objective | 最大数据丢失量 |
| RTO | Recovery Time Objective | 最大恢复时间 |
SQL
-- 策略设计
-- RPO=1小时:完全备份 + binlog增量备份
-- RTO=30分钟:物理备份快速恢复
-- 建议策略:
-- 每周日完全备份 + 每天增量备份 + 实时binlog
-- 本地备份 + 异地备份(异地灾备)
完全恢复实战
Bash
# 场景:数据库崩溃,从完全备份恢复
# 1. 停止服务
systemctl stop mysql
# 2. 清空数据目录(谨慎)
rm -rf /var/lib/mysql/*
# 3. 恢复完全备份
mysql -u root -p < /backup/full_backup.sql
# 4. 应用增量备份(如果有)
mysqlbinlog /backup/mysql-bin.000003 | mysql -u root -p
# 5. 启动服务
systemctl start mysql
# 6. 验证数据
mysql -u root -p -e "SELECT COUNT(*) FROM users;"
Point-in-Time恢复实战
Bash
# 场景:误删重要数据,恢复到删除前
# 误操作时间:2024-01-15 14:30:00
# 完全备份时间:2024-01-15 00:00:00
# 1. 查找误操作在binlog中的位置
mysqlbinlog --base64-output=decode-rows -v \
--start-datetime="2024-01-15 14:00:00" \
--stop-datetime="2024-01-15 15:00:00" \
mysql-bin.000005 | grep -n "DELETE FROM users"
# 假设找到DELETE在position 5000
# 2. 恢复完全备份
mysql -u root -p mydb < /backup/mydb_full.sql
# 3. 应用binlog到误操作前
mysqlbinlog --start-position=154 \
--stop-position=5000 \
mysql-bin.000005 | mysql -u root -p
# 4. 验证恢复结果
mysql -u root -p -e "SELECT * FROM users WHERE id < 100;"
单表恢复实战
Bash
# 场景:误删单表数据
# 1. 从备份中提取单表
sed -n '/^-- Table structure for table `users`/,/^-- Table structure for table `orders`/p' \
full_backup.sql > users.sql
# 或使用正则提取
awk '/Table structure for table .users./{p=1} /^--/{if(p)print}' \
full_backup.sql > users.sql
# 2. 恢复单表到临时库
mysql -u root -p -e "CREATE DATABASE recover_db;"
mysql -u root -p recover_db < users.sql
# 3. 导出需要恢复的数据
mysqldump -u root -p recover_db users > users_data.sql
# 4. 恢复到原库
mysql -u root -p mydb < users_data.sql
# 5. 清理临时库
mysql -u root -p -e "DROP DATABASE recover_db;"
xtrabackup恢复实战
Bash
# 场景:从xtrabackup物理备份恢复
# 1. 停止服务
systemctl stop mysql
# 2. 准备备份(确保数据一致性)
xtrabackup --prepare --target-dir=/backup/full
# 3. 恢复数据
xtrabackup --copy-back --target-dir=/backup/full
# 4. 设置权限
chown -R mysql:mysql /var/lib/mysql
# 5. 启动服务
systemctl start mysql
增量备份恢复
Bash
# 场景:从完全备份 + 增量备份恢复
# 完全备份: /backup/full
# 增量备份1: /backup/inc1
# 增量备份2: /backup/inc2
# 1. 准备完全备份
xtrabackup --prepare --apply-log-only --target-dir=/backup/full
# 2. 应用第一个增量
xtrabackup --prepare --apply-log-only \
--target-dir=/backup/full \
--incremental-dir=/backup/inc1
# 3. 应用第二个增量(最后一个不加apply-log-only)
xtrabackup --prepare \
--target-dir=/backup/full \
--incremental-dir=/backup/inc2
# 4. 恢复
xtrabackup --copy-back --target-dir=/backup/full
chown -R mysql:mysql /var/lib/mysql
systemctl start mysql
灾难恢复流程
Bash
# 场景:服务器完全损坏,异地恢复
# 1. 准备新服务器
# 安装MySQL,版本与原服务器一致
# 2. 获取异地备份
scp backup_server:/backup/mysql/full.tar.gz /local/
# 3. 解压备份
tar -xzvf full.tar.gz -C /var/lib/mysql/
# 4. 设置权限
chown -R mysql:mysql /var/lib/mysql
# 5. 启动服务
systemctl start mysql
# 6. 验证数据完整性
mysql -u root -p -e "CHECK TABLE users;"
mysql -u root -p -e "SELECT COUNT(*) FROM users;"
恢复验证清单
SQL
-- 1. 检查表结构
SHOW TABLES;
DESCRIBE users;
-- 2. 检查数据量
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM orders;
-- 3. 检查数据完整性
CHECK TABLE users;
CHECK TABLE orders;
-- 4. 检查索引
SHOW INDEX FROM users;
-- 5. 检查存储过程
SHOW PROCEDURE STATUS;
-- 6. 检查触发器
SHOW TRIGGERS;
定期演练恢复流程,确保备份有效可恢复。
要点总结
- 制定明确的RPO和RTO目标
- 完全恢复用于整体崩溃,Point-in-Time用于误操作
- 单表恢复可避免全库恢复影响
- xtrabackup物理备份恢复更快
- 定期演练恢复流程,验证备份有效性
📝 发现内容有误?点击此处直接编辑