我想将列更改为NOT NULL:
ALTER TABLE "foos" ALTER "bar_id" SET NOT NULL
" foos"表有近1 000 000条记录。它的写入量相当低,但却不断。有很多阅读。
根据我的经验,将大表中的列更改为NOT NULL会导致应用程序停机,这可能是因为它会导致(b)锁定。
但是,我还没有找到证实这一点的好解释。如果确实如此,我该怎么办才能避免它?
编辑:The docs(通过this comment)说:
添加带有DEFAULT子句的列或更改现有列的类型将需要重写整个表及其索引。
我不确定更改NULL是否计为&#34;更改现有列的类型&#34;,但我相信我上次看到此问题时确实在列上有索引。< / p>
也许删除索引,使列NOT NULL,然后再添加索引会改善一些事情吗?
答案 0 :(得分:4)
我认为你可以使用检查约束而不是set not null
来做到这一点。
ALTER TABLE foos
add constraint id_not_null check (bar_id is not null) not valid;
这仍然需要桌面上的ACCESS EXCLUSIVE锁,但它非常快,因为Postgres没有验证约束(因此它不必扫描整个表)。这将确保新行(或更改的行)不能将空值放入该列
然后(在提交alter table
之后!)你可以这样做:
alter table foos validate constraint id_not_null;
不哪个需要ACCESS EXCLUSIVE锁,但仍然允许访问该表。