Sheet happens. 上一节我们也学过数据库崩溃后完整恢复的步骤。不过现实总是爱搞点小意外。如果你的备份文件损坏了怎么办?现在就来搞清楚这个问题。
简历最好放哪?
开个玩笑。接下来我们要聊技术问题。不过别忘了,玩笑里总有点真话 :)
分析备份损坏
损坏的备份 —— 就像你毕业论文的文件交稿前打不开一样。症状差不多:
- 恢复时出错:用
pg_restore时你可能会看到类似这样的报错:
pg_restore: [archiver] input file does not appear to be a valid archive
- 部分数据丢失或者文件大小不对(比如突然变小或者为零)。
- 解压出来的 SQL 文件有数据断裂、乱码或者空白部分。
备份损坏的原因有很多:
- 备份过程中被中断(比如断电或者系统关机)。
- 文件传输不对(比如拷贝到U盘或网络时出错)。
- 硬件故障(硬盘、内存、RAID阵列崩了)。
- 系统或备份工具配置错误。
- 病毒、恶意软件,还有当然,手滑点错了。
从损坏的备份恢复数据
文件损坏了也不一定就完蛋了。有时候还是能救点东西出来。下面说几个方法。
用 pg_restore 尝试恢复
如果备份是用 pg_dump 以 custom 或 directory 格式做的,可以试试用 pg_restore 加 --ignore-errors 标志来恢复。命令示例:
pg_restore --dbname=your_database --ignore-errors backup_file.dump
这个参数让工具遇到错误时跳过继续往下执行。当然,损坏的地方数据会丢,但至少还能救回一部分。
如果成功了,恢复完一定要仔细检查数据,记录下到底缺了什么。
利用部分数据
假设你有 SQL 文本格式的备份。可以用文本编辑器打开(最好用点高级的,比如 Visual Studio Code 或 Notepad++),看看哪里断了。如果文件还能读,大部分 SQL 语句还在:
- 删掉损坏的部分。
- 手动或者用
psql命令执行剩下的 SQL:
psql -U username -d database_name -f partial_backup.sql
读取 custom 格式文件
如果你的备份是 custom 格式,可以试着分块提取内容:
pg_restore --list backup_file.dump > file_list.txt
这条命令会生成备份里所有对象的列表。然后你可以试着只恢复部分元素(比如某些表或 schema),命令如下:
pg_restore --dbname=your_database --use-list=file_list.txt backup_file.dump
编辑 file_list.txt,把损坏的部分排除掉再恢复。
通过归档日志(WAL)恢复
如果你用的是增量或差异备份(比如 pg_basebackup),你大概率有归档日志(WAL 文件)。这些文件记录了自上次备份以来的所有变更。恢复数据时可以:
- 找到最后一个完整的备份(比如全量备份)。
- 告诉 PostgreSQL WAL 文件在哪:
restore_command = 'cp /path/to/wal_directory/%f %p'
- 执行恢复。
用第三方工具
有时候可以用文件恢复工具尽量减少备份损坏的影响。比较常用的是 ddrescue。命令示例:
ddrescue --force backup_file.dump recovered_dump.file
这个工具会尽量多地恢复数据,生成一个新文件。
如何避免备份损坏
没错,和损坏的文件打交道真的很崩溃。来想想怎么避免这种事吧。
多地存储备份
做项目时备份永远要记住“别把鸡蛋放一个篮子里”。建议多备份几份:
- 本地服务器上。
- 云端(Amazon S3、Google Cloud Storage,或者用 Dropbox 这种简单服务也行)。
- 外部存储(如果你想超级保险)。
定期校验备份完整性
IT 圈有句话:“没测试过的备份不叫备份”。要定期做数据恢复测试。具体做法:
- 把备份上传到测试服务器。
- 从备份恢复数据。
- 检查数据是否正常。
用校验和
备份时生成文件校验和(比如用 MD5 或 SHA256):
md5sum backup_file.dump > backup_file.md5
恢复时对比当前校验和和原始校验和:
md5sum -c backup_file.md5
这样你能提前发现文件损坏。
损坏备份恢复案例
来看几个真实案例。
案例 1. 文件传输出错
你用 FTP 传备份,结果发现文件比预期小。你用的是 pg_dump 的文本格式,所以:
- 用编辑器打开文件。
- 删掉损坏的数据部分。
- 用
psql恢复剩下的内容。
案例 2. WAL 部分丢失
你的服务器用的是增量备份和归档 WAL 文件。突然有些文件丢了。但你还是用 pg_basebackup 和剩下的 WAL 文件恢复了数据,在恢复配置里指定了 WAL 路径。
记住,备份不仅要做,还要测。别等到世界末日才发现备份没用。如果备份真坏了,也别慌:PostgreSQL 有很多办法帮你把数据找回来。关键是要快、要细心!
如果实在没救——再回头看看本讲第一条吧。
GO TO FULL VERSION