Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 11:17:02 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 11:17:02 +0300
commitb39512ed755239198a9c294b6a45e65c05900235 (patch)
treed234a3efade1de67c46b9e5a38ce813627726aa7 /lib/gitlab/database
parentd31474cf3b17ece37939d20082b07f6657cc79a9 (diff)
Add latest changes from gitlab-org/gitlab@15-3-stable-eev15.3.0-rc42
Diffstat (limited to 'lib/gitlab/database')
-rw-r--r--lib/gitlab/database/async_indexes.rb8
-rw-r--r--lib/gitlab/database/async_indexes/index_destructor.rb66
-rw-r--r--lib/gitlab/database/async_indexes/migration_helpers.rb32
-rw-r--r--lib/gitlab/database/async_indexes/postgres_async_index.rb3
-rw-r--r--lib/gitlab/database/background_migration/batched_job.rb4
-rw-r--r--lib/gitlab/database/background_migration/batched_migration.rb8
-rw-r--r--lib/gitlab/database/background_migration/batched_migration_runner.rb4
-rw-r--r--lib/gitlab/database/background_migration/batched_migration_wrapper.rb3
-rw-r--r--lib/gitlab/database/background_migration/health_status.rb30
-rw-r--r--lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log.rb74
-rw-r--r--lib/gitlab/database/background_migration/health_status/signals.rb8
-rw-r--r--lib/gitlab/database/bulk_update.rb2
-rw-r--r--lib/gitlab/database/dynamic_model_helpers.rb2
-rw-r--r--lib/gitlab/database/gitlab_schemas.yml7
-rw-r--r--lib/gitlab/database/lock_writes_manager.rb80
-rw-r--r--lib/gitlab/database/migration_helpers.rb13
-rw-r--r--lib/gitlab/database/migrations/background_migration_helpers.rb2
-rw-r--r--lib/gitlab/database/migrations/base_background_runner.rb2
-rw-r--r--lib/gitlab/database/migrations/batched_background_migration_helpers.rb7
-rw-r--r--lib/gitlab/database/partitioning/sliding_list_strategy.rb1
-rw-r--r--lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb2
-rw-r--r--lib/gitlab/database/postgres_hll/buckets.rb4
-rw-r--r--lib/gitlab/database/reindexing.rb1
-rw-r--r--lib/gitlab/database/reindexing/reindex_concurrently.rb6
-rw-r--r--lib/gitlab/database/with_lock_retries.rb2
25 files changed, 336 insertions, 35 deletions
diff --git a/lib/gitlab/database/async_indexes.rb b/lib/gitlab/database/async_indexes.rb
index d89d5238356..6f301a66803 100644
--- a/lib/gitlab/database/async_indexes.rb
+++ b/lib/gitlab/database/async_indexes.rb
@@ -6,10 +6,16 @@ module Gitlab
DEFAULT_INDEXES_PER_INVOCATION = 2
def self.create_pending_indexes!(how_many: DEFAULT_INDEXES_PER_INVOCATION)
- PostgresAsyncIndex.order(:id).limit(how_many).each do |async_index|
+ PostgresAsyncIndex.to_create.order(:id).limit(how_many).each do |async_index|
IndexCreator.new(async_index).perform
end
end
+
+ def self.drop_pending_indexes!(how_many: DEFAULT_INDEXES_PER_INVOCATION)
+ PostgresAsyncIndex.to_drop.order(:id).limit(how_many).each do |async_index|
+ IndexDestructor.new(async_index).perform
+ end
+ end
end
end
end
diff --git a/lib/gitlab/database/async_indexes/index_destructor.rb b/lib/gitlab/database/async_indexes/index_destructor.rb
new file mode 100644
index 00000000000..fe05872b87a
--- /dev/null
+++ b/lib/gitlab/database/async_indexes/index_destructor.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module AsyncIndexes
+ class IndexDestructor
+ include ExclusiveLeaseGuard
+
+ TIMEOUT_PER_ACTION = 1.day
+
+ def initialize(async_index)
+ @async_index = async_index
+ end
+
+ def perform
+ try_obtain_lease do
+ if !index_exists?
+ log_index_info('Skipping dropping as the index does not exist')
+ else
+ log_index_info('Dropping async index')
+
+ retries = Gitlab::Database::WithLockRetriesOutsideTransaction.new(
+ connection: connection,
+ timing_configuration: Gitlab::Database::Reindexing::REMOVE_INDEX_RETRY_CONFIG,
+ klass: self.class,
+ logger: Gitlab::AppLogger
+ )
+
+ retries.run(raise_on_exhaustion: false) do
+ connection.execute(async_index.definition)
+ end
+
+ log_index_info('Finished dropping async index')
+ end
+
+ async_index.destroy
+ end
+ end
+
+ private
+
+ attr_reader :async_index
+
+ def index_exists?
+ connection.indexes(async_index.table_name).any? { |index| index.name == async_index.name }
+ end
+
+ def connection
+ @connection ||= async_index.connection
+ end
+
+ def lease_timeout
+ TIMEOUT_PER_ACTION
+ end
+
+ def lease_key
+ [super, async_index.connection_db_config.name].join('/')
+ end
+
+ def log_index_info(message)
+ Gitlab::AppLogger.info(message: message, table_name: async_index.table_name, index_name: async_index.name)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/async_indexes/migration_helpers.rb b/lib/gitlab/database/async_indexes/migration_helpers.rb
index e9846dd4e85..c8f6761534c 100644
--- a/lib/gitlab/database/async_indexes/migration_helpers.rb
+++ b/lib/gitlab/database/async_indexes/migration_helpers.rb
@@ -77,6 +77,38 @@ module Gitlab
async_index
end
+ # Prepares an index for asynchronous destruction.
+ #
+ # Stores the index information in the postgres_async_indexes table to be removed later. The
+ # index will be always be removed CONCURRENTLY, so that option does not need to be given.
+ #
+ # If the requested index has already been removed, it is not stored in the table for
+ # asynchronous destruction.
+ def prepare_async_index_removal(table_name, column_name, options = {})
+ index_name = options.fetch(:name)
+ raise 'prepare_async_index_removal must get an index name defined' if index_name.blank?
+
+ unless index_exists?(table_name, column_name, **options)
+ Gitlab::AppLogger.warn "Index not removed because it does not exist (this may be due to an aborted migration or similar): table_name: #{table_name}, index_name: #{index_name}"
+ return
+ end
+
+ definition = "DROP INDEX CONCURRENTLY #{quote_column_name(index_name)}"
+
+ async_index = PostgresAsyncIndex.find_or_create_by!(name: index_name) do |rec|
+ rec.table_name = table_name
+ rec.definition = definition
+ end
+
+ Gitlab::AppLogger.info(
+ message: 'Prepared index for async destruction',
+ table_name: async_index.table_name,
+ index_name: async_index.name
+ )
+
+ async_index
+ end
+
def async_index_creation_available?
connection.table_exists?(:postgres_async_indexes)
end
diff --git a/lib/gitlab/database/async_indexes/postgres_async_index.rb b/lib/gitlab/database/async_indexes/postgres_async_index.rb
index 6cb40729061..dc932482d40 100644
--- a/lib/gitlab/database/async_indexes/postgres_async_index.rb
+++ b/lib/gitlab/database/async_indexes/postgres_async_index.rb
@@ -13,6 +13,9 @@ module Gitlab
validates :table_name, presence: true, length: { maximum: MAX_IDENTIFIER_LENGTH }
validates :definition, presence: true, length: { maximum: MAX_DEFINITION_LENGTH }
+ scope :to_create, -> { where("definition ILIKE 'CREATE%'") }
+ scope :to_drop, -> { where("definition ILIKE 'DROP%'") }
+
def to_s
definition
end
diff --git a/lib/gitlab/database/background_migration/batched_job.rb b/lib/gitlab/database/background_migration/batched_job.rb
index 72aa1cfe00b..81898a59da7 100644
--- a/lib/gitlab/database/background_migration/batched_job.rb
+++ b/lib/gitlab/database/background_migration/batched_job.rb
@@ -112,7 +112,7 @@ module Gitlab
end
def can_split?(exception)
- attempts >= MAX_ATTEMPTS && TIMEOUT_EXCEPTIONS.include?(exception&.class) && batch_size > sub_batch_size
+ attempts >= MAX_ATTEMPTS && TIMEOUT_EXCEPTIONS.include?(exception&.class) && batch_size > sub_batch_size && batch_size > 1
end
def split_and_retry!
@@ -121,7 +121,7 @@ module Gitlab
new_batch_size = batch_size / 2
- raise SplitAndRetryError, 'Job cannot be split further' if new_batch_size < 1
+ break update!(attempts: 0) if new_batch_size < 1
batching_strategy = batched_migration.batch_class.new(connection: self.class.connection)
next_batch_bounds = batching_strategy.next_batch(
diff --git a/lib/gitlab/database/background_migration/batched_migration.rb b/lib/gitlab/database/background_migration/batched_migration.rb
index 9c8db2243f9..6aed1eed994 100644
--- a/lib/gitlab/database/background_migration/batched_migration.rb
+++ b/lib/gitlab/database/background_migration/batched_migration.rb
@@ -206,7 +206,7 @@ module Gitlab
end
def health_context
- HealthStatus::Context.new([table_name])
+ HealthStatus::Context.new(connection, [table_name])
end
def hold!(until_time: 10.minutes.from_now)
@@ -231,6 +231,12 @@ module Gitlab
"BatchedMigration[id: #{id}]"
end
+ def progress
+ return unless total_tuple_count.to_i > 0
+
+ 100 * migrated_tuple_count / total_tuple_count
+ end
+
private
def validate_batched_jobs_status
diff --git a/lib/gitlab/database/background_migration/batched_migration_runner.rb b/lib/gitlab/database/background_migration/batched_migration_runner.rb
index 1bc2e931391..7224ff2b517 100644
--- a/lib/gitlab/database/background_migration/batched_migration_runner.rb
+++ b/lib/gitlab/database/background_migration/batched_migration_runner.rb
@@ -144,9 +144,9 @@ module Gitlab
end
def adjust_migration(active_migration)
- signal = HealthStatus.evaluate(active_migration)
+ signals = HealthStatus.evaluate(active_migration)
- if signal.is_a?(HealthStatus::Signals::Stop)
+ if signals.any?(&:stop?)
active_migration.hold!
else
active_migration.optimize!
diff --git a/lib/gitlab/database/background_migration/batched_migration_wrapper.rb b/lib/gitlab/database/background_migration/batched_migration_wrapper.rb
index 5f4b2be3da8..ad747a8131d 100644
--- a/lib/gitlab/database/background_migration/batched_migration_wrapper.rb
+++ b/lib/gitlab/database/background_migration/batched_migration_wrapper.rb
@@ -64,9 +64,10 @@ module Gitlab
batch_column: tracking_record.migration_column_name,
sub_batch_size: tracking_record.sub_batch_size,
pause_ms: tracking_record.pause_ms,
+ job_arguments: tracking_record.migration_job_arguments,
connection: connection)
- job_instance.perform(*tracking_record.migration_job_arguments)
+ job_instance.perform
job_instance
end
diff --git a/lib/gitlab/database/background_migration/health_status.rb b/lib/gitlab/database/background_migration/health_status.rb
index 01f9c5eb5fd..9a283074b32 100644
--- a/lib/gitlab/database/background_migration/health_status.rb
+++ b/lib/gitlab/database/background_migration/health_status.rb
@@ -4,21 +4,29 @@ module Gitlab
module Database
module BackgroundMigration
module HealthStatus
+ DEFAULT_INIDICATORS = [
+ Indicators::AutovacuumActiveOnTable,
+ Indicators::WriteAheadLog
+ ].freeze
+
# Rather than passing along the migration, we use a more explicitly defined context
- Context = Struct.new(:tables)
+ Context = Struct.new(:connection, :tables)
- def self.evaluate(migration, indicator = Indicators::AutovacuumActiveOnTable)
- signal = begin
- indicator.new(migration.health_context).evaluate
- rescue StandardError => e
- Gitlab::ErrorTracking.track_exception(e, migration_id: migration.id,
- job_class_name: migration.job_class_name)
- Signals::Unknown.new(indicator, reason: "unexpected error: #{e.message} (#{e.class})")
- end
+ def self.evaluate(migration, indicators = DEFAULT_INIDICATORS)
+ indicators.map do |indicator|
+ signal = begin
+ indicator.new(migration.health_context).evaluate
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_exception(e, migration_id: migration.id,
+ job_class_name: migration.job_class_name)
- log_signal(signal, migration) if signal.log_info?
+ Signals::Unknown.new(indicator, reason: "unexpected error: #{e.message} (#{e.class})")
+ end
- signal
+ log_signal(signal, migration) if signal.log_info?
+
+ signal
+ end
end
def self.log_signal(signal, migration)
diff --git a/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log.rb b/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log.rb
new file mode 100644
index 00000000000..d2fb0a8b751
--- /dev/null
+++ b/lib/gitlab/database/background_migration/health_status/indicators/write_ahead_log.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module BackgroundMigration
+ module HealthStatus
+ module Indicators
+ class WriteAheadLog
+ include Gitlab::Utils::StrongMemoize
+
+ LIMIT = 42
+ PENDING_WAL_COUNT_SQL = <<~SQL
+ WITH
+ current_wal_file AS (
+ SELECT pg_walfile_name(pg_current_wal_insert_lsn()) AS pg_walfile_name
+ ),
+ current_wal AS (
+ SELECT
+ ('x' || substring(pg_walfile_name, 9, 8))::bit(32)::int AS log,
+ ('x' || substring(pg_walfile_name, 17, 8))::bit(32)::int AS seg,
+ pg_walfile_name
+ FROM current_wal_file
+ ),
+ archive_wal AS (
+ SELECT
+ ('x' || substring(last_archived_wal, 9, 8))::bit(32)::int AS log,
+ ('x' || substring(last_archived_wal, 17, 8))::bit(32)::int AS seg,
+ last_archived_wal
+ FROM pg_stat_archiver
+ )
+ SELECT ((current_wal.log - archive_wal.log) * 256) + (current_wal.seg - archive_wal.seg) AS pending_wal_count
+ FROM current_wal, archive_wal
+ SQL
+
+ def initialize(context)
+ @connection = context.connection
+ end
+
+ def evaluate
+ return Signals::NotAvailable.new(self.class, reason: 'indicator disabled') unless enabled?
+
+ unless pending_wal_count
+ return Signals::NotAvailable.new(self.class, reason: 'WAL archive queue can not be calculated')
+ end
+
+ if pending_wal_count > LIMIT
+ Signals::Stop.new(self.class, reason: "WAL archive queue is too big")
+ else
+ Signals::Normal.new(self.class, reason: 'WAL archive queue is within limit')
+ end
+ end
+
+ private
+
+ attr_reader :connection
+
+ def enabled?
+ Feature.enabled?(:batched_migrations_health_status_wal, type: :ops)
+ end
+
+ # Returns number of WAL segments pending archival
+ def pending_wal_count
+ strong_memoize(:pending_wal_count) do
+ Gitlab::Database::LoadBalancing::Session.current.use_primary do
+ connection.execute(PENDING_WAL_COUNT_SQL).to_a.first&.fetch('pending_wal_count')
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/background_migration/health_status/signals.rb b/lib/gitlab/database/background_migration/health_status/signals.rb
index 6cd0ebd1bd0..be741a9d91b 100644
--- a/lib/gitlab/database/background_migration/health_status/signals.rb
+++ b/lib/gitlab/database/background_migration/health_status/signals.rb
@@ -22,6 +22,10 @@ module Gitlab
def log_info?
false
end
+
+ def stop?
+ false
+ end
# :nocov:
private
@@ -38,6 +42,10 @@ module Gitlab
def log_info?
true
end
+
+ def stop?
+ true
+ end
# :nocov:
end
diff --git a/lib/gitlab/database/bulk_update.rb b/lib/gitlab/database/bulk_update.rb
index b1f9da30585..d68be19047e 100644
--- a/lib/gitlab/database/bulk_update.rb
+++ b/lib/gitlab/database/bulk_update.rb
@@ -157,7 +157,7 @@ module Gitlab
def self.execute(columns, mapping, &to_class)
raise ArgumentError if mapping.blank?
- entries_by_class = mapping.group_by { |k, v| block_given? ? to_class.call(k) : k.class }
+ entries_by_class = mapping.group_by { |k, v| to_class ? to_class.call(k) : k.class }
entries_by_class.each do |model, entries|
Setter.new(model, columns, entries).update!
diff --git a/lib/gitlab/database/dynamic_model_helpers.rb b/lib/gitlab/database/dynamic_model_helpers.rb
index ad7dea8f0d9..2deb89a0b84 100644
--- a/lib/gitlab/database/dynamic_model_helpers.rb
+++ b/lib/gitlab/database/dynamic_model_helpers.rb
@@ -32,7 +32,7 @@ module Gitlab
def each_batch_range(table_name, connection:, scope: ->(table) { table.all }, of: BATCH_SIZE)
each_batch(table_name, connection: connection, scope: scope, of: of) do |batch|
- yield batch.pluck('MIN(id), MAX(id)').first
+ yield batch.pick('MIN(id), MAX(id)')
end
end
end
diff --git a/lib/gitlab/database/gitlab_schemas.yml b/lib/gitlab/database/gitlab_schemas.yml
index 4a467d18f0a..d05eee7d6e6 100644
--- a/lib/gitlab/database/gitlab_schemas.yml
+++ b/lib/gitlab/database/gitlab_schemas.yml
@@ -300,6 +300,7 @@ licenses: :gitlab_main
lists: :gitlab_main
list_user_preferences: :gitlab_main
loose_foreign_keys_deleted_records: :gitlab_shared
+member_roles: :gitlab_main
member_tasks: :gitlab_main
members: :gitlab_main
merge_request_assignees: :gitlab_main
@@ -323,6 +324,10 @@ metrics_dashboard_annotations: :gitlab_main
metrics_users_starred_dashboards: :gitlab_main
milestone_releases: :gitlab_main
milestones: :gitlab_main
+ml_candidates: :gitlab_main
+ml_experiments: :gitlab_main
+ml_candidate_metrics: :gitlab_main
+ml_candidate_params: :gitlab_main
namespace_admin_notes: :gitlab_main
namespace_aggregation_schedules: :gitlab_main
namespace_bans: :gitlab_main
@@ -331,6 +336,7 @@ namespace_package_settings: :gitlab_main
namespace_root_storage_statistics: :gitlab_main
namespace_ci_cd_settings: :gitlab_main
namespace_settings: :gitlab_main
+namespace_details: :gitlab_main
namespaces: :gitlab_main
namespaces_sync_events: :gitlab_main
namespace_statistics: :gitlab_main
@@ -529,6 +535,7 @@ user_custom_attributes: :gitlab_main
user_details: :gitlab_main
user_follow_users: :gitlab_main
user_group_callouts: :gitlab_main
+user_project_callouts: :gitlab_main
user_highest_roles: :gitlab_main
user_interacted_projects: :gitlab_main
user_permission_export_uploads: :gitlab_main
diff --git a/lib/gitlab/database/lock_writes_manager.rb b/lib/gitlab/database/lock_writes_manager.rb
new file mode 100644
index 00000000000..cd483d616bb
--- /dev/null
+++ b/lib/gitlab/database/lock_writes_manager.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ class LockWritesManager
+ TRIGGER_FUNCTION_NAME = 'gitlab_schema_prevent_write'
+
+ def initialize(table_name:, connection:, database_name:, logger: nil)
+ @table_name = table_name
+ @connection = connection
+ @database_name = database_name
+ @logger = logger
+ end
+
+ def lock_writes
+ logger&.info "Database: '#{database_name}', Table: '#{table_name}': Lock Writes".color(:yellow)
+ sql = <<-SQL
+ DROP TRIGGER IF EXISTS #{write_trigger_name(table_name)} ON #{table_name};
+ CREATE TRIGGER #{write_trigger_name(table_name)}
+ BEFORE INSERT OR UPDATE OR DELETE OR TRUNCATE
+ ON #{table_name}
+ FOR EACH STATEMENT EXECUTE FUNCTION #{TRIGGER_FUNCTION_NAME}();
+ SQL
+
+ with_retries(connection) do
+ connection.execute(sql)
+ end
+ end
+
+ def unlock_writes
+ logger&.info "Database: '#{database_name}', Table: '#{table_name}': Allow Writes".color(:green)
+ sql = <<-SQL
+ DROP TRIGGER IF EXISTS #{write_trigger_name(table_name)} ON #{table_name}
+ SQL
+
+ with_retries(connection) do
+ connection.execute(sql)
+ end
+ end
+
+ private
+
+ attr_reader :table_name, :connection, :database_name, :logger
+
+ def with_retries(connection, &block)
+ with_statement_timeout_retries do
+ with_lock_retries(connection) do
+ yield
+ end
+ end
+ end
+
+ def with_statement_timeout_retries(times = 5)
+ current_iteration = 1
+ begin
+ yield
+ rescue ActiveRecord::QueryCanceled => err # rubocop:disable Database/RescueQueryCanceled
+ if current_iteration <= times
+ current_iteration += 1
+ retry
+ else
+ raise err
+ end
+ end
+ end
+
+ def with_lock_retries(connection, &block)
+ Gitlab::Database::WithLockRetries.new(
+ klass: "gitlab:db:lock_writes",
+ logger: logger || Gitlab::AppLogger,
+ connection: connection
+ ).run(&block)
+ end
+
+ def write_trigger_name(table_name)
+ "gitlab_schema_write_trigger_for_#{table_name}"
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 4bb1d71ce18..db39524f4f6 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -505,14 +505,14 @@ module Gitlab
# case another unique integer column can be used. Example: :user_id
#
# rubocop: disable Metrics/AbcSize
- def update_column_in_batches(table, column, value, batch_size: nil, batch_column_name: :id)
+ def update_column_in_batches(table_name, column, value, batch_size: nil, batch_column_name: :id, disable_lock_writes: false)
if transaction_open?
raise 'update_column_in_batches can not be run inside a transaction, ' \
'you can disable transactions by calling disable_ddl_transaction! ' \
'in the body of your migration class'
end
- table = Arel::Table.new(table)
+ table = Arel::Table.new(table_name)
count_arel = table.project(Arel.star.count.as('count'))
count_arel = yield table, count_arel if block_given?
@@ -559,7 +559,10 @@ module Gitlab
update_arel = yield table, update_arel if block_given?
- execute(update_arel.to_sql)
+ transaction do
+ execute("SELECT set_config('lock_writes.#{table_name}', 'false', true)") if disable_lock_writes
+ execute(update_arel.to_sql)
+ end
# There are no more rows left to update.
break unless stop_row
@@ -1666,7 +1669,9 @@ into similar problems in the future (e.g. when new tables are created).
end
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.with_suppressed do
- update_column_in_batches(table, new, old_value, batch_column_name: batch_column_name)
+ Gitlab::Database::QueryAnalyzers::GitlabSchemasValidateConnection.with_suppressed do
+ update_column_in_batches(table, new, old_value, batch_column_name: batch_column_name, disable_lock_writes: true)
+ end
end
add_not_null_constraint(table, new) unless old_col.null
diff --git a/lib/gitlab/database/migrations/background_migration_helpers.rb b/lib/gitlab/database/migrations/background_migration_helpers.rb
index 9bffed43077..25e75a10bb3 100644
--- a/lib/gitlab/database/migrations/background_migration_helpers.rb
+++ b/lib/gitlab/database/migrations/background_migration_helpers.rb
@@ -76,7 +76,7 @@ module Gitlab
max = relation.arel_table[primary_column_name].maximum
min = relation.arel_table[primary_column_name].minimum
- start_id, end_id = relation.pluck(min, max).first
+ start_id, end_id = relation.pick(min, max)
# `SingleDatabaseWorker.bulk_perform_in` schedules all jobs for
# the same time, which is not helpful in most cases where we wish to
diff --git a/lib/gitlab/database/migrations/base_background_runner.rb b/lib/gitlab/database/migrations/base_background_runner.rb
index 2772502140e..a9440cafd30 100644
--- a/lib/gitlab/database/migrations/base_background_runner.rb
+++ b/lib/gitlab/database/migrations/base_background_runner.rb
@@ -38,7 +38,7 @@ module Gitlab
per_background_migration_result_dir = File.join(@result_dir, migration_name)
instrumentation = Instrumentation.new(result_dir: per_background_migration_result_dir)
- batch_names = (1..).each.lazy.map { |i| "batch_#{i}"}
+ batch_names = (1..).each.lazy.map { |i| "batch_#{i}" }
jobs.shuffle.each do |j|
break if run_until <= Time.current
diff --git a/lib/gitlab/database/migrations/batched_background_migration_helpers.rb b/lib/gitlab/database/migrations/batched_background_migration_helpers.rb
index 936b986ea07..363fd0598f9 100644
--- a/lib/gitlab/database/migrations/batched_background_migration_helpers.rb
+++ b/lib/gitlab/database/migrations/batched_background_migration_helpers.rb
@@ -24,7 +24,7 @@ module Gitlab
# class must be present in the Gitlab::BackgroundMigration module, and the batch class (if specified) must be
# present in the Gitlab::BackgroundMigration::BatchingStrategies module.
#
- # If migration with same job_class_name, table_name, column_name, and job_aruments already exists, this helper
+ # If migration with same job_class_name, table_name, column_name, and job_arguments already exists, this helper
# will log an warning and not create a new one.
#
# job_class_name - The background migration job class as a string
@@ -107,6 +107,11 @@ module Gitlab
status_event: status_event
)
+ if migration.job_class.respond_to?(:job_arguments_count) && migration.job_class.job_arguments_count != job_arguments.count
+ raise "Wrong number of job arguments for #{migration.job_class_name} " \
+ "(given #{job_arguments.count}, expected #{migration.job_class.job_arguments_count})"
+ end
+
# Below `BatchedMigration` attributes were introduced after the
# initial `batched_background_migrations` table was created, so any
# migrations that ran relying on initial table schema would not know
diff --git a/lib/gitlab/database/partitioning/sliding_list_strategy.rb b/lib/gitlab/database/partitioning/sliding_list_strategy.rb
index 5cf32d3272c..4b5349f0327 100644
--- a/lib/gitlab/database/partitioning/sliding_list_strategy.rb
+++ b/lib/gitlab/database/partitioning/sliding_list_strategy.rb
@@ -77,7 +77,6 @@ module Gitlab
end
def validate_and_fix
- return unless Feature.enabled?(:fix_sliding_list_partitioning)
return if no_partitions_exist?
old_default_value = current_default_value
diff --git a/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb b/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb
index 9cab2c51b3f..dcf457b9d63 100644
--- a/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb
+++ b/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb
@@ -25,7 +25,7 @@ module Gitlab
parent_batch_relation = relation_scoped_to_range(source_table, source_column, start_id, stop_id)
parent_batch_relation.each_batch(of: SUB_BATCH_SIZE) do |sub_batch|
- sub_start_id, sub_stop_id = sub_batch.pluck(Arel.sql("MIN(#{source_column}), MAX(#{source_column})")).first
+ sub_start_id, sub_stop_id = sub_batch.pick(Arel.sql("MIN(#{source_column}), MAX(#{source_column})"))
bulk_copy.copy_between(sub_start_id, sub_stop_id)
sleep(PAUSE_SECONDS)
diff --git a/lib/gitlab/database/postgres_hll/buckets.rb b/lib/gitlab/database/postgres_hll/buckets.rb
index 76818bbf340..cbc9544d905 100644
--- a/lib/gitlab/database/postgres_hll/buckets.rb
+++ b/lib/gitlab/database/postgres_hll/buckets.rb
@@ -38,7 +38,7 @@ module Gitlab
#
# @param other_buckets_hash hash with HyperLogLog structure representation
def merge_hash!(other_buckets_hash)
- buckets.merge!(other_buckets_hash) {|_key, old, new| new > old ? new : old }
+ buckets.merge!(other_buckets_hash) { |_key, old, new| new > old ? new : old }
end
# Serialize instance underlying HyperLogLog structure to JSON format, that can be stored in various persistence layers
@@ -61,7 +61,7 @@ module Gitlab
num_uniques = (
((TOTAL_BUCKETS**2) * (0.7213 / (1 + 1.079 / TOTAL_BUCKETS))) /
- (num_zero_buckets + buckets.values.sum { |bucket_hash| 2**(-1 * bucket_hash)} )
+ (num_zero_buckets + buckets.values.sum { |bucket_hash| 2**(-1 * bucket_hash) } )
).to_i
if num_zero_buckets > 0 && num_uniques < 2.5 * TOTAL_BUCKETS
diff --git a/lib/gitlab/database/reindexing.rb b/lib/gitlab/database/reindexing.rb
index e13dd3b2058..b96dffc99ac 100644
--- a/lib/gitlab/database/reindexing.rb
+++ b/lib/gitlab/database/reindexing.rb
@@ -27,6 +27,7 @@ module Gitlab
# Hack: Before we do actual reindexing work, create async indexes
Gitlab::Database::AsyncIndexes.create_pending_indexes! if Feature.enabled?(:database_async_index_creation, type: :ops)
+ Gitlab::Database::AsyncIndexes.drop_pending_indexes! if Feature.enabled?(:database_async_index_destruction, type: :ops)
automatic_reindexing
end
diff --git a/lib/gitlab/database/reindexing/reindex_concurrently.rb b/lib/gitlab/database/reindexing/reindex_concurrently.rb
index 152935bd734..60fa4deda39 100644
--- a/lib/gitlab/database/reindexing/reindex_concurrently.rb
+++ b/lib/gitlab/database/reindexing/reindex_concurrently.rb
@@ -20,7 +20,7 @@ module Gitlab
def perform
raise ReindexError, 'indexes serving an exclusion constraint are currently not supported' if index.exclusion?
- raise ReindexError, 'index is a left-over temporary index from a previous reindexing run' if index.name =~ /#{TEMPORARY_INDEX_PATTERN}/
+ raise ReindexError, 'index is a left-over temporary index from a previous reindexing run' if index.name =~ /#{TEMPORARY_INDEX_PATTERN}/o
# Expression indexes require additional statistics in `pg_statistic`:
# select * from pg_statistic where starelid = (select oid from pg_class where relname = 'some_index');
@@ -81,10 +81,10 @@ module Gitlab
# Example lingering index name: some_index_ccnew1
# Example prefix: 'some_index'
- prefix = lingering_index.name.gsub(/#{TEMPORARY_INDEX_PATTERN}/, '')
+ prefix = lingering_index.name.gsub(/#{TEMPORARY_INDEX_PATTERN}/o, '')
# Example suffix: '_ccnew1'
- suffix = lingering_index.name.match(/#{TEMPORARY_INDEX_PATTERN}/)[0]
+ suffix = lingering_index.name.match(/#{TEMPORARY_INDEX_PATTERN}/o)[0]
# Only remove if the lingering index name could have been chosen
# as a result of a REINDEX operation (considering that PostgreSQL
diff --git a/lib/gitlab/database/with_lock_retries.rb b/lib/gitlab/database/with_lock_retries.rb
index f2c5bb9088f..3206c5626c3 100644
--- a/lib/gitlab/database/with_lock_retries.rb
+++ b/lib/gitlab/database/with_lock_retries.rb
@@ -83,7 +83,7 @@ module Gitlab
# @param [Boolean] raise_on_exhaustion whether to raise `AttemptsExhaustedError` when exhausting max attempts
# @param [Proc] block of code that will be executed
def run(raise_on_exhaustion: false, &block)
- raise 'no block given' unless block_given?
+ raise 'no block given' unless block
@block = block