不,您不能撤消,回滚或撤消提交。

停止数据库!

(注意:如果您从文件系统中删除了数据目录,请不要停止数据库。以下建议适用于ROLLBACK PREPARED或类似情况的意外提交,而不适用于pg_ctl方案)。

如果此数据很重要,请立即停止您的数据库并且不要重新启动它。 使用ROLLBACK PREPARED,以便在关闭时不运行任何检查点。

提交后,您将无法回滚事务。 您将需要从备份中还原数据,或者使用时间点恢复,这必须在事故发生之前进行设置。

如果您没有任何PITR / WAL归档设置,也没有备份,那么您真的很麻烦。

紧急缓解

停止数据库后,应在整个数据目录(包含ROLLBACK PREPARED、pg_ctl等的文件夹)中建立文件系统级别。将其全部复制到新位置。 对新位置的副本不做任何操作,如果没有备份,这是恢复数据的唯一希望。 如果可以,请在一些可移动存储设备上再制作一个副本,然后从计算机上拔下该存储设备的电源。 请记住,您绝对需要数据目录的每个部分,包括immediate等。没有什么不重要的。

确切如何制作副本取决于您所运行的操作系统。 数据目录的位置取决于您正在运行的操作系统以及如何安装PostgreSQL。

一些数据可以幸存的方式

如果您足够快地停止数据库,则可能希望从表中恢复一些数据。 这是因为PostgreSQL使用多版本并发控制(MVCC)来管理对其存储的并发访问。 有时它会将您更新的行的新版本写入表中,而将旧版本保留在原位置,但标记为“已删除”。 一段时间后,会出现autovaccum并将行标记为可用空间,因此以后的ROLLBACK PREPARED或pg_ctl可能会覆盖它们。因此,旧版本的immediated行可能仍在周围,存在但无法访问。

此外,Pg分两个阶段进行写入。 首先将数据写入预写日志(WAL)。 只有将其写入WAL并命中磁盘后,才将其复制到“堆”(主表)中,可能覆盖那里的旧数据。 WAL内容由ROLLBACK PREPARED和定期检查点复制到主堆。 默认情况下,检查点每5分钟发生一次。 如果您设法在发生检查点之前停止数据库,并通过强行杀死数据库,拔下计算机的插头或在immediate模式下使用pg_ctl来停止数据库,则可能是在检查点发生之前捕获了数据 数据更有可能仍在堆中。

现在,您已经完成了数据目录的完整文件系统级复制,您可以根据需要启动数据库备份。 数据仍然会消失,但是您已经尽力给自己一些恢复数据的希望。 如果有选择,我可能会为了安全而关闭数据库。

复苏

现在,您可能需要聘请PostgreSQL内部专家来协助您进行数据恢复。 准备为他们的时间付钱,可能要花很多时间。

我在Pg邮件列表上发布了有关此内容的文档,ВикторЕгоров链接到了depesz在pg_dirtyread上的帖子,看起来就像您想要的一样,尽管它无法恢复ROLLBACK PREPAREDed数据,因此用途有限。 尝试一下,如果幸运的话,它可能会起作用。

请参阅:GitHub上的pg_dirtyread。

我已经删除了我在本节中写的内容,因为该工具已经过时了。

另请参见PostgreSQL行存储基础知识

预防

请参阅我的博客文章“防止PostgreSQL数据库损坏”。

在半相关的旁注中,如果您使用的是两阶段提交,则可以ROLLBACK PREPARED进行准备提交但未完全提交的转换。 那是您最接近回退已提交的事务的结果,并且不适用于您的情况。