我遇到了postgresql-9.2
数据库的问题,这导致了整个数据库系统的死锁。
基本上我有一个充当操作队列的表。将条目添加到表中以指示需要执行操作。随后,多个服务中的一个将更新这些条目以指示操作已被拾取以进行处理,并最终删除该条目以指示操作已完成。
对表的所有访问都是通过首先获取事务性建议锁的事务。这是为了确保在任何时间点只有一个服务正在操作队列。
我见过这样的实例,这个队列上的查询基本上会锁定并且什么都不做。我可以从pg_stat_activity
看到受影响的查询是state = active
,waiting = false
。我还可以看到已授予PID
中pg_locks
的所有请求锁定。但这个过程只是坐在那里,什么都不做。
通常我可以通过重复批量添加和删除(数十万)条目到队列来解决这个问题。所有访问都必须通过咨询锁,因此一次只能做一件事。
一旦其中一个查询被锁定,其他查询就会堆积在其后面,等待咨询锁定 - 最终耗尽所有数据库连接。
锁定的查询通常是删除队列中的所有条目(从queue_table;
删除)。但是,我看到一个实例,其中锁定的查询是表中几个元组的更新。
现在,我没有看到任何可能与任何其他交易陷入僵局的地方。这些是简单的插入,删除和更新。不涉及其他表(在添加从其他表中选择数据的条目期间接受)。
其他相关事实:
所有对表的访问实际上都是通过视图进行的(不能直接访问表,这就是为什么我使用咨询锁而不是桌面上的独占锁等)。
记录表(在这种情况下,这可能是一个非常糟糕的选择,我将在下周尝试使用未记录的表)。
我通常也会看到一个autovacuum(analyze)操作,同样处于活动状态,wait = false并且显然也被锁定了。我认为在我的质量增加/清除之后,autovacuum正在进行重新优化。
在我下次重现时,寻找有关我可能会考虑调试此问题的任何建议。我有点开始觉得这可能是某种与性能优化/数据库配置相关的问题。
任何有待观察的建议都会受到欢迎!