PostgreSQL 中的事后死锁调试

Dan*_*Dan 6 postgresql transactions database-deadlocks

我想收集有关 PostgreSQL 死锁中“获胜者”事务和“失败者”事务的事后调试信息。

  • 我发现这个维基页面包含一些很好的实时视图,可以提示当前出现的问题,但如果我理解正确的话,当丢失的事务已经回滚时,大多数最有用的信息将已经被删除从这些实时视图中。
  • 我看到了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;

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

Dan*_*ité 5

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

我想收集有关 PostgreSQL 死锁中“获胜者”事务和“失败者”事务的事后调试信息。

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

作为一个例子,这里有一个死锁跟踪,用于log_line_prefix = '%t [%p] '这个问题中提到的情况:postgres deadlock withoutexplicitlocking

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:插入bvalues(1);
    进程21028:插入values(1);
2015-04-09 15:16:42 CEST [21689] 提示:请参阅服务器日志以获取查询详细信息。
2015-04-09 15:16:42 CEST [21689] 声明:插入 b 值(1);

“松散”的是21689作为错误产生者的PID。“胜利者”是 PID 21028,因为它是另一个。

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

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

没有提及查询,但这是客户端刚刚发送的查询。没有提到松散的,但它是出现此错误的一个,另一个不必注意到任何事情。