这是一篇关于 PostgreSQL 数据恢复的博客文章,主要内容如下:
- 事件背景:3 月 11 日再次出现故障,PostgreSQL 启动时出现错误,经排查是由于分区挂载和服务启动设置问题,以及未停止运行的 postgresql 守护进程导致旧的空实例覆盖了解密的数据库,默认情况下 PostgreSQL 遇到空数据目录会崩溃。
- pg_control 介绍:pg_control 是一个 8KB 的二进制文件,存储关于 PostgreSQL 内部状态的元数据,其结构在源代码中有定义,还有 pg_controldata 和 pg_resetwal 两个用于调试的实用程序。通过 pg_controldata 可以了解文件的相关信息,发现实际数据未丢失或损坏,可尝试重建元数据。
- 数据结构与 WAL:数据库数据由数据文件(堆)、Write-Ahead Log(WAL)和 pg_control 文件组成,WAL 用于在系统崩溃时保持数据库的一致性,基本思想是在对实际数据文件进行任何操作之前,将整个事务的描述刷新到 WAL 中,以确保在崩溃时能够持久保存。为了提高效率,PostgreSQL 定期发出检查点,将修改后的块内容复制到 WAL 中。WAL 还用于物理复制、增量备份和时间点恢复等。
- 修复过程:通过运行 pg_waldump 找到第一个 CHECKPOINT 行,确定其 LSN 为 404/04973878,然后根据 WAL 文件的结构和已知的良好 pg_control 版本,编写脚本生成新的 pg_control.restored 文件,替换被覆盖的 pg_control 文件,成功完成恢复。恢复过程中遇到 invalid record length at 404/4BE7FC8: wanted 24, got 0 是正常的结束方式。
- 经验教训:从备份恢复可能更合理,但此次恢复过程是很好的学习经验,也了解到 PostgreSQL 数据库底层备份的可能性,未来将改善基础设施以进行更频繁的备份。最后感谢多人帮忙校对和协助恢复。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。