diff options
Diffstat (limited to 'lib/gitlab/database/reindexing.rb')
-rw-r--r-- | lib/gitlab/database/reindexing.rb | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/lib/gitlab/database/reindexing.rb b/lib/gitlab/database/reindexing.rb index 841e04ccbd1..04b409a9306 100644 --- a/lib/gitlab/database/reindexing.rb +++ b/lib/gitlab/database/reindexing.rb @@ -8,6 +8,13 @@ module Gitlab SUPPORTED_TYPES = %w(btree gist).freeze + # When dropping an index, we acquire a SHARE UPDATE EXCLUSIVE lock, + # which only conflicts with DDL and vacuum. We therefore execute this with a rather + # high lock timeout and a long pause in between retries. This is an alternative to + # setting a high statement timeout, which would lead to a long running query with effects + # on e.g. vacuum. + REMOVE_INDEX_RETRY_CONFIG = [[1.minute, 9.minutes]] * 30 + # candidate_indexes: Array of Gitlab::Database::PostgresIndex def self.perform(candidate_indexes, how_many: DEFAULT_INDEXES_PER_INVOCATION) IndexSelection.new(candidate_indexes).take(how_many).each do |index| @@ -15,10 +22,22 @@ module Gitlab end end - def self.candidate_indexes - Gitlab::Database::PostgresIndex - .not_match("#{ReindexConcurrently::TEMPORARY_INDEX_PATTERN}$") - .reindexing_support + def self.cleanup_leftovers! + PostgresIndex.reindexing_leftovers.each do |index| + Gitlab::AppLogger.info("Removing index #{index.identifier} which is a leftover, temporary index from previous reindexing activity") + + retries = Gitlab::Database::WithLockRetriesOutsideTransaction.new( + timing_configuration: REMOVE_INDEX_RETRY_CONFIG, + klass: self.class, + logger: Gitlab::AppLogger + ) + + retries.run(raise_on_exhaustion: false) do + ApplicationRecord.connection.tap do |conn| + conn.execute("DROP INDEX CONCURRENTLY IF EXISTS #{conn.quote_table_name(index.schema)}.#{conn.quote_table_name(index.name)}") + end + end + end end end end |