如何在生产型PostgreSQL上零宕机的情况下,在表中添加一列?

问题描述 投票:0回答:1

下面是 https:/stackoverflow.coma5301619310894456。是为Oracle 11g提供的答案,我的问题也是一样。

在生产的oracle数据库中,当一个表包含100万条记录并且是实时的时候,添加一个具有默认值的非空列的最佳方法是什么?如果我们在一条语句中创建列,添加默认值并将其设为非空,是否会产生任何锁?

但对于PostgreSQL来说呢?

postgresql production-environment alter-table downtime
1个回答
2
投票

此前的回答 基本上回答了你的疑问。

交叉引用 相关PostgreSQL文档 与PostgreSQL源码的 AlterTableGetLockLevel 上述答案中提到的,说明 ALTER TABLE ... ADD COLUMN 将永远获得 ACCESS EXCLUSIVE 表锁,阻止任何其他事务在该表的 ADD COLUMN 这个相同的独占锁可以在任何一个 ADD COLUMN 变化;即无论你是否添加了一个。NULL 栏目 DEFAULT)或有 NOT NULL 含有一个默认值。

然而,正如上面链接的答案中提到的,在一个默认的情况下,添加一个 NULL 栏目,没有 DEFAULT 应该是非常快的,因为这个操作只是更新目录。

与此相反,添加一个带有 DEFAULT 根据链接的答案,PostgreSQL >= 11不需要重写这样的列,所以应该更类似于不需要重写。DEFAULT 的情况。

我需要补充的是,对于PostgreSQL 11及以上的版本来说,在PostgreSQL 11中的 ALTER TABLE 文件 注意,只有在非易失性的情况下,才会避免表的重写。DEFAULT 指定符。

当使用ADD COLUMN添加一列并指定一个非易失性的DEFAULT时,默认值将在声明时进行评估,结果存储在表的元数据中。该值将被用于所有现有行的列。如果没有指定DEFAULT,则使用NULL。在这两种情况下,都不需要重写表。

添加一个具有易失性DEFAULT的列[...]将需要重写整个表和它的索引。[...]对于一个大表来说,表和或索引的重写可能需要大量的时间;并且会暂时需要多达一倍的磁盘空间。

© www.soinside.com 2019 - 2024. All rights reserved.