Commit 6cb5b7c8 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Recover from unique constraint violation in stages migration

parent 378b2bad
...@@ -3,7 +3,7 @@ class ScheduleBuildStageMigration < ActiveRecord::Migration ...@@ -3,7 +3,7 @@ class ScheduleBuildStageMigration < ActiveRecord::Migration
DOWNTIME = false DOWNTIME = false
MIGRATION = 'MigrateBuildStage'.freeze MIGRATION = 'MigrateBuildStage'.freeze
BATCH_SIZE = 500 BATCH_SIZE = 800
disable_ddl_transaction! disable_ddl_transaction!
......
...@@ -13,19 +13,20 @@ module Gitlab ...@@ -13,19 +13,20 @@ module Gitlab
class Build < ActiveRecord::Base class Build < ActiveRecord::Base
self.table_name = 'ci_builds' self.table_name = 'ci_builds'
def ensure_stage! def ensure_stage!(attempts: 2)
find || create! find_stage || create_stage!
rescue ActiveRecord::RecordNotUnique rescue ActiveRecord::RecordNotUnique
# TODO retry if (attempts -= 1) > 0
raise
end end
def find def find_stage
Stage.find_by(name: self.stage, Stage.find_by(name: self.stage || 'test',
pipeline_id: self.commit_id, pipeline_id: self.commit_id,
project_id: self.project_id) project_id: self.project_id)
end end
def create! def create_stage!
Stage.create!(name: self.stage || 'test', Stage.create!(name: self.stage || 'test',
pipeline_id: self.commit_id, pipeline_id: self.commit_id,
project_id: self.project_id) project_id: self.project_id)
...@@ -34,11 +35,10 @@ module Gitlab ...@@ -34,11 +35,10 @@ module Gitlab
end end
def perform(start_id, stop_id) def perform(start_id, stop_id)
# TODO, should we disable_statement_timeout? # TODO, statement timeout?
# TODO, use plain SQL query?
stages = Migratable::Build.where('stage_id IS NULL') stages = Migratable::Build.where('stage_id IS NULL')
.where("id BETWEEN #{start_id.to_i} AND #{stop_id.to_i}") .where('id BETWEEN ? AND ?', start_id, stop_id)
.map { |build| build.ensure_stage! } .map { |build| build.ensure_stage! }
.compact.map(&:id) .compact.map(&:id)
......
...@@ -40,4 +40,15 @@ describe Gitlab::BackgroundMigration::MigrateBuildStage, :migration, schema: 201 ...@@ -40,4 +40,15 @@ describe Gitlab::BackgroundMigration::MigrateBuildStage, :migration, schema: 201
STATUSES[:failed], STATUSES[:failed],
STATUSES[:pending]] STATUSES[:pending]]
end end
it 'recovers from unique constraint violation only twice' do
allow(described_class::Migratable::Stage)
.to receive(:find_by).and_return(nil)
expect(described_class::Migratable::Stage)
.to receive(:find_by).exactly(3).times
expect { described_class.new.perform(1, 6) }
.to raise_error ActiveRecord::RecordNotUnique
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