【问题标题】:postmortem deadlock debugging in PostgreSQLPostgreSQL 中的事后死锁调试
【发布时间】:2015-04-09 07:13:10
【问题描述】:

我想收集有关 PostgreSQL 死锁中“赢家”事务和“输家”事务的事后调试信息。

  • 我找到了this wiki 页面,其中包含一些很好的实时视图,可以提示当前出了什么问题,但如果我理解正确,那么当失败的交易已经被滚动时大部分最有用的信息已经从这些实时视图中删除。
  • 我看到了诸如deadlock_timeoutlog_lock_waits 之类的选项,它们记录了有关失败交易的信息,但特别是没有记录获胜交易的信息。似乎没有任何方法可以自定义生成的日志输出以包含比这更详细的信息(值得注意的是,当我在事后基于日志进行调试时,这些整数都没有任何意义): LOG: process 11367 still waiting for ShareLock on transaction 717 after 1000.108 ms DETAIL: Process holding the lock: 11366. Wait queue: 11367. CONTEXT: while updating tuple (0,2) in relation "foo" STATEMENT: UPDATE foo SET value = 3;

我可以使用更好的数据源来收集这些信息吗?

【问题讨论】:

  • 最简单的事情是简单地记录关于每个事务的所有,并在事后挖掘竞争过程的历史。这是一个选择吗?
  • 现在我想起来了,当你点击deadlock_timeout 时,所有涉及的进程都应该触发log_lock_waits。您缺少什么信息?

标签: postgresql transactions database-deadlocks


【解决方案1】:

首先,粘贴到问题中的跟踪不是死锁跟踪,而是关于资源锁定的警告,这些锁定已经足够长(超过deadlock_timeout)不可用。这不是错误,也不会中止事务,而死锁对事务来说是致命的。

我想收集有关两者的事后调试信息 PostgreSQL 中的“赢家”交易和“输家”交易 死锁。

它们与终止的查询一起在服务器日志中。

作为一个例子,对于这个问题中提到的情况,这是一个带有log_line_prefix = '%t [%p] ' 的死锁跟踪:postgres deadlock without explicit locking

2015-04-09 15:16:42 CEST [21689] 错误:检测到死锁 2015-04-09 15:16:42 CEST [21689] 详细信息:进程 21689 等待事务 1866436 上的 ShareLock;被进程 21028 阻止。 进程 21028 等待事务 1866435 上的 ShareLock;被进程 21689 阻止。 过程 21689:插入 b 值(1); 过程21028:插入值(1); 2015-04-09 15:16:42 CEST [21689] 提示:有关查询详细信息,请参阅服务器日志。 2015-04-09 15:16:42 CEST [21689] 声明:插入 b 值(1);

“宽松者”是 PID 21689 作为错误的产生者。 “赢家”是 PID 21028,因为它只是另一个。

如果从客户端的角度来看它,它会收到以下消息:

错误:检测到死锁 详细信息:进程 21689 等待事务 1866436 上的 ShareLock;被进程 21028 阻止。 进程 21028 等待事务 1866435 上的 ShareLock;被进程 21689 阻止。 提示:有关查询详细信息,请参阅服务器日志。

没有提及查询,但那是客户刚刚发送的查询。没有提到更宽松的,但它是一个得到这个错误的,另一个不需要注意任何东西。

【讨论】:

  • 谢谢,这肯定回答了我关于死锁的问题。对于相关类别的问题是否有任何类似的策略(即当您具有隔离级别 = REPEATABLE READ 或 SERIALIZABLE 时的序列化问题)?
  • 没有类似的,但你会感兴趣阅读wiki.postgresql.org/wiki/SSI
猜你喜欢
  • 2021-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-06
  • 2012-09-17
  • 1970-01-01
相关资源
最近更新 更多