4、分区表还原实战:单分区还原、跨分区还原、时间点还原(PITR)、还原后的数据一致性校验
分区表备份做完了,接下来就是还原。说实话,很多DBA备份做得勤快,但还原却很少演练。我见过不少项目,真到出故障时才发现备份文件有问题,或者还原步骤记不清了。嗯,今天咱们就把分区表还原的几种场景都过一遍。
4.1 单分区还原:只恢复坏掉的那一块
先说说最常见的场景。某个分区数据损坏了,比如2024年1月的销售记录读不出来。这时候你不需要恢复整个表,只恢复这一个分区就行。
我个人习惯用 ALTER TABLE ... EXCHANGE PARTITION 配合备份文件来做。流程是这样的:
- 先把损坏的分区交换成一个临时表
- 从备份中恢复这个分区的数据到临时表
- 再把临时表交换回原分区
举个例子,假设表 sales 有分区 p202401:
-- 第一步:创建临时表,结构要和分区一致
CREATE TABLE sales_temp LIKE sales;
-- 第二步:把损坏的分区交换出去
ALTER TABLE sales EXCHANGE PARTITION p202401 WITH TABLE sales_temp;
-- 第三步:从备份恢复数据到临时表
-- 假设你用的是 pg_dump 或 mysqldump 的单分区备份
pg_restore -d mydb -t sales_temp /backup/sales_p202401.dump
-- 第四步:把恢复好的数据交换回来
ALTER TABLE sales EXCHANGE PARTITION p202401 WITH TABLE sales_temp;
-- 清理临时表
DROP TABLE sales_temp;
4.2 跨分区还原:把数据恢复到另一个分区
跨分区还原听起来复杂,其实说白了就是把A分区的数据恢复到B分区。什么场景下会用?比如你误删了某个分区的数据,但备份里还有,你想恢复到另一个时间分区里做对比分析。
我建议的做法是:
- 从备份中恢复数据到一个独立表
- 修改数据的时间字段,使其符合目标分区的边界
- 用
INSERT INTO ... SELECT插入目标分区
-- 从备份恢复到一个临时表
pg_restore -d mydb -t sales_restore /backup/sales_p202401.dump
-- 检查数据范围
SELECT MIN(sale_date), MAX(sale_date) FROM sales_restore;
-- 假设结果是 2024-01-01 到 2024-01-31
-- 如果要恢复到 p202402 分区,需要修改日期
UPDATE sales_restore
SET sale_date = sale_date + INTERVAL '1 month'
WHERE sale_date BETWEEN '2024-01-01' AND '2024-01-31';
-- 插入目标分区
INSERT INTO sales (id, sale_date, amount)
SELECT id, sale_date, amount FROM sales_restore;
COUNT(*) 对比,确认数据量对得上再提交。
4.3 时间点还原(PITR):回到故障前的最后一刻
时间点还原,简称PITR,是数据库恢复的终极武器。它能让你把数据库恢复到过去任意一个时间点。比如今天上午10点有人误删了数据,你可以恢复到9点59分59秒的状态。
PITR的原理其实不复杂:
- 你有一个全量备份(比如昨晚的)
- 还有从那时到现在的WAL日志(或binlog)
- 数据库重放这些日志,停在你要的时间点
在PostgreSQL里,我常用的步骤是:
-- 1. 恢复全量备份到某个目录
pg_restore -d mydb /backup/full_backup.dump
-- 2. 配置恢复参数
-- 在 postgresql.conf 或 recovery.conf 中设置:
restore_command = 'cp /wal_archive/%f %p'
recovery_target_time = '2024-01-15 09:59:59'
-- 3. 启动数据库,它会自动重放WAL到指定时间点
pg_ctl start -D /data/mydb
-- 4. 确认恢复完成后,执行:
SELECT pg_is_in_recovery();
-- 返回 false 表示恢复完成
核心要点:PITR的精度取决于WAL日志的完整性。我建议WAL归档目录和数据库放在不同的磁盘上,避免同时损坏。另外,测试PITR时一定要用测试库,别在生产库上直接试。
4.4 还原后的数据一致性校验
数据恢复完了,不代表就万事大吉了。我见过有人恢复完数据就直接上线,结果发现少了几行,或者数据对不上。所以,校验这一步绝对不能省。
我一般做三件事:
- 行数校验:对比备份时的行数和恢复后的行数
- 校验和校验:对关键字段做MD5或CRC校验
- 业务逻辑校验:比如总金额、订单数量等业务指标
-- 行数校验
SELECT COUNT(*) FROM sales WHERE partition_key = '202401';
-- 对比备份记录中的行数
-- 校验和校验(PostgreSQL示例)
SELECT MD5(STRING_AGG(id::text || amount::text, ',' ORDER BY id))
FROM sales WHERE partition_key = '202401';
-- 和备份时记录的MD5值对比
-- 业务逻辑校验
SELECT SUM(amount) FROM sales WHERE partition_key = '202401';
-- 和业务报表对比
4.5 本章知识体系图
下面这张图帮你理清分区表还原的几种场景和流程:
这张图把四种还原场景串起来了。你想想看,从单分区到跨分区,再到PITR,最后落到一致性校验,每一步都有它的价值。我个人觉得,校验这一步最容易被忽略,但恰恰是最关键的。
好了,分区表还原的内容就这些。记住,备份是手段,还原才是目的。能把数据完整、一致地恢复回来,才是真本事。