我的生产Rails应用程序中出现了"Mysql2::错误:超过了锁定等待超时"错误,我正在寻求帮助,以调试哪个事务锁定表的时间过长。MySQL有一个"慢速查询"日志,但据我所知,没有慢速事务日志。
有没有一种方法可以直接从ActiveRecord记录事务需要多长时间的信息?
我的团队记录的慢事务如下:
在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
。