web-dev-qa-db-ja.com

PG :: TRDeadlockDetected:エラー:デッドロックが検出されました

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のアイドルプロセスが発生します。 (私の意見では8つ多すぎます。)

これらのプロセスをより適切に管理するにはどうすればよいですか?ご協力いただきありがとうございます!


更新

私の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
20
Railsana

質問の解決策を見つけたかもしれません:コントローラー(カスタムミドルウェア)の外部でいくつかのクエリがあり、問題が発生したようです。

コントローラの外部にクエリがある場合(ActiveMailerもこの問題を引き起こす可能性があります)、コードをActiveRecord::Base.connection_pool.with_connectionブロックに配置します。

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

ActiveRecordのwith_connectionメソッドは、プールからブロックへのデータベース接続を生成します。ブロックが終了すると、接続が自動的にプールにチェックインされ、接続リークが回避されます。

これがあなたの何人かを助けることを願っています!

23
Railsana

これは、サーバーのシャットダウン時にデータベース接続が閉じられていないことが原因である可能性があります。 https://github.com/puma/puma/issues/59 この問題の多くの人が、ActiveRecord :: ConnectionAdapters :: ConnectionManagementを使用してこれを処理しています。そうしないと、ロールすることができる場合があります。 Pumaの on_restart フックを使用して所有します。

1
getabetterpic