【发布时间】:2015-08-21 16:26:20
【问题描述】:
为什么在 PostgreSQL 中删除表需要 ACCESS EXCLUSIVE 锁定任何引用的表?如何将其减少到 ACCESS SHARED 锁定或根本没有锁定?即有没有办法在不锁定引用表的情况下删除关系?
我在文档中找不到任何关于需要哪些锁的信息,但除非我在并发操作期间删除多个表时以正确的顺序明确获取锁,否则我可以在日志中看到等待 AccessExclusiveLock 的死锁,并且在常用表上获取这种限制性锁定会在删除表时导致其他进程暂时延迟。
为了澄清,
CREATE TABLE base (
id SERIAL,
PRIMARY KEY (id)
);
CREATE TABLE main (
id SERIAL,
base_id INT,
PRIMARY KEY (id),
CONSTRAINT fk_main_base (base_id)
REFERENCES base (id)
ON DELETE CASCADE ON UPDATE CASCADE
);
DROP TABLE main; -- why does this need to lock base?
【问题讨论】:
-
您希望发生什么?您正试图从一家繁忙的餐厅搬走家具,人们还在用餐中途,他们应该支付什么费用?半顿饭?全餐?只有他们消耗的部分?
-
@wildplasser 我不明白你的类比;我不是在谈论我要删除的表上的锁,而是在它引用的表上。被引用的表不应该关心是否有删除 - 它的数据不会被操作更改。它根本不需要做任何事情。
-
@wildplasser 看我的例子
-
我明白了。我仍然不清楚为什么你想删除和(也许)重新创建表。顺便说一句:目录上的酸很难;可能是 postgres 在这里过于防守了。
-
@wildplasser 表没有被重新创建。这些表用于确保客户隔离(例如 project_1_data 等)。我们正在迁移到为此使用模式(我们可以简单地复制共享信息),但由于我们仍在从 MySQL 迁移的过程中,我们还不能做出改变。当我们归档死项目时,表格会被删除,但更重要的是在集成测试期间,我们会快速创建和销毁项目以确保其测试环境的隔离。
标签: postgresql database-deadlocks drop-table