Commit 99f7b03e authored by Krasimir Angelov's avatar Krasimir Angelov Committed by GitLab Release Tools Bot

Merge branch '360556-batched-background-migrations-instance-upgrades' into 'master'

Resolve "Batched background migrations - Add steal method"

See merge request gitlab-org/gitlab!86551

(cherry picked from commit c1e6688924fd6cf4fce43e35a7015f10304e3802)

4ec02f8d Add steal method for BatchedBackgroundMigrationHelpers
parent e7b75f38
...@@ -943,7 +943,7 @@ module Gitlab ...@@ -943,7 +943,7 @@ module Gitlab
execute("DELETE FROM batched_background_migrations WHERE #{conditions}") execute("DELETE FROM batched_background_migrations WHERE #{conditions}")
end end
def ensure_batched_background_migration_is_finished(job_class_name:, table_name:, column_name:, job_arguments:) def ensure_batched_background_migration_is_finished(job_class_name:, table_name:, column_name:, job_arguments:, finalize: true)
migration = Gitlab::Database::BackgroundMigration::BatchedMigration migration = Gitlab::Database::BackgroundMigration::BatchedMigration
.for_configuration(job_class_name, table_name, column_name, job_arguments).first .for_configuration(job_class_name, table_name, column_name, job_arguments).first
...@@ -954,9 +954,13 @@ module Gitlab ...@@ -954,9 +954,13 @@ module Gitlab
job_arguments: job_arguments job_arguments: job_arguments
} }
if migration.nil? return Gitlab::AppLogger.warn "Could not find batched background migration for the given configuration: #{configuration}" if migration.nil?
Gitlab::AppLogger.warn "Could not find batched background migration for the given configuration: #{configuration}"
elsif !migration.finished? return if migration.finished?
Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.finalize(job_class_name, table_name, column_name, job_arguments, connection: connection) if finalize
unless migration.reload.finished? # rubocop:disable Cop/ActiveRecordAssociationReload
raise "Expected batched background migration for the given configuration to be marked as 'finished', " \ raise "Expected batched background migration for the given configuration to be marked as 'finished', " \
"but it is '#{migration.status_name}':" \ "but it is '#{migration.status_name}':" \
"\t#{configuration}" \ "\t#{configuration}" \
......
...@@ -122,6 +122,14 @@ module Gitlab ...@@ -122,6 +122,14 @@ module Gitlab
migration.save! migration.save!
migration migration
end end
def finalize_batched_background_migration(job_class_name:, table_name:, column_name:, job_arguments:)
migration = Gitlab::Database::BackgroundMigration::BatchedMigration.find_for_configuration(job_class_name, table_name, column_name, job_arguments)
raise 'Could not find batched background migration' if migration.nil?
Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.finalize(job_class_name, table_name, column_name, job_arguments, connection: connection)
end
end end
end end
end end
......
...@@ -2210,12 +2210,17 @@ RSpec.describe Gitlab::Database::MigrationHelpers do ...@@ -2210,12 +2210,17 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end end
describe '#ensure_batched_background_migration_is_finished' do describe '#ensure_batched_background_migration_is_finished' do
let(:job_class_name) { 'CopyColumnUsingBackgroundMigrationJob' }
let(:table) { :events }
let(:column_name) { :id }
let(:job_arguments) { [["id"], ["id_convert_to_bigint"], nil] }
let(:configuration) do let(:configuration) do
{ {
job_class_name: 'CopyColumnUsingBackgroundMigrationJob', job_class_name: job_class_name,
table_name: :events, table_name: table,
column_name: :id, column_name: column_name,
job_arguments: [["id"], ["id_convert_to_bigint"], nil] job_arguments: job_arguments
} }
end end
...@@ -2224,6 +2229,10 @@ RSpec.describe Gitlab::Database::MigrationHelpers do ...@@ -2224,6 +2229,10 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
it 'raises an error when migration exists and is not marked as finished' do it 'raises an error when migration exists and is not marked as finished' do
create(:batched_background_migration, :active, configuration) create(:batched_background_migration, :active, configuration)
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
allow(runner).to receive(:finalize).with(job_class_name, table, column_name, job_arguments).and_return(false)
end
expect { ensure_batched_background_migration_is_finished } expect { ensure_batched_background_migration_is_finished }
.to raise_error "Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':" \ .to raise_error "Expected batched background migration for the given configuration to be marked as 'finished', but it is 'active':" \
"\t#{configuration}" \ "\t#{configuration}" \
...@@ -2251,6 +2260,28 @@ RSpec.describe Gitlab::Database::MigrationHelpers do ...@@ -2251,6 +2260,28 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
expect { ensure_batched_background_migration_is_finished } expect { ensure_batched_background_migration_is_finished }
.not_to raise_error .not_to raise_error
end end
it 'finalizes the migration' do
migration = create(:batched_background_migration, :active, configuration)
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
expect(runner).to receive(:finalize).with(job_class_name, table, column_name, job_arguments).and_return(migration.finish!)
end
ensure_batched_background_migration_is_finished
end
context 'when the flag finalize is false' do
it 'does not finalize the migration' do
create(:batched_background_migration, :active, configuration)
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
expect(runner).not_to receive(:finalize).with(job_class_name, table, column_name, job_arguments)
end
expect { model.ensure_batched_background_migration_is_finished(**configuration.merge(finalize: false)) }.to raise_error(RuntimeError)
end
end
end end
describe '#index_exists_by_name?' do describe '#index_exists_by_name?' do
......
...@@ -163,4 +163,24 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers d ...@@ -163,4 +163,24 @@ RSpec.describe Gitlab::Database::Migrations::BatchedBackgroundMigrationHelpers d
end end
end end
end end
describe '#finalize_batched_background_migration' do
let!(:batched_migration) { create(:batched_background_migration, job_class_name: 'MyClass', table_name: :projects, column_name: :id, job_arguments: []) }
it 'finalizes the migration' do
allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
expect(runner).to receive(:finalize).with('MyClass', :projects, :id, [])
end
migration.finalize_batched_background_migration(job_class_name: 'MyClass', table_name: :projects, column_name: :id, job_arguments: [])
end
context 'when the migration does not exist' do
it 'raises an exception' do
expect do
migration.finalize_batched_background_migration(job_class_name: 'MyJobClass', table_name: :projects, column_name: :id, job_arguments: [])
end.to raise_error(RuntimeError, 'Could not find batched background migration')
end
end
end
end end
...@@ -9,9 +9,11 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration do ...@@ -9,9 +9,11 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration do
let_it_be(:migration) { described_class::MIGRATION } let_it_be(:migration) { described_class::MIGRATION }
describe '#up' do describe '#up' do
shared_examples 'raises migration not finished exception' do shared_examples 'finalizes the migration' do
it 'raises exception' do it 'finalizes the migration' do
expect { migrate! }.to raise_error(/Expected batched background migration for the given configuration to be marked as 'finished'/) allow_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |runner|
expect(runner).to receive(:finalize).with('"ProjectNamespaces::BackfillProjectNamespaces"', :projects, :id, [nil, "up"])
end
end end
end end
...@@ -61,7 +63,7 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration do ...@@ -61,7 +63,7 @@ RSpec.describe FinalizeProjectNamespacesBackfill, :migration do
project_namespace_backfill.update!(status: status) project_namespace_backfill.update!(status: status)
end end
it_behaves_like 'raises migration not finished exception' it_behaves_like 'finalizes the migration'
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment