Postgres:如何清除交易ID以实现匿名和数据减少



我们正在运行一个评估平台,用户可以在该平台上对某些事情发表评论。一个关键的特点是人们只能评论一次,而且每条评论都是匿名的。

我们所有的数据都使用Postgres。我们想在数据库中保存一个标志,用户创建了一个评论(这样他们就不能再评论了(。在一个单独的表中,但在同一事务中,我们希望保存注释本身,而不需要任何指向用户的链接。

但是,postgres保存插入数据库的每个元组的事务ID(系统列的xmin(。所以现在用户和他们的评论之间有一个链接,我们必须避免!

可能的(非(解决方案

  • 单独抽真空没有帮助,因为它不能清除事务ID。请参阅"24.1.5"中的"注意"框。postgres docs.中的"防止事务ID包装失败"部分

  • 将这些插入放入不同的事务中并不能真正解决任何问题,因为事务ID是连续的。

  • 我们可以用一些分隔符将多个用户的评论聚合到数据库中的一个大文本中,但由于这个大文本的旧版本至少会被postgres保留到下一个真空,这似乎不是一个完整的解决方案。此外,我们仍然有用户添加评论的顺序,如果不保存也很好。

  • 定期重写这些表中的所有元组(通过对所有元组进行伪UPDATE(,然后进行真空操作,可能会充分擦除"插入历史",但这似乎也是一个粗糙的破解。

postgres中是否有其他方法使其无法重建表的插入历史?

也许您可以使用类似dblinkpostgres_fdw的东西来使用远程连接(到当前数据库或另一个数据库(写入表,从而分离xmin值,即使您作为用户认为这一切都是在"同一事务"中完成的。

关于通过逆向工程顺序xmin值进行跟踪的问题,由于dblink是异步的,当许多用户同时向系统添加注释时,这个问题可能会变得毫无意义。如果您需要在遇到错误后回滚,这可能不起作用——这实际上取决于将操作限制在一个事务中的重要性。

我认为没有问题。

在你的评论中,你写道,你为用户保留了一个标志(无论你存储的是什么(,用来跟踪用户对哪个帖子发表了评论。要保持这些信息的隐私,你必须保持该标志的隐私,这样除了用户自己之外,没有人可以阅读它。

如果没有其他用户可以看到该信息,则没有其他用户能够看到相应表条目上的xmin。然后没有人可以在评论上与xmin进行关联,所以问题不存在。

困难的部分是你想如何保持用户评论的信息隐私。我看到两种方法:

  1. 不要使用数据库技术,而是编写应用程序,以便向用户隐藏这些信息。

  2. 使用PostgreSQL行级安全性来做到这一点。

您无法向超级用户保留信息。甚至不要尝试。

您可以将用户及其标志和注释存储在不同的数据库集群上(并使用分布式事务(,那么xmins将是不相关的。

确保禁用track_commit_timestamp

为了使数据库中的事务无法关联,您可以发布随机

SELECT txid_current();

其除了增加事务计数器之外什么也不做。

最新更新