从正在运行的 PostgreSQL 实例中“恢复”数据;数据目录被删除

1 postgresql postgresql-9.1

我不小心/var/lib/pgsql/9.1/data从运行 postgresql 服务器中删除了数据目录。

我想当服务器重新启动时我会丢失我的数据。

我想知道 postgresql 是否有任何工具可以从正在运行的服务器实例中恢复数据,或者我必须使用系统数据恢复工具?

小智 6

恐怕你的机会在无穷小和零之间。

该目录及其子目录中有很多文件。任何在您删除目录时由 postgresql 后端进程之一实际打开的并且此后尚未关闭的文件仍然存在于文件系统中,但任何不存在的都早已消失。因此,您所能希望的最好方法是恢复某些文件,并且数据库不太可能在丢失文件的情况下正常启动。

假设是 Linux 系统,您可以使用以下命令查看哪些文件实际上是打开的(因此理论上至少仍然可以恢复):

lsof -u postgres | grep /var/lib/pgsql
Run Code Online (Sandbox Code Playgroud)

您将看到以下条目:

postmaste 2418 postgres 5u REG  253,0 8192 274804 /var/lib/pgsql/9.2/data/global/5445770
Run Code Online (Sandbox Code Playgroud)

第二列是进程的PID,第四列的数字部分是FD(文件描述符)编号。可以使用如下命令恢复该文件:

cp /proc/{PID}/fd/{FD} {dest_file}
Run Code Online (Sandbox Code Playgroud)

根据需要替换 {PID}、{FD} 和 {dest_file}。

但是,正如我所说,您恢复所有丢失文件的机会,甚至是恢复足够的文件以便之后能够再次启动数据库的机会非常渺茫。即使是您确实恢复的那些也可能已损坏,因为打开它们的另一个进程将同时写入它们。

相反,可能值得尝试 pg_dump。可能无法转储整个数据库,但如果幸运的话,您可能会以这种方式恢复其中的一些。如果有些表对您来说比其他表更重要,并且运行中的数据库似乎仍然能够访问它们,那么您可以尝试使用 pg_dump 仅转储这些表。

您有可能(但我认为不太可能)使用系统文件恢复工具恢复底层文件。