Skip to content

Commit

Permalink
Add INNODB STATUS logging when a deadlock happens.
Browse files Browse the repository at this point in the history
Fix deadlock_retry breakage under ActiveRecord < 2.2.0
  • Loading branch information
mperham committed Feb 8, 2009
1 parent 303e830 commit 46be428
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion lib/deadlock_retry.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -44,16 +44,39 @@ def transaction_with_deadlock_handling(*objects, &block)
begin begin
transaction_without_deadlock_handling(*objects, &block) transaction_without_deadlock_handling(*objects, &block)
rescue ActiveRecord::StatementInvalid => error rescue ActiveRecord::StatementInvalid => error
raise unless connection.open_transactions.zero? raise if in_nested_transaction?
if DEADLOCK_ERROR_MESSAGES.any? { |msg| error.message =~ /#{Regexp.escape(msg)}/ } if DEADLOCK_ERROR_MESSAGES.any? { |msg| error.message =~ /#{Regexp.escape(msg)}/ }
raise if retry_count >= MAXIMUM_RETRIES_ON_DEADLOCK raise if retry_count >= MAXIMUM_RETRIES_ON_DEADLOCK
retry_count += 1 retry_count += 1
logger.info "Deadlock detected on retry #{retry_count}, restarting transaction" logger.info "Deadlock detected on retry #{retry_count}, restarting transaction"
log_innodb_status
retry retry
else else
raise raise
end end
end end
end end

private

def in_nested_transaction?
cn = connection
# open_transactions was added in 2.2's connection pooling changes.
cn.respond_to?(:open_transactions) && cn.open_transactions != 0
end

def log_innodb_status
# show innodb status is the only way to get visiblity into why
# the transaction deadlocked. log it.
lines = connection.select_value("show innodb status")
logger.warn "INNODB Status follows:"
lines.each_line do |line|
logger.warn line
end
rescue Exception => e
# Access denied, ignore
logger.warn "Cannot log innodb status: #{e.message}"
end

end end
end end

0 comments on commit 46be428

Please sign in to comment.