gitlab-org--gitlab-foss/app/models/postgresql/replication_slot.rb
Stan Hu d092ed178f Fix background migrations failing with unused replication slot
When there is an unused replication slot, the replication lag function
will return a nil value, resulting in "NoMethodError: undefined method
`>=' for nil:NilClass" error. We now just ignore these nil values.

Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/63666
2019-06-25 08:35:29 -07:00

43 lines
1.5 KiB
Ruby

# frozen_string_literal: true
module Postgresql
class ReplicationSlot < ApplicationRecord
self.table_name = 'pg_replication_slots'
# Returns true if there are any replication slots in use.
# PostgreSQL-compatible databases such as Aurora don't support
# replication slots, so this will return false as well.
def self.in_use?
transaction { exists? }
rescue ActiveRecord::StatementInvalid
false
end
# Returns true if the lag observed across all replication slots exceeds a
# given threshold.
#
# max - The maximum replication lag size, in bytes. Based on GitLab.com
# statistics it takes between 1 and 5 seconds to replicate around
# 100 MB of data.
def self.lag_too_great?(max = 100.megabytes)
return false unless in_use?
lag_function = "#{Gitlab::Database.pg_wal_lsn_diff}" \
"(#{Gitlab::Database.pg_current_wal_insert_lsn}(), restart_lsn)::bigint"
# We force the use of a transaction here so the query always goes to the
# primary, even when using the EE DB load balancer.
sizes = transaction { pluck(lag_function) }
too_great = sizes.compact.count { |size| size >= max }
# If too many replicas are falling behind too much, the availability of a
# GitLab instance might suffer. To prevent this from happening we require
# at least 1 replica to have data recent enough.
if sizes.any? && too_great.positive?
(sizes.length - too_great) <= 1
else
false
end
end
end
end