【问题标题】:postgres deadlock without explicit locking没有显式锁定的postgres死锁
【发布时间】:2013-04-16 17:06:41
【问题描述】:

我使用的是 PostgreSQL 9.2,我没有在任何地方使用显式锁定,既不是 LOCK 语句也不是 SELECT ... FOR UPDATE。但是,最近我收到了ERROR: 40P01: deadlock detected。但是,检测到死锁的查询被包装在事务块中。无论如何,这是怎么回事?

【问题讨论】:

  • 您能否显示发生死锁的位置的缩减查询/模式?您的交易中是否使用了哈希索引?

标签: postgresql transactions database-deadlocks


【解决方案1】:

您不需要任何明确的LOCK 即可进入死锁。这是一个从头开始的非常简单的演示,只有 INSERT:

create table a(i int primary key);
create table b(i int primary key);

第 1 次会议:

begin;
insert into a values(1);

然后会话 #2 会:

begin;
insert into b values(1);
insert into a values(1);
-- here it goes into waiting for session #1 to finish its transaction

然后会话 #1 会:

insert into b values(1);

然后发生死锁:

错误:检测到死锁
详细信息:进程 9571 等待 ShareLock 开启 交易4150;被进程 9501 阻止。
进程 9501 等待 交易 4149 上的 ShareLock;被进程 9571 阻止。
提示:见 查询详情的服务器日志。

简单的 UPDATE 或 UPDATE 和 INSERT 的组合也会发生同样的情况。 这些操作采用隐式锁,如果它们在不同的会话中以不同的顺序发生,它们可能会死锁。

【讨论】:

    【解决方案2】:

    我会首先怀疑哈希索引。

    • 将任何hash-indexes 切换为B-tree
    • 如果合适,请使用Serializable 隔离级别。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 2018-03-04
    • 2020-03-19
    • 1970-01-01
    相关资源
    最近更新 更多