给现有列添加默认值或重命名列会锁定Postgres表吗?

3
我需要在一个200万行的Postgres表上执行两个迁移操作,并需要确保每次运行的停机时间最小,即少于5秒。

这些迁移是:

1)向现有的bigint列添加默认值0,并从null更改为非空

2)重命名一个列

注意:我发现很多帖子都说在大表上添加一个具有默认值的新列会导致锁定,但没有关于向现有列添加默认值的说明。

这些操作会锁定表吗?

2个回答

8

文档详细描述了哪种ALTER TABLE变体会使用哪种锁。

SET DEFAULTSET NOT NULLRENAME COLUMN都需要使用ACCESS EXCLUSIVE锁。

这很不方便,但通常只有在ALTER TABLE语句执行时间较长时才会出现问题。 SET DEFAULTRENAME COLUMN都很快,但SET NOT NULL将必须扫描表以确定条件是否满足。


感谢Laurenz提供的添加默认值、重命名列和文档链接信息。这些帮助我向前迈进了一步。 - robodisco

6
我们知道默认值仅适用于后续的INSERT命令;它们不会导致已存在于表中的行发生更改。这意味着在将默认值设置为现有列时,表上不会有锁定。
请参考https://www.postgresql.org/docs/9.1/static/sql-altertable.html中的SET/DROP DEFAULT部分。
您也可以参考this文章了解高容量PostgreSql的安全操作。

感谢Lakhan的回复和提供有用的链接。 - robodisco
好的,表上确实会有一个锁,但只是短暂的。然而,如果表上有很多活动,ALTER TABLE 将不得不排队等待并发锁请求,并阻塞在它之后的所有语句,直到它获得锁并完成为止。如果您只有短事务,那应该不是什么大问题,但对于长事务来说就不同了。 - Laurenz Albe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接