找出删除和更新的行
Posted
技术标签:
【中文标题】找出删除和更新的行【英文标题】:Find Out What Rows Where Deleted And Updated 【发布时间】:2014-07-22 08:30:48 【问题描述】:是否有可能以某种方式找出从表中删除的行的主键?
同样,是否可以找出表中更新行的主键?
让我们考虑一个简单的用例:
我有两个时间戳:
开始 结束给我这两个时间戳之间更新/删除的所有行的主键。
表格内没有任何信息表明它们已更新。
【问题讨论】:
主键的可能值是多少?如果这些是连续的,那么您可以编写查询以查找从头到尾丢失的主键,结果输出是被删除的行。 Postgres 不存储有关表活动的信息,最好的方法是自己创建一个触发器来更新表上的一行以进行更新,或者只是将信息写入另一个位置更新或删除。 【参考方案1】:不,PostgreSQL 不提供类似的内置功能。
为此,它必须浪费空间和 I/O 来跟踪大多数人永远不需要的东西。
如果您的主键是连续且单调的,那么您只需对generate_series
进行左反连接即可找到漏洞。但是,如果您使用 serial
(即序列)来生成密钥,这将不起作用,因为任何回滚都会产生间隙,即使实际上没有插入任何内容以便随后被删除。
您需要添加一个审核触发器,以将您要跟踪的操作记录到单独的审核表中。您不能追溯执行此操作;您无法审核过去的事情。这是迄今为止最简单的选择。
另一种常见的解决方案是在应用程序级别将行标记为“已删除”,而不是从表中实际删除它们。例如,您可以在表中设置deleted_at
和deleted_by
字段。您甚至可以使用带有ON INSERT OR UPDATE OR DELETE DO INSTEAD
触发器的视图使此应用程序透明。
还有一个 pg_audit
扩展正在开发中以使这更容易,但它还没有准备好。
半相关旁注:在 PostgreSQL 9.5 中,我认为这对于 最近 删除的行实际上是可能的,在 VACUUM
使用 C 清理它们之前延期。 9.5 将能够记录提交的时间戳,而 9.4 及更低版本则不能(它们只记录事务 ID)。因此,您可以通过检查 xmax
来找出哪个事务 ID 删除了一行,并从那里确定它被删除的时间戳。您需要一个 C 扩展,因为您必须对表进行“脏读”。
【讨论】:
“如果你的主键是连续的且单调的,那么你可以在 generate_series 上做一个左反连接”对我有用。我的用例是确定源数据库表中删除了哪些行,以便我可以删除目标数据库表中的相应记录。对于我的用例,这两个表必须是不同的数据库,并且目标数据库表中的行都具有对源数据库表行 ID 的反向引用。在这个用例中,如果我每次都获得一些额外的 ID 并不重要,因为替代方法是将所有剩余的源 ID 放入内存。谢谢!!! :-)【参考方案2】:使用Netezza
,不仅可以提取主键,还可以提取所有已删除的数据。
首先运行一个命令来暴露被删除的记录set show_deleted_records=true;
然后查询数据库。
Select deletexid,*
from table_name
where deletexid>0
这个技巧对于恢复错误很有用。请注意,在reclaim
或groom
之后不再保留已删除的记录。
【讨论】:
以上是关于找出删除和更新的行的主要内容,如果未能解决你的问题,请参考以下文章