有什么方法可以恢复或重新创建意外删除的 pg_filenode.map 文件?或者有什么解决方案可以在不影响数据库的情况下解决这个问题?非常感谢任何解决此问题的建议!我们拥有的 postgres 版本是在 Redhat Linux 5 中运行的 9.0。谢谢!
2 回答
立即停止尝试修复任何事情。你所做的一切都有可能使情况变得更糟。
将此视为严重的数据库损坏。阅读这篇 wiki 文章并采取行动。
只有在您听从了它的建议后,您才应该考虑尝试修复或恢复。
如果您可能希望恢复已删除的文件(如果它尚未被覆盖),您还应该停止整个服务器机器或卸载 PostgreSQL 所在的文件系统并对其进行磁盘映像。
如果此数据对您很重要,我建议您联系专业支持。这将花费您,但可能是在像这样的严重管理员错误之后取回数据的最佳机会。请参阅PostgreSQL 专业支持。(免责声明:我在我的 SO 简介中显示的一家上市公司工作)。
您可以pg_filenode.map
使用从磁盘表中提取的有关表结构和内容的信息手动重建。不过,这可能是一项艰巨的工作。
首先,如果这是紧急且有价值的,我强烈建议您首先联系专业支持。但是,如果您可以在磁盘映像上工作,如果它不是时间紧迫的等等。这里有一些需要注意的重点以及如何继续(我们最近不得不恢复一个坏的 pg_filenode.map。此外,您最好在一个磁盘映像的磁盘映像。
以下是我从由于对包含目录的不完整写入而不得不恢复损坏的文件中学到的东西。 它是 PostgreSQL 10 的最新版本,但随时可能发生变化
在你开始之前
数据恢复是有风险的业务。在开始之前,请始终注意恢复对您的组织意味着什么、可以容忍的数据丢失、可以容忍的停机时间等。如果可以的话,制作一份副本。如果有任何不正确的地方,请回过头来评估问题所在,并确保在继续之前了解原因。
这个文件是什么以及它的作用
PostgreSQL 的标准文件节点映射存储在 pg_class 关系中,该关系由 Pg 目录中的对象 id 引用。不幸的是,您需要一种方法来引导系统表的映射,以便您可以查找此类信息。
在大多数部署中,永远不会写入此文件。它可以从相同版本的 Postgres 上的新 initdb 复制,除了数据目录之外,传递给 initdb 的选项相同。但是,这不能保证。
有几件事可以改变这个映射。如果您对系统目录执行完全真空或类似操作,这可能会更改默认映射,然后从 initdb 复制新文件将无济于事。
一些可以尝试的事情
尝试的第一件事(在副本的副本上!)是将文件替换为来自新 initdb 的文件到来自同一服务器的另一个文件系统(这可能是拇指驱动器或其他)。这可能有效。它可能不起作用。
如果失败了,那么也许可以使用 pg_filedump 和自定义脚本/C 编程来创建一个新文件,该文件基于查看数据目录中每个关系文件的数据的努力。正如上面 Craig 所说,这将是一项重要的工作。
如果你让它工作
获取数据库的新 pg_dump 并将其还原到新的 initdb 中。这样你就知道一切都是一致和完整的。