我想我在某处看到在postgres数据库上运行ALTER TABLE foo ADD COLUMN baz text
不会导致读或写锁定。设置默认值会导致锁定,但允许空默认值会阻止锁定。
答案 0 :(得分:22)
在文档中提到了不同类型的锁以及何时使用它们
Table-level Locks。例如,Postgres 11的ALTER TABLE
可能会获得SHARE UPDATE EXCLUSIVE
,SHARE ROW EXCLUSIVE
或ACCESS EXCLUSIVE
锁定。
Postgres 9.1到9.3声称支持上述三个中的两个但实际上是forced Access Exclusive
for all variants of this command。此限制为lifted in Postgres 9.4,但 ADD COLUMN
仍设计为ACCESS EXCLUSIVE
。
检查源代码很容易,因为在各种情况下,有一个专门用于建立此命令所需锁定级别的函数:AlterTableGetLockLevel
中的src/backend/commands/tablecmds.c
。
关于锁定持续时间,一旦获得:
答案 1 :(得分:22)
添加新的空列将在非常短的时间内锁定表,因为无需重写磁盘上的所有数据。添加具有默认值的列需要PostgreSQL创建所有行的新版本并将其存储在磁盘上。在此期间,表格将被锁定。
因此,当您需要将具有默认值的列添加到大表时,建议先添加空值,然后以小部分更新所有行。这样你就可以避免磁盘上的高负载,并允许autovacuum完成它的工作,所以你最终不会使表大小加倍。
答案 2 :(得分:12)
http://www.postgresql.org/docs/current/static/sql-altertable.html#AEN57290
“添加具有非null默认值的列或更改现有列的类型将需要重写整个表和索引。”
因此,文档仅指定何时不重写表。 总会有锁,但如果不重写表,它将会很短。