2017-02-02 197 views
3

正在运行Postgres-9.5。我有一张大桌子,我正在做ALTER TABLE table SET UNLOGGED。我已经放弃了所有针对表的外键约束,因为FK引用的表不能被记录。查询花费了大约20分钟,并且一直占用100%的CPU。我可以理解,需要很长时间才能使表格被记录下来,但是使其没有记录似乎并不困难......但是这样吗?Postgres SET UNLOGGED需要很长时间

有什么我可以做的,使其更快地设置表unlogged?

+0

也许它正在等待锁? https://wiki.postgresql.org/wiki/Lock_Monitoring –

+0

我每隔几秒就通过查询'pg_stat_activity'来监控它,并且没有看到'waiting'列设置为真,另外我看到一直很高的CPU使用率,这将表明它并没有等待。另外,我知道自从它在一个独立的测试数据库以来,没有其他查询运行。 – sudo

+0

@NickBarnes啊,那就是解决方案。对我来说似乎很奇怪,设置unlogged会需要重写,但我真的不知道Postgres是如何工作的。 – sudo

回答

4

SET UNLOGGED涉及一个表重写,所以对于一个大型表,你可以期待它需要一段时间。

正如你所说,似乎并不像表UNLOGGED应该是那么困难。而简单地转换表不是那很难;这个复杂的因素是需要使其安全。 UNLOGGED表具有与其关联的附加文件(init fork),并且无法将此文件的创建与其余提交同步。

所以取而代之,SET UNLOGGED构建表的副本,其中附接一个init叉,然后在交换新relfilenode,其提交可以原子处理。更有效的实施方式将是可能的,但不是没有改变未记录表格的表示(其早于SET UNLOGGED很长一段时间)或COMMIT本身的逻辑,这两者都被认为对于这个相对次要的特征太侵入。您可以阅读pgsql-hackers list上的设计背后的讨论。

如果你真的需要最大限度地减少停机时间,你可以采取类似的方法,通过SET UNLOGGED采取:创建一个新UNLOGGED表,整个复制所有的记录,简单而您同步过去几年的变化锁定旧表,完成后将新表换成RENAME