我可以每1-2分钟运行一次PostgreSQL真空吸尘器吗?

问题描述:

我正在考虑为即将推出的项目提供各种支持MVCC的数据库,并将PostgreSQL引入我的视线。我可以每1-2分钟运行一次PostgreSQL真空吸尘器吗?

我的程序的要求,包括大致是如下顺序:

  1. 从数据库中读取当前版本的一些信息,修改数据的80%-90%,并在一个写回或更多的交易(想象在Conway的生命游戏中更新网格,需要网格的新老状态)。

  2. 等待提交后1-2分钟。在此期间,客户可以针对新数据发布读取内容。

  3. 重复。

数据库将被限制在2-4GB之类。

〜90%的变化是对现有对象的更新,〜5%将是新对象,〜5%将被删除对象。

所以我的问题是,我可以合理地每隔1-2分钟运行一次普通的VACUUM命令作为步骤1.5,并让PostgreSQL能够跟上每次可能的2-3 + GB的更改吗?

+5

您可能不需要手动运行它。调整该特定表的自动真空设置应该足够了。但是,当您删除或插入大量行时,真空是非常必要的。更新将不需要这样一个积极的真空。 – 2012-03-13 22:50:55

+0

我的理解是,每次更新都会生成一个新的XID记录,并且由于每个循环都会更新80-90%的对象,因此我期望有许多“旧”记录进行清理。 – MindJuice 2012-03-13 22:56:09

+0

也许同样重要的是要注意,在步骤1运行时,客户端也可能会从步骤“0”发出针对数据库的“旧”状态的读取,因此这些旧记录需要在新记录时可用产生。 – MindJuice 2012-03-13 22:59:18

我相信Postgres在这种情况下应该可以做得很好。这种情况非常罕见,巨大更新之间的手动真空似乎是一个合理的选择。

请考虑如果您可以让它代替巨大的更新,您将生成一组新的表,分析它们(必要的!),然后用事务性ddl删除旧的并重新命名新的一个到他们的位置。这应该可以缓解您对VACUUM的担忧。

在这种情况下,你应该做一些认真的调整。特别是,查看shared_buffers,与检查点相关的参数以及与真空有关的参数。此外,请记住关于实际工作负载的基准测试。

+0

关于在最后使用两个单独的表并重命名的有趣建议。这可能对我有用。我会仔细思考一下。谢谢! – MindJuice 2012-03-14 00:12:10

+0

要重命名表,数据库首先必须锁定表。这比更新的普通行锁要慢得多。 – 2012-03-14 07:46:16

+1

@FrankHeikens:这是一个折衷,OP想要更新几乎整个表,简单的排他锁可能比处理VACUUM和东西更容易。如果读者仅发布短期查询,情况尤其如此。或者,可以想象在客户端这么做 - 小型search_path舞蹈可能意味着“旧”读者使用旧模式中的表,新读者​​使用新模式中的表,而在后台您正在准备另一个版本。然后你放弃任何人不再使用的模式。 – maniek 2012-03-14 12:24:49