如何找出何时将数据插入Postgres?

Ond*_*rae 12 postgresql database-metadata

我继承了一个充满数据的现有Postgres数据库.大多数数据都有'created_date'列值.在跟踪之前插入了一些早期数据.

有一个Postgres元数据表隐藏在跟踪INSERT查询完成时的某个地方吗?

Erw*_*ter 18

除非你自己录制,否则PostgreSQL中没有这样的元数据 - 直到Postgres 9.4.

您可以从行标题(HeapTupleHeaderData)中推断出某些信息,特别是从插入事务ID中.它包含插入行的事务的ID(需要决定PostgreSQL的MVCC模型中的可见性).尝试(对于任何表):track_commit_timestamp

SELECT xmin, * FROM tbl LIMIT 10;
Run Code Online (Sandbox Code Playgroud)

一些限制适用:

  • 如果数据库被转储和恢复,那么显然,信息已经消失 - 所有行都插入到同一个事务中.
  • 如果数据库是巨大的/非常老的/非常大的写入,那么它可能已经通过事务ID环绕,并且数字的顺序postgresql.conf是不明确的.

但对于大多数数据库,您应该能够推导出:

  • INSERT的时间顺序
  • 哪些行插在一起
  • 什么时候插入之间有很长一段时间

但是没有时间戳.

Postgres 9.5或更高版本

您可以启用xminxmin(重启)开始跟踪提交时间戳.然后你可以得到你的时间戳xmin.相关回答:


Cha*_*ack 6

根据 Erwin Brandstetter 的答案,如果您有 PostgreSQL 9.5 或更高版本,提交的时间戳将始终记录在预写日志中,即使track_commit_timestamp已关闭。它们被记录在那里以支持时间点恢复,您可以将数据库滚动到可以指定为日期和时间的确切过去状态。

通过打开,您track_commit_timestamp可以更轻松地检索该信息,您可以简单地使用以下命令进行查询

SELECT pg_xact_commit_timestamp(xid);
Run Code Online (Sandbox Code Playgroud)

其中xidxmin您关心的行中的,它为您提供时间戳。

这很方便,但只有在以下情况下才有效:

  • track_commit_timestamp已开启
  • 事务提交时亮起
  • 交易 ID 的过去还不足以被“冻结”。

(PostgreSQL 通过最终“冻结”旧事务 ID 来控制永远记住事务 ID 的开销。这还控制track_commit_timestamp依赖函数可以回溯的程度。还有另一个设置 ,vacuum_freeze_max_age用于调整它。)

那么,如果您需要开机前发生的事务的时间戳,该怎么办track_commit_timestamp

只要发生在 PG 9.5 或更高版本中,时间戳就在预写日志中。如果您一直保留足以进行时间点恢复的备份,那么这为您提供了一种找到答案的粗略方法:您可以在您认为发生之前恢复基本备份,在您附近设置一个恢复“暂停”目标时间戳猜测它发生了,当它暂停时连接并查询它是否发生了。如果没有,请设置稍晚的目标,让恢复继续,然后再次检查。这一切都可以使用另一个 PostgreSQL 实例中的备份来完成,以避免干扰正在运行的生产。

这是一个足够笨拙的过程,您可能希望您可以回到过去并告诉以前的自己打开track_commit_timestamp,这样当您感兴趣的事务发生时它就会打开。您可以track_commit_timestamp在启动服务器之前打开从备份中恢复,但这并不能完全解决问题:如果在备份时关闭它,它只会在恢复的事务之后开始保存新事务的时间戳。

事实证明,可以欺骗 PostgreSQL 使其认为track_commit_timestamp 开启,然后在恢复中启动服务器,这达到了预期的效果:当它重播预写日志中的事务时,它确实会记住它们的时间戳,并且您可以然后使用pg_xact_commit_timestamp()来查询它们。它不会包含基本备份中任何内容的时间戳,而仅包含基本备份之后并从 WAL 重播的事务。尽管如此,通过选择已知早于所需事务的基础备份,这允许恢复时间戳。

没有官方工具/选项可以track_commit_timestamp以这种方式“追溯”设置,但(繁琐且不受支持的)概念验证已在 上pgsql-hackers进行了讨论。