当您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
可以帮助解决更困难的情况。