59 lines
1.8 KiB
Ruby
59 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class RescheduleMergeRequestDiffUsersBackgroundMigration < ActiveRecord::Migration[6.1]
|
|
include Gitlab::Database::MigrationHelpers
|
|
|
|
disable_ddl_transaction!
|
|
|
|
# The number of rows to process in a single migration job.
|
|
#
|
|
# The minimum interval for background migrations is two minutes. On staging we
|
|
# observed we can process roughly 20 000 rows in a minute. Based on the total
|
|
# number of rows on staging, this translates to a total processing time of
|
|
# roughly 14 days.
|
|
#
|
|
# By using a batch size of 40 000, we maintain a rate of roughly 20 000 rows
|
|
# per minute, hopefully keeping the total migration time under two weeks;
|
|
# instead of four weeks.
|
|
BATCH_SIZE = 40_000
|
|
|
|
MIGRATION_NAME = 'MigrateMergeRequestDiffCommitUsers'
|
|
|
|
class MergeRequestDiff < ActiveRecord::Base
|
|
self.table_name = 'merge_request_diffs'
|
|
end
|
|
|
|
def up
|
|
start = MergeRequestDiff.minimum(:id).to_i
|
|
max = MergeRequestDiff.maximum(:id).to_i
|
|
delay = BackgroundMigrationWorker.minimum_interval
|
|
|
|
Gitlab::Database::BackgroundMigrationJob
|
|
.where(class_name: MIGRATION_NAME)
|
|
.delete_all
|
|
|
|
# The table merge_request_diff_commits contains _a lot_ of rows (roughly 400
|
|
# 000 000 on staging). Iterating a table that large to determine job ranges
|
|
# would take a while.
|
|
#
|
|
# To avoid that overhead, we simply schedule fixed ranges according to the
|
|
# minimum and maximum IDs. The background migration in turn only processes
|
|
# rows that actually exist.
|
|
while start < max
|
|
stop = start + BATCH_SIZE
|
|
|
|
migrate_in(delay, MIGRATION_NAME, [start, stop])
|
|
|
|
Gitlab::Database::BackgroundMigrationJob
|
|
.create!(class_name: MIGRATION_NAME, arguments: [start, stop])
|
|
|
|
delay += BackgroundMigrationWorker.minimum_interval
|
|
start += BATCH_SIZE
|
|
end
|
|
end
|
|
|
|
def down
|
|
# no-op
|
|
end
|
|
end
|