【问题标题】:Postgres SET UNLOGGED takes a long timePostgres SET UNLOGGED 需要很长时间
【发布时间】:2017-06-20 00:03:50
【问题描述】:

运行 Postgres-9.5。我有一张大桌子,我正在做ALTER TABLE table SET UNLOGGED。我已经删除了所有针对该表的外键约束,因为无法取消记录 FK 引用的表。查询耗时约 20 分钟,整个过程消耗了 100% 的 CPU。我可以理解记录表格需要很长时间,但不记录表格似乎并不困难......但是是吗?

我有什么办法可以更快地设置未记录的表吗?

【问题讨论】:

  • 也许它正在等待锁定? wiki.postgresql.org/wiki/Lock_Monitoring
  • 我通过每隔几秒查询一次pg_stat_activity 来监控它,但没有看到waiting 列设置为true,而且我看到CPU 使用率一直很高,这表明它没有等待。另外,我知道根本没有其他查询在运行,因为它位于一个独立的测试数据库中。
  • @NickBarnes 啊,这就是解决方案。对我来说,设置 unlogged 需要重写似乎很奇怪,但我真的不知道 Postgres 在后台是如何工作的。
  • 啊。在这种情况下,使用我的特定硬件,我可以更快地创建一个新的未记录表并使用多个进程将数据移动到其中(我的磁盘+缓存足够快,不会成为瓶颈)。谢谢。
  • @Nick:我认为您的 cmets 中有足够的内容可以将其作为可接受的答案。

标签: postgresql alter-table postgresql-9.5


【解决方案1】:

SET UNLOGGED 涉及表重写,因此对于大表,您可以预期它需要相当长的时间。

正如你所说,制作一张桌子UNLOGGED 似乎没有那么困难。并且简单地转换表格并没有那么困难;复杂的因素是需要使其具有碰撞安全性。 UNLOGGED 表有一个与之关联的附加文件(init fork),无法将此文件的创建与提交的其余部分同步。

因此,SET UNLOGGED 构建了一个表的副本,并附加了一个 init fork,然后换入新的relfilenode,提交可以原子地处理它。一个更有效的实现是可能的,但不是不改变未记录表的表示(早于SET UNLOGGED 很长一段时间)或COMMIT 本身背后的逻辑,对于这个相对较小的功能来说,这两者都被认为过于侵入。您可以在pgsql-hackers list 上阅读设计背后的讨论。

如果您确实需要最大程度地减少停机时间,您可以采用与SET UNLOGGED 类似的方法:创建一个新的UNLOGGED 表,复制所有记录,在同步最后一个时短暂锁定旧表进行一些更改,并在完成后将新表替换为 RENAME

【讨论】:

    猜你喜欢
    • 2021-02-27
    • 2011-12-26
    • 2013-09-07
    • 2020-08-26
    • 2014-10-09
    • 2012-11-26
    • 2019-12-27
    • 2017-10-22
    • 2020-11-15
    相关资源
    最近更新 更多