From b5c69ce3abed5f8269dee256fca02d3e74b30347 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 5 Feb 2018 16:22:19 +0100 Subject: [PATCH] Retry migration removing stages in case of duplicates --- ...121225_remove_redundant_pipeline_stages.rb | 21 +++++++++++++++---- .../remove_redundant_pipeline_stages_spec.rb | 9 ++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/db/post_migrate/20180119121225_remove_redundant_pipeline_stages.rb b/db/post_migrate/20180119121225_remove_redundant_pipeline_stages.rb index be5a80261c0..9644cfabb60 100644 --- a/db/post_migrate/20180119121225_remove_redundant_pipeline_stages.rb +++ b/db/post_migrate/20180119121225_remove_redundant_pipeline_stages.rb @@ -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 ( diff --git a/spec/migrations/remove_redundant_pipeline_stages_spec.rb b/spec/migrations/remove_redundant_pipeline_stages_spec.rb index 3bd2a9a2146..b2b6446f2c8 100644 --- a/spec/migrations/remove_redundant_pipeline_stages_spec.rb +++ b/spec/migrations/remove_redundant_pipeline_stages_spec.rb @@ -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