PG :: TRDeadlockDetected:ERROR:检测到死锁

时间:2014-06-24 11:26:09

标签: ruby-on-rails ruby postgresql puma idle-processing

我正在通过bundle exec pumactl -F config/puma.rb phased-restart重启8名彪马工作人员。现在我得到越来越多的postgres错误:

PG::TRDeadlockDetected: ERROR:  deadlock detected

我发现大约有50个闲置的postgres进程在运行:

postgres: myapp myapp_production 127.0.0.1(59950) idle
postgres: myapp myapp_production 127.0.0.1(60141) idle
...

当我跑步bundle exec pumactl -F config/puma.rb stop时,它们会消失。 用bundle exec pumactl -F config/puma.rb start启动应用程序后,我得到了16个空闲进程。 (在我看来,太多了。)

如何更好地管理这些流程?谢谢你的帮助!


更新

我的puma.rb:

environment 'production'
daemonize true

pidfile 'tmp/pids/puma.pid'
state_path 'tmp/pids/puma.state'

threads 0, 1
bind 'tcp://0.0.0.0:3010'

workers 8

quiet

2 个答案:

答案 0 :(得分:20)

我可能已经找到了解决问题的方法:我的控制器之外有一些查询(自定义中间件),这似乎导致了问题。

如果您在控制器之外有查询(ActiveMailer也可能导致此问题),请将您的代码放在ActiveRecord::Base.connection_pool.with_connection块中:

ActiveRecord::Base.connection_pool.with_connection do
  # code
end

ActiveRecord的with_connection方法产生从其池到块的数据库连接。块完成后,连接会自动检回池中,避免连接泄漏。

我希望这有助于你们中的一些人!

答案 1 :(得分:1)

看起来这可能是由于数据库连接未在服务器关闭时关闭。 https://github.com/puma/puma/issues/59该问题中的很多人正在使用ActiveRecord :: ConnectionAdapters :: ConnectionManagement来处理这个问题,或者您也可以使用Puma的on_restart挂钩来推销自己的。