Retry migration removing stages in case of duplicates

parent 5f57c7a5
Pipeline #17103882 failed with stages
in 49 minutes and 45 seconds
......@@ -3,12 +3,15 @@ class RemoveRedundantPipelineStages < ActiveRecord::Migration
DOWNTIME = false
def up
remove_concurrent_index :ci_stages, [:pipeline_id, :name]
disable_ddl_transaction!
def up(attempts: 100)
remove_outdated_index!
remove_redundant_pipeline_stages!
add_concurrent_index :ci_stages, [:pipeline_id, :name], unique: true
add_unique_index!
rescue ActiveRecord::RecordNotUnique
retry if (attempts -= 1) > 0
raise
end
def down
......@@ -18,6 +21,16 @@ class RemoveRedundantPipelineStages < ActiveRecord::Migration
private
def remove_outdated_index!
return unless index_exists?(:ci_stages, [:pipeline_id, :name])
remove_concurrent_index :ci_stages, [:pipeline_id, :name]
end
def add_unique_index!
add_concurrent_index :ci_stages, [:pipeline_id, :name], unique: true
end
def remove_redundant_pipeline_stages!
redundant_stages_ids = <<~SQL
SELECT id FROM ci_stages WHERE (pipeline_id, name) IN (
......
......@@ -36,4 +36,13 @@ describe RemoveRedundantPipelineStages, :migration do
expect(builds.all.count).to eq 6
expect(builds.all.pluck(:stage_id).compact).to eq [102]
end
it 'retries when duplicated stages are being created during migration' do
allow(subject).to receive(:remove_outdated_index!)
expect(subject).to receive(:remove_redundant_pipeline_stages!).exactly(3).times
allow(subject).to receive(:add_unique_index!)
.and_raise(ActiveRecord::RecordNotUnique.new('Duplicated stages present!'))
expect { subject.up(attempts: 3) }.to raise_error ActiveRecord::RecordNotUnique
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