lockingpostgres交易

我负载testing我的node.js应用程序。 在某些时候,我达到了请求正在等待的状态,我最好的猜测是因为locking的事务。 这是最后的日志声明:

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; 

pg_lock我得到了4行,上面的查询是GRANTED = truemode ExclusiveLock

我应该从哪里开始寻找一个错误? 如果在这个locking请求中我做了很多insertupdate操作,隔离级别应该是REPEATABLE READ ? 有什么办法来debugging/处理这种情况? 有没有任何机制超时锁,所以应用程序可以轻松/自动释放,并不阻止进一步的请求?

侧面的问题(因为我不直接寻找工具):有没有任何工具来监视和发现这种情况? (我希望能使用Munin。)

我用express 4.13.3来使用nodejs 4.2.1,用PostgreSQL 9.4.1 ORM将3.19.3作为后缀。

欢迎来到PostgreSQL事务锁地狱:)

你可以花费大量的时间来弄清楚究竟发生了什么,以及为什么。 但是很less有机会帮助你解决这个问题。

解决这种情况的一般方法如下:

  • 将交易规模保持在应用业务逻辑所要求的最低限度。 例如,避免使用相同types的插入或更新,将其replace为多行类似,因为查询IO很昂贵
  • 在执行只修改数据的单个查询时不要使用事务,即避免不必要的事务。
  • 实现可以确定事务锁的error handling,并提供执行事务的重复尝试。 logging这样的重复将帮助你理解系统的弱点,以及如何更好地重新devise它。

即使在一个精心devise的系统中,最后一步往往也是必须的,不要让它吓倒你;)

我遇到了类似的情况,我开始了5个并发交易请求相同的更新锁,第一个也继续工作,需要更多的postgres电话。 整个系统发生死锁,并且第一个事务在pg_stat_activity中被列为事务空闲,并被授予对它在pg_locks中所请求的所有锁的访问权限。

我在想什么

第一个事务获得locking,然后完成查询。 之后,它将连接到postgres。

以下4个事务每个都打开一个连接,并locking由第一个事务持有的锁。

由于它们被阻塞,第一个事务会执行,当它试图连接到postgres进行查询时,它会被locking,因为sequiezlize已经没有连接了。

当我改变我的sequiezlize初始化,并添加更多的连接池,默认是5,死锁消失。

我不确定是谁在使用第五个连接,或者如果默认情况是由于某种原因,出现了4而不是5,但似乎仍然勾选了所有的框。

另一个解决scheme是在postgres中使用NOWAIT选项,所以当请求一个锁而不是获取它时,根据你的用例,事务中止。

希望这有助于其他人遇到同样的问题。