我的生产Rails应用程序中出现“Mysql2 :: Error:Lock wait timeout exceeded”错误,我正在寻找帮助调试哪个事务锁定表格的时间过长。据我所知,MySQL有一个“慢查询”日志,但不是慢速事务的日志。
有没有办法记录有关事务直接从ActiveRecord获取多长时间的信息?
答案 0 :(得分:4)
我的团队记录这样的慢事务:
在lib/slow_transaction_logger.rb
:
module SlowTransactionLogger
LOG_IF_SLOWER_THAN_SECONDS = ENV.fetch("LOG_TRANSACTIONS_SLOWER_THAN_SECONDS", "5").to_f
def transaction(*args)
start = Time.now
value = super
finish = Time.now
duration = finish - start
return value if duration <= LOG_IF_SLOWER_THAN_SECONDS
backtrace = caller.
select { |path| path.start_with?(Rails.root.to_s) }.
reject { |row|
row.include?("/gems/") ||
row.include?("/app/middleware/") ||
row.include?("/config/initializers/")
}
puts "slow_transaction_logger: duration=#{duration.round(2)} start=#{start.to_s.inspect} finish=#{finish.to_s.inspect} class=#{name} caller=#{backtrace.to_json}"
value
end
end
在config/initializers/active_record.rb
:
class ActiveRecord::Base
class << self
prepend SlowTransactionLogger
end
end
因此,默认情况下,它会在每个环境中记录慢于5秒的事务。
如果您设置LOG_TRANSACTIONS_SLOWER_THAN_SECONDS
环境变量(例如在Heroku上),则可以调整该限制。
我们故意用puts
登录,因为它最终出现在Heroku的日志中,我们也在开发和测试中更容易看到它。但如果您愿意,可以随意使用Rails.logger
。