PG::TRDeadlockDetected: ERROR: deadlock detected

Railsana picture Railsana · Jun 24, 2014 · Viewed 12.5k times · Source

I am restarting 8 puma workers via bundle exec pumactl -F config/puma.rb phased-restart what works fine. Now I am getting more and more postgres errors:

PG::TRDeadlockDetected: ERROR:  deadlock detected

I found a about 50 of idle postgres processes running:

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

They disappear when I am running bundle exec pumactl -F config/puma.rb stop. After starting the app with bundle exec pumactl -F config/puma.rb start, I get exactly 16 idle processes. (Eight too many in my opinion.)

How can I manage these processes better? Thanks for your help!


Update

My 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

Answer

Railsana picture Railsana · Nov 14, 2014

I might have found a solution to my question: I had some queries outside of my controllers (custom middleware), which seem to have caused the problem.

If you have queries outside of controllers (ActiveMailer could also cause this problem), put your code in a ActiveRecord::Base.connection_pool.with_connection block:

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

ActiveRecord’s with_connection method yields a database connection from its pool to the block. When the block finishes, the connection is automatically checked back into the pool, avoiding connection leaks.

I hope this helps some of you!