PG:: TRDeadlockDetected: ОШИБКА: обнаружен тупик
Я перезапускаю 8 работников puma через bundle exec pumactl -F config/puma.rb phased-restart
, что отлично работает. Теперь я получаю все больше ошибок 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
Ответы
Ответ 1
Возможно, я нашел решение моего вопроса: У меня были некоторые запросы за пределами моих контроллеров (настраиваемое промежуточное ПО), которые, похоже, вызвали эту проблему.
Если у вас есть запросы вне контроллеров (ActiveMailer также может вызвать эту проблему), поместите свой код в блок ActiveRecord::Base.connection_pool.with_connection
:
ActiveRecord::Base.connection_pool.with_connection do
# code
end
Метод ActiveRecords with_connection дает соединение с базой данных из своего пула в блок. Когда блок завершается, соединение автоматически проверяется обратно в пул, избегая утечек соединения.
Надеюсь, это поможет некоторым из вас!
Ответ 2
Похоже, это связано с тем, что соединения с базой данных не закрываются при завершении работы сервера. https://github.com/puma/puma/issues/59 Многие люди в этой проблеме используют ActiveRecord:: ConnectionAdapters:: ConnectionManagement, чтобы справиться с этим, или вы можете самостоятельно используя Puma on_restart.