Commit a5719143 authored by Stan Hu's avatar Stan Hu

Merge branch 'feature/gb/instrument-sub-transactions' into 'master'

Instrument sub-transactions created by ActiveRecord

See merge request gitlab-org/gitlab!66477
parents 7c885d0c 0cca2912
...@@ -86,4 +86,17 @@ class ApplicationRecord < ActiveRecord::Base ...@@ -86,4 +86,17 @@ class ApplicationRecord < ActiveRecord::Base
values = enum_mod.definition.transform_values { |v| v[:value] } values = enum_mod.definition.transform_values { |v| v[:value] }
enum(enum_mod.key => values) enum(enum_mod.key => values)
end end
def self.transaction(**options, &block)
if options[:requires_new] && track_subtransactions?
::Gitlab::Database::Metrics.subtransactions_increment(self.name)
end
super(**options, &block)
end
def self.track_subtransactions?
::Feature.enabled?(:active_record_subtransactions_counter, type: :ops, default_enabled: :yaml) &&
connection.transaction_open?
end
end end
---
name: active_record_subtransactions_counter
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66477
rollout_issue_url:
milestone: '14.1'
type: ops
group: group::pipeline execution
default_enabled: false
...@@ -42,9 +42,9 @@ module Gitlab ...@@ -42,9 +42,9 @@ module Gitlab
# timeout - The time after which the pool should be forcefully # timeout - The time after which the pool should be forcefully
# disconnected. # disconnected.
def disconnect!(timeout = 120) def disconnect!(timeout = 120)
start_time = Metrics::System.monotonic_time start_time = ::Gitlab::Metrics::System.monotonic_time
while (Metrics::System.monotonic_time - start_time) <= timeout while (::Gitlab::Metrics::System.monotonic_time - start_time) <= timeout
break if pool.connections.none?(&:in_use?) break if pool.connections.none?(&:in_use?)
sleep(2) sleep(2)
......
# frozen_string_literal: true
module Gitlab
module Database
class Metrics
extend ::Gitlab::Utils::StrongMemoize
class << self
def subtransactions_increment(model_name)
subtransactions_counter.increment(model: model_name)
end
private
def subtransactions_counter
strong_memoize(:subtransactions_counter) do
name = :gitlab_active_record_subtransactions_total
comment = 'Total amount of subtransactions created by ActiveRecord'
::Gitlab::Metrics.counter(name, comment)
end
end
end
end
end
end
...@@ -105,6 +105,50 @@ RSpec.describe ApplicationRecord do ...@@ -105,6 +105,50 @@ RSpec.describe ApplicationRecord do
end end
end end
describe '.transaction', :delete do
it 'opens a new transaction' do
expect(described_class.connection.transaction_open?).to be false
Project.transaction do
expect(Project.connection.transaction_open?).to be true
Project.transaction(requires_new: true) do
expect(Project.connection.transaction_open?).to be true
end
end
end
it 'does not increment a counter when a transaction is not nested' do
expect(described_class.connection.transaction_open?).to be false
expect(::Gitlab::Database::Metrics)
.not_to receive(:subtransactions_increment)
Project.transaction do
expect(Project.connection.transaction_open?).to be true
end
Project.transaction(requires_new: true) do
expect(Project.connection.transaction_open?).to be true
end
end
it 'increments a counter when a nested transaction is created' do
expect(described_class.connection.transaction_open?).to be false
expect(::Gitlab::Database::Metrics)
.to receive(:subtransactions_increment)
.with('Project')
.once
Project.transaction do
Project.transaction(requires_new: true) do
expect(Project.connection.transaction_open?).to be true
end
end
end
end
describe '.with_fast_read_statement_timeout' do describe '.with_fast_read_statement_timeout' do
context 'when the query runs faster than configured timeout' do context 'when the query runs faster than configured timeout' do
it 'executes the query without error' do it 'executes the query without error' 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