PostgreSQL ALTER TABLE显式锁定没有按预期工作

时间:2016-07-07 09:08:51

标签: postgresql

我试图在没有完全访问锁定的巨大桌子上执行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

1 个答案:

答案 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锁。