mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-01 16:04:19 +00:00
75 lines
2.3 KiB
Ruby
75 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Database
|
|
class StatActivitySampler
|
|
include ExclusiveLeaseGuard
|
|
|
|
# Lookup the pg_stat_get_activity(-1) function instead of pg_stat_activity table.
|
|
# This query returns non-null `query` only for users which the connection is authorised to.
|
|
#
|
|
# application is either sidekiq or puma
|
|
# endpoint refers to a worker class or a route
|
|
# database refers to the configured database field in `config/database.yml`
|
|
#
|
|
# This query omits idle tuples from the pg_stat_activity table as it is only concerned with active or idle in
|
|
# transaction processes.
|
|
PG_STAT_ACTIVITY_SAMPLER_SQL = <<~SQL
|
|
SELECT
|
|
a.matches[1] AS application,
|
|
a.matches[2] AS endpoint,
|
|
a.matches[3] AS database,
|
|
a.state AS state,
|
|
COUNT(*) AS count
|
|
FROM (
|
|
SELECT
|
|
state,
|
|
regexp_matches(query, '^\\s*(?:\\/\\*(?:application:(\\w+),?)?(?:correlation_id:\\w+,?)?(?:jid:\\w+,?)?(?:endpoint_id:([\\w/\\-\\.:\\\#\\s]+),?)?(?:db_config_database:(\\w+),?)?.*?\\*\\/)?\\s*(\\w+)') AS matches
|
|
FROM
|
|
pg_stat_get_activity(-1)
|
|
) a
|
|
GROUP BY application, endpoint, database, state
|
|
SQL
|
|
|
|
SAMPLING_INTERVAL = 15
|
|
|
|
def self.sample
|
|
Gitlab::Database::LoadBalancing.base_models.each do |bm|
|
|
new(bm.connection).execute
|
|
end
|
|
end
|
|
|
|
attr_reader :connection
|
|
|
|
def initialize(connection)
|
|
@connection = connection
|
|
@lease_key = "pg_stat_sampler:#{connection.load_balancer.name}:lock"
|
|
end
|
|
|
|
def execute
|
|
try_obtain_lease do
|
|
sample = sample_pg_stat_activity
|
|
StatActivity.write(connection.load_balancer.name, sample)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def lease_timeout
|
|
SAMPLING_INTERVAL
|
|
end
|
|
|
|
# Overrides ExclusiveLeaseGuard to not release lease after the sample to ensure we do not oversample
|
|
def lease_release?
|
|
false
|
|
end
|
|
|
|
def sample_pg_stat_activity
|
|
Gitlab::Database::LoadBalancing::SessionMap.current(connection.load_balancer).use_primary do
|
|
connection.execute(PG_STAT_ACTIVITY_SAMPLER_SQL).to_a
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|