如何更改大型Postgres表的默认值而不需要永远?

时间:2011-09-13 00:16:23

标签: ruby-on-rails performance postgresql migration alter-table

在Heroku上运行的Postgres支持的Rails应用程序中,我试图添加一个布尔列,默认设置为false,null设置为false(NOT NULL)。

迁移需要花费数小时才能运行(实际上大约有15个这样的字段需要添加)。内存使用量通过屋顶(5-6gb或更多)。我认为这是因为Postgres将迁移包装在事务中并尝试将整个表加载到内存中,以便它可以在失败时回滚。

如果没有字段默认值或NOT NULL,则会立即添加列。

作为临时解决方案,我在没有任何限制的情况下添加新列,在1000个记录的批量中更新具有错误默认值的所有记录,然后最终更改列以具有默认和NOT NULL要求。 / p>

现在,迁移大约需要3-4个小时才能运行,并且只使用大约100mb的RAM。

那里有更好的解决方案吗?

2 个答案:

答案 0 :(得分:2)

从您的时间开始,我希望您通过RoR执行“升级”,这可能意味着“一次排列”处理。我刚刚在一个带有主键和3个外键的300K行表上进行了测试,并且添加了一个布尔成本大约5秒(对于我来说,太短了,无法对其进行基准测试)查询:

ALTER TABLE mine.trivally
    ADD COLUMN the_bool boolean NOT NULL DEFAULT 'True' ;

这表明您的框架会产生次优代码。至少可以说。

答案 1 :(得分:0)

结帐large-hadron-migrator。它声称是执行大规模单表迁移的方案的实现。它比迁移要复杂得多,因为它使用了几个后台表和一组触发器来完全在线或最小停机时间进行迁移。