我试图在没有完全访问锁定的巨大桌子上执行ALTER TABLE。 根据ALTER TABLE文档:
除非明确注明
,否则将保持ACCESS EXCLUSIVE锁定
因此我做了以下事情:
BEGIN;
LOCK TABLE MyTable IN SHARE MODE;
ALTER TABLE MyTable ALTER COLUMN size SET DATA TYPE BIGINT;
COMMIT;
我希望它能让我在升级过程中执行SELECT查询。 但事实上它并没有。在交易过程中查看 pg_locks ,我发现:
SELECT c.relname, l.mode, l.granted, l.pid
FROM pg_locks as l JOIN pg_class as c on c.oid = l.relation
WHERE relname='MyTable' AND granted IS TRUE;
relname | mode | granted | pid
----------+---------------------+---------+------
MyTable | ShareLock | t | 2277
MyTable | AccessExclusiveLock | t | 2277
所以 AccessExclusiveLock 意外地被采用了,它解释了为什么我的SELECT挂起直到交易结束
我使用PostgreSQL 9.4
答案 0 :(得分:1)
除非明确指出位,否则您似乎会错误解释。
这意味着,鉴于在ALTER TABLE
下分组的行动不同,对于其中一些行为而言,弱于ACCESS EXCLUSIVE
的锁定可能就足够了,而且当它为&#39时在这种情况下,它在文档中明确指出。
例如(来自 https://www.postgresql.org/docs/9.5/static/sql-altertable.html):
SET STATISTICS获取SHARE UPDATE EXCLUSIVE锁。
...
更改每个属性选项会获得SHARE UPDATE EXCLUSIVE锁。
...
验证仅在被更改的表上获取SHARE UPDATE EXCLUSIVE锁。如果约束是外键,则约束
引用的表上也需要ROW SHARE锁
这并不意味着需要ACCESS EXCLUSIVE
锁定的操作(例如更改列的类型)可能会受到同一事务中表中抓取的先前显式弱锁的影响。无论如何,他们都需要ACCESS EXCLUSIVE
锁。