Commit 024cd6e8 authored by Yannis Roussos's avatar Yannis Roussos

Merge branch 'ab/reindexing-guard-lingering' into 'master'

Exclude temporary indexes from reindexing

See merge request gitlab-org/gitlab!43992
parents 5f5ff212 0d8d12ee
...@@ -21,6 +21,8 @@ module Gitlab ...@@ -21,6 +21,8 @@ module Gitlab
limit(how_many).order(Arel.sql('RANDOM()')) limit(how_many).order(Arel.sql('RANDOM()'))
end end
scope :not_match, ->(regex) { where("name !~ ?", regex)}
def to_s def to_s
name name
end end
......
...@@ -10,6 +10,13 @@ module Gitlab ...@@ -10,6 +10,13 @@ module Gitlab
end end
end end
end end
def self.candidate_indexes
Gitlab::Database::PostgresIndex
.regular
.not_match("^#{ConcurrentReindex::TEMPORARY_INDEX_PREFIX}")
.not_match("^#{ConcurrentReindex::REPLACED_INDEX_PREFIX}")
end
end end
end end
end end
...@@ -24,6 +24,7 @@ module Gitlab ...@@ -24,6 +24,7 @@ module Gitlab
raise ReindexError, 'UNIQUE indexes are currently not supported' if index.unique? raise ReindexError, 'UNIQUE indexes are currently not supported' if index.unique?
raise ReindexError, 'partitioned indexes are currently not supported' if index.partitioned? raise ReindexError, 'partitioned indexes are currently not supported' if index.partitioned?
raise ReindexError, 'indexes serving an exclusion constraint are currently not supported' if index.exclusion? raise ReindexError, 'indexes serving an exclusion constraint are currently not supported' if index.exclusion?
raise ReindexError, 'index is a left-over temporary index from a previous reindexing run' if index.name.start_with?(TEMPORARY_INDEX_PREFIX, REPLACED_INDEX_PREFIX)
logger.info "Starting reindex of #{index}" logger.info "Starting reindex of #{index}"
......
...@@ -177,7 +177,7 @@ namespace :gitlab do ...@@ -177,7 +177,7 @@ namespace :gitlab do
indexes = if args[:index_name] indexes = if args[:index_name]
Gitlab::Database::PostgresIndex.by_identifier(args[:index_name]) Gitlab::Database::PostgresIndex.by_identifier(args[:index_name])
else else
Gitlab::Database::PostgresIndex.regular.random_few(2) Gitlab::Database::Reindexing.candidate_indexes.random_few(2)
end end
Gitlab::Database::Reindexing.perform(indexes) Gitlab::Database::Reindexing.perform(indexes)
......
...@@ -30,7 +30,7 @@ RSpec.describe Gitlab::Database::PostgresIndex do ...@@ -30,7 +30,7 @@ RSpec.describe Gitlab::Database::PostgresIndex do
end end
end end
describe '#regular' do describe '.regular' do
it 'only non-unique indexes' do it 'only non-unique indexes' do
expect(described_class.regular).to all(have_attributes(unique: false)) expect(described_class.regular).to all(have_attributes(unique: false))
end end
...@@ -44,7 +44,17 @@ RSpec.describe Gitlab::Database::PostgresIndex do ...@@ -44,7 +44,17 @@ RSpec.describe Gitlab::Database::PostgresIndex do
end end
end end
describe '#random_few' do describe '.not_match' do
it 'excludes indexes matching the given regex' do
expect(described_class.not_match('^bar_k').map(&:name)).to all(match(/^(?!bar_k).*/))
end
it 'matches indexes without this prefix regex' do
expect(described_class.not_match('^bar_k')).not_to be_empty
end
end
describe '.random_few' do
it 'limits to two records by default' do it 'limits to two records by default' do
expect(described_class.random_few(2).size).to eq(2) expect(described_class.random_few(2).size).to eq(2)
end end
......
...@@ -58,6 +58,28 @@ RSpec.describe Gitlab::Database::Reindexing::ConcurrentReindex, '#perform' do ...@@ -58,6 +58,28 @@ RSpec.describe Gitlab::Database::Reindexing::ConcurrentReindex, '#perform' do
end end
end end
context 'when the index is a lingering temporary index from a previous reindexing run' do
context 'with the temporary index prefix' do
let(:index_name) { 'tmp_reindex_something' }
it 'raises an error' do
expect do
subject.perform
end.to raise_error(described_class::ReindexError, /left-over temporary index/)
end
end
context 'with the replaced index prefix' do
let(:index_name) { 'old_reindex_something' }
it 'raises an error' do
expect do
subject.perform
end.to raise_error(described_class::ReindexError, /left-over temporary index/)
end
end
end
context 'replacing the original index with a rebuilt copy' do context 'replacing the original index with a rebuilt copy' do
let(:replacement_name) { 'tmp_reindex_42' } let(:replacement_name) { 'tmp_reindex_42' }
let(:replaced_name) { 'old_reindex_42' } let(:replaced_name) { 'old_reindex_42' }
......
...@@ -52,4 +52,15 @@ RSpec.describe Gitlab::Database::Reindexing do ...@@ -52,4 +52,15 @@ RSpec.describe Gitlab::Database::Reindexing do
it_behaves_like 'reindexing' it_behaves_like 'reindexing'
end end
end end
describe '.candidate_indexes' do
subject { described_class.candidate_indexes }
it 'retrieves regular indexes that are no left-overs from previous runs' do
result = double
expect(Gitlab::Database::PostgresIndex).to receive_message_chain('regular.not_match.not_match').with(no_args).with('^tmp_reindex_').with('^old_reindex_').and_return(result)
expect(subject).to eq(result)
end
end
end end
...@@ -170,7 +170,7 @@ RSpec.describe 'gitlab:db namespace rake task' do ...@@ -170,7 +170,7 @@ RSpec.describe 'gitlab:db namespace rake task' do
context 'when no index_name is given' do context 'when no index_name is given' do
it 'rebuilds a random number of large indexes' do it 'rebuilds a random number of large indexes' do
expect(Gitlab::Database::PostgresIndex).to receive_message_chain('regular.random_few').and_return(indexes) expect(Gitlab::Database::Reindexing).to receive_message_chain('candidate_indexes.random_few').and_return(indexes)
expect(Gitlab::Database::Reindexing).to receive(:perform).with(indexes) expect(Gitlab::Database::Reindexing).to receive(:perform).with(indexes)
run_rake_task('gitlab:db:reindex') run_rake_task('gitlab:db:reindex')
......
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