当您ALTER TABLE在PostgreSQL中发出时,它将获得一个ACCESS EXCLUSIVE锁,该锁将阻止所有内容,包括SELECT。然而,这种锁可以非常简短,如果表不需要重新编写,没有新的UNIQUE,CHECK或FOREIGN KEY限制需要昂贵的全表扫描,验证等。
如有疑问,通常可以尝试一下!PostgreSQL中的所有DDL都是事务性的,因此ALTER TABLE如果花费太长的时间取消并开始保留其他查询,则可以取消。锁定页面中记录了各种命令所需的锁定级别。
可以加快某些通常较慢的操作的安全性,而无需停机。例如,如果你有表t,你想更改列customercode integer NOT NULL到text因为客户已经决定所有的客户代码必须现在有开始X,你可以写:
ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );
...但这将锁定整个表以进行重新写入。添加带有的列也是如此DEFAULT。可以通过几个步骤来完成此操作,以避免长时间锁定,但是应用程序必须能够应对临时复制:
ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;
这只会防止写入到t在该过程; 锁的名称EXCLUSIVE是在一定程度上欺骗它排除一切除了SELECT ; 该ACCESS EXCLUSIVE模式是唯一不包含绝对内容的模式。请参阅锁定模式。由于要求进行锁升级,因此存在操作可能死锁回滚的风险ALTER TABLE,但是在最坏的情况下,您只需要重新执行一次即可。
你甚至可以避开锁,并通过创建触发器功能做全活的东西t,只要一个INSERT或UPDATE到来时,会自动填充customercode_new从customercode。
还有一些内置工具,例如CREATE INDEX CONCURRENTLY和,它们ALTER TABLE ... ADD table_constraint_using_index旨在允许DBA通过以并发友好的方式更慢地进行工作来减少排他锁定时间。
该pg_reorg工具或其后继工具pg_repack也可以用于某些表重组操作。
pg_reorg可以帮助解决更困难的情况。