Commit b4def6d4 authored by Krasimir Angelov's avatar Krasimir Angelov

Finalize conversion to bigint for push_event_payloads

1. Ensure the migration of `event_id` to `event_id_convert_to_bigint` is
completed.
2. Copy indexes and FKs
3. Swap columns

See https://gitlab.com/gitlab-org/gitlab/-/issues/288005.

Changelog: other
parent f39f7d41
# frozen_string_literal: true
class FinalizePushEventPayloadsBigintConversion < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
TABLE_NAME = 'push_event_payloads'
INDEX_NAME = 'index_push_event_payloads_on_event_id_convert_to_bigint'
def up
ensure_batched_background_migration_is_finished(
job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
table_name: 'push_event_payloads',
column_name: 'event_id',
job_arguments: [["event_id"], ["event_id_convert_to_bigint"]]
)
swap_columns
end
def down
swap_columns
end
private
def swap_columns
add_concurrent_index TABLE_NAME, :event_id_convert_to_bigint, unique: true, name: INDEX_NAME
# Duplicate fk_36c74129da FK
add_concurrent_foreign_key TABLE_NAME, :events, column: :event_id_convert_to_bigint, on_delete: :cascade
with_lock_retries(safe: true) do
# Swap column names
rename_column TABLE_NAME, :event_id, :event_id_convert_to_bigint_tmp
rename_column TABLE_NAME, :event_id_convert_to_bigint, :event_id
rename_column TABLE_NAME, :event_id_convert_to_bigint_tmp, :event_id_convert_to_bigint
# Swap defaults
change_column_default TABLE_NAME, :event_id, nil
change_column_default TABLE_NAME, :event_id_convert_to_bigint, 0
# Swap PK constraint
execute "ALTER TABLE #{TABLE_NAME} DROP CONSTRAINT push_event_payloads_pkey"
rename_index TABLE_NAME, index_name(TABLE_NAME, column: :event_id), 'push_event_payloads_pkey'
execute "ALTER TABLE #{TABLE_NAME} ADD CONSTRAINT push_event_payloads_pkey PRIMARY KEY USING INDEX push_event_payloads_pkey"
# Drop FK fk_36c74129da
remove_foreign_key TABLE_NAME, name: concurrent_foreign_key_name(TABLE_NAME, :event_id)
# Change the name of the FK for event_id_convert_to_bigint to the FK name for event_id
execute <<~SQL
ALTER TABLE #{TABLE_NAME}
RENAME CONSTRAINT #{concurrent_foreign_key_name(TABLE_NAME, :event_id_convert_to_bigint)}
TO #{concurrent_foreign_key_name(TABLE_NAME, :event_id)}
SQL
end
end
end
750cda544df323be99452d53aaf39933c8584fc6754ece45263e131884d980d0
\ No newline at end of file
......@@ -17313,7 +17313,7 @@ ALTER SEQUENCE protected_tags_id_seq OWNED BY protected_tags.id;
CREATE TABLE push_event_payloads (
commit_count bigint NOT NULL,
event_id integer NOT NULL,
event_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
action smallint NOT NULL,
ref_type smallint NOT NULL,
commit_from bytea,
......@@ -17321,7 +17321,7 @@ CREATE TABLE push_event_payloads (
ref text,
commit_title character varying(70),
ref_count integer,
event_id_convert_to_bigint bigint DEFAULT 0 NOT NULL
event_id bigint NOT NULL
);
CREATE TABLE push_rules (
......@@ -389,12 +389,14 @@ module Gitlab
# * +logger+ - [Gitlab::JsonLogger]
# * +env+ - [Hash] custom environment hash, see the example with `DISABLE_LOCK_RETRIES`
def with_lock_retries(*args, **kwargs, &block)
raise_on_exhaustion = !!kwargs.delete(:safe)
merged_args = {
klass: self.class,
logger: Gitlab::BackgroundMigration::Logger
}.merge(kwargs)
Gitlab::Database::WithLockRetries.new(**merged_args).run(&block)
Gitlab::Database::WithLockRetries.new(**merged_args)
.run(raise_on_exhaustion: raise_on_exhaustion, &block)
end
def true_value
......
......@@ -2157,6 +2157,31 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
buffer.rewind
expect(buffer.read).to include("\"class\":\"#{model.class}\"")
end
using RSpec::Parameterized::TableSyntax
where(:safe, :raise_on_exhaustion) do
true | true
false | false
end
with_them do
it 'sets raise_on_exhaustion as requested' do
with_lock_retries = double
expect(Gitlab::Database::WithLockRetries).to receive(:new).and_return(with_lock_retries)
expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: raise_on_exhaustion)
model.with_lock_retries(env: env, logger: in_memory_logger, safe: safe) { }
end
end
it 'does not raise on exhaustion by default' do
with_lock_retries = double
expect(Gitlab::Database::WithLockRetries).to receive(:new).and_return(with_lock_retries)
expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: false)
model.with_lock_retries(env: env, logger: in_memory_logger) { }
end
end
describe '#backfill_iids' do
......
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