Commit 19e38656 authored by Stan Hu's avatar Stan Hu

Log backtrace when SAVEPOINT is discovered

We have mostly eliminated using subtransactions from the code, but there
are a few places where they may be happening. Log the backtrace of the
caller to identify exactly where this is happening.

Changelog: added
parent 5526b946
...@@ -38,6 +38,11 @@ module Gitlab ...@@ -38,6 +38,11 @@ module Gitlab
(@context[:queries] ||= []).push(sql) (@context[:queries] ||= []).push(sql)
end end
def track_backtrace(backtrace)
cleaned_backtrace = Gitlab::BacktraceCleaner.clean_backtrace(backtrace)
(@context[:backtraces] ||= []).push(cleaned_backtrace)
end
def duration def duration
return unless @context[:start_time].present? return unless @context[:start_time].present?
...@@ -66,6 +71,10 @@ module Gitlab ...@@ -66,6 +71,10 @@ module Gitlab
log(:rollback) log(:rollback)
end end
def backtraces
@context[:backtraces].to_a
end
private private
def queries def queries
...@@ -99,7 +108,8 @@ module Gitlab ...@@ -99,7 +108,8 @@ module Gitlab
savepoints_count: @context[:savepoints].to_i, savepoints_count: @context[:savepoints].to_i,
rollbacks_count: @context[:rollbacks].to_i, rollbacks_count: @context[:rollbacks].to_i,
releases_count: @context[:releases].to_i, releases_count: @context[:releases].to_i,
sql: queries sql: queries,
savepoint_backtraces: backtraces
} }
application_info(attributes) application_info(attributes)
......
...@@ -24,6 +24,7 @@ module Gitlab ...@@ -24,6 +24,7 @@ module Gitlab
elsif cmd.start_with?('SAVEPOINT', 'EXCEPTION') elsif cmd.start_with?('SAVEPOINT', 'EXCEPTION')
context.set_depth(manager.open_transactions) context.set_depth(manager.open_transactions)
context.increment_savepoints context.increment_savepoints
context.track_backtrace(caller)
elsif cmd.start_with?('ROLLBACK TO SAVEPOINT') elsif cmd.start_with?('ROLLBACK TO SAVEPOINT')
context.increment_rollbacks context.increment_rollbacks
elsif cmd.start_with?('RELEASE SAVEPOINT ') elsif cmd.start_with?('RELEASE SAVEPOINT ')
......
...@@ -62,6 +62,26 @@ RSpec.describe Gitlab::Database::Transaction::Context do ...@@ -62,6 +62,26 @@ RSpec.describe Gitlab::Database::Transaction::Context do
it { expect(data[:queries]).to eq(['SELECT 1', 'SELECT * FROM users']) } it { expect(data[:queries]).to eq(['SELECT 1', 'SELECT * FROM users']) }
end end
describe '#track_backtrace' do
before do
subject.track_backtrace(caller)
end
it { expect(data[:backtraces]).to be_a(Array) }
it { expect(data[:backtraces]).to all(be_a(Array)) }
it { expect(data[:backtraces].length).to eq(1) }
it { expect(data[:backtraces][0][0]).to be_a(String) }
it 'appends the backtrace' do
subject.track_backtrace(caller)
expect(data[:backtraces].length).to eq(2)
expect(subject.backtraces).to be_a(Array)
expect(subject.backtraces).to all(be_a(Array))
expect(subject.backtraces[1][0]).to be_a(String)
end
end
describe '#duration' do describe '#duration' do
before do before do
subject.set_start_time subject.set_start_time
......
...@@ -25,7 +25,7 @@ RSpec.describe Gitlab::Database::Transaction::Observer do ...@@ -25,7 +25,7 @@ RSpec.describe Gitlab::Database::Transaction::Observer do
User.first User.first
expect(transaction_context).to be_a(::Gitlab::Database::Transaction::Context) expect(transaction_context).to be_a(::Gitlab::Database::Transaction::Context)
expect(context.keys).to match_array(%i(start_time depth savepoints queries)) expect(context.keys).to match_array(%i(start_time depth savepoints queries backtraces))
expect(context[:depth]).to eq(2) expect(context[:depth]).to eq(2)
expect(context[:savepoints]).to eq(1) expect(context[:savepoints]).to eq(1)
expect(context[:queries].length).to eq(1) expect(context[:queries].length).to eq(1)
...@@ -35,6 +35,7 @@ RSpec.describe Gitlab::Database::Transaction::Observer do ...@@ -35,6 +35,7 @@ RSpec.describe Gitlab::Database::Transaction::Observer do
expect(context[:depth]).to eq(2) expect(context[:depth]).to eq(2)
expect(context[:savepoints]).to eq(1) expect(context[:savepoints]).to eq(1)
expect(context[:releases]).to eq(1) expect(context[:releases]).to eq(1)
expect(context[:backtraces].length).to eq(1)
end end
describe '.extract_sql_command' do describe '.extract_sql_command' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment