gpt4 book ai didi

ruby-on-rails - 如何调试卡在数据库事务中的 ruby​​ 进程?

转载 作者:太空宇宙 更新时间:2023-11-03 16:41:11 26 4
gpt4 key购买 nike

我在一个相当大的 Rails 应用程序中运行了一些 ruby​​ 后台处理。后台处理由 sidekiq gem 执行。有时我会经历一种非常奇怪的行为,这种行为会陷入死亡漩涡。

一些相对简单的工作在连接的 postgresql 数据库中对单个记录进行简单的 UPDATE s 不知何故永远不会成功。他们执行的查询在 postgresql 中作为 waiting 卡住,在事务中空闲,因为更新查询的事务显然从未发送 COMMIT。当 postgresql 正在等待这个时,发送查询的 ruby​​ 后台处理似乎也在等待! ruby 进程似乎挂起等待事务从 postgresql 完成,因此没有做任何进一步的工作。

我现在的问题是,在这种死锁情况下,如何进一步调试问题的根本原因? (ruby、postgresql、操作系统、网络、其他)

附言。如果我通过发送 SELECT pg_cancel_backend(faulty_pid) 手动取消 postgresql 中挂起的事务,那么挂起的 sidekiq/ruby 进程会立即出现连接错误并恢复正常,继续接收作业和像什么都没发生过一样工作。这似乎向我表明,db 和 ruby​​ 之间的连接仍然正常,ruby 进程并没有真正卡住。但不知何故出了点问题。

附言。我正在运行 ruby​​ 2.4.0、rails 4.2、Postgresql 9.3、sidekiq 4.2 和 pg 0.20.0

最佳答案

这可能会导致您的工作人员打开与 postgres 的连接,而这些连接永远不会关闭。如果您重试作业,这会使问题更加复杂。要解决此问题,您可能需要按计划运行这样的工作程序以清除所有未关闭的连接:

class DbIdleCleanerWorker
include Sidekiq::Worker

sidekiq_options retry: 0

def perform()
sql = "SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE query != '<IDLE>' AND query NOT ILIKE '%pg_stat_activity%' AND state = 'idle'
AND now()-pg_stat_activity.query_start > interval '1 minutes'
ORDER BY query_start desc;"
ActiveRecord::Base.connection.execute(sql)
end
end

关于ruby-on-rails - 如何调试卡在数据库事务中的 ruby​​ 进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49418424/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com