Add swap_primary_key database helper
Ref: #374743 (closed)
What does this MR do and why?
This MR adds a new migration helper method to swap primary key using a predefined index easily.
Why do we need this?
This is required in order to partition a table, the partition key must be include in the primary key.
It was brought up in !97926 (comment 1107227533) that we need to change the primary key of a table we are currently partitioning ci_builds_metadata
.
This MR simplifies the process to swap the primary key.
Fake migration test
class SwapPrimaryKey < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
TABLE_NAME = :ci_builds_metadata
PRIMARY_KEY = :ci_builds_metadata_pkey
OLD_INDEX_NAME = :index_ci_builds_metadata_on_id_unique
NEW_INDEX_NAME = :index_ci_builds_metadata_on_id_partition_id_unique
def up
swap_primary_key(TABLE_NAME, PRIMARY_KEY, NEW_INDEX_NAME)
end
def down
add_concurrent_index(TABLE_NAME, :id, unique: true, name: OLD_INDEX_NAME)
add_concurrent_index(TABLE_NAME, [:id, :partition_id], unique: true, name: NEW_INDEX_NAME)
unswap_primary_key(TABLE_NAME, PRIMARY_KEY, OLD_INDEX_NAME)
end
end
Database changes
ci: == 20220922140645 SwapPrimaryKey: migrating ===================================
ci: -- transaction_open?()
ci: -> 0.0000s
ci: -- quote_table_name(:ci_builds_metadata)
ci: -> 0.0000s
ci: -- quote_column_name(:ci_builds_metadata_pkey)
ci: -> 0.0000s
ci: -- execute("ALTER TABLE \"ci_builds_metadata\" DROP CONSTRAINT \"ci_builds_metadata_pkey\" CASCADE\n")
ci: -> 0.0009s
ci: -- rename_index(:ci_builds_metadata, :index_ci_builds_metadata_on_id_partition_id_unique, :ci_builds_metadata_pkey)
ci: -> 0.0008s
ci: -- quote_table_name(:ci_builds_metadata)
ci: -> 0.0000s
ci: -- quote_table_name(:ci_builds_metadata_pkey)
ci: -> 0.0000s
ci: -- quote_table_name(:ci_builds_metadata_pkey)
ci: -> 0.0000s
ci: -- execute("ALTER TABLE \"ci_builds_metadata\" ADD CONSTRAINT \"ci_builds_metadata_pkey\" PRIMARY KEY USING INDEX \"ci_builds_metadata_pkey\"\n")
ci: -> 0.0011s
ci: == 20220922140645 SwapPrimaryKey: migrated (0.0163s) ==========================
------------------------ROLLBACK------------------------------
ci: == 20220922140645 SwapPrimaryKey: reverting ===================================
ci: -- transaction_open?()
ci: -> 0.0000s
ci: -- index_exists?(:ci_builds_metadata, :id, {:unique=>true, :name=>:index_ci_builds_metadata_on_id_unique, :algorithm=>:concurrently})
ci: -> 0.0056s
ci: -- execute("SET statement_timeout TO 0")
ci: -> 0.0001s
ci: -- add_index(:ci_builds_metadata, :id, {:unique=>true, :name=>:index_ci_builds_metadata_on_id_unique, :algorithm=>:concurrently})
ci: -> 0.0016s
ci: -- execute("RESET statement_timeout")
ci: -> 0.0001s
ci: -- transaction_open?()
ci: -> 0.0000s
ci: -- index_exists?(:ci_builds_metadata, [:id, :partition_id], {:unique=>true, :name=>:index_ci_builds_metadata_on_id_partition_id_unique, :algorithm=>:concurrently})
ci: -> 0.0020s
ci: -- add_index(:ci_builds_metadata, [:id, :partition_id], {:unique=>true, :name=>:index_ci_builds_metadata_on_id_partition_id_unique, :algorithm=>:concurrently})
ci: -> 0.0011s
ci: -- transaction_open?()
ci: -> 0.0000s
ci: -- quote_table_name(:ci_builds_metadata)
ci: -> 0.0000s
ci: -- quote_column_name(:ci_builds_metadata_pkey)
ci: -> 0.0000s
ci: -- execute("ALTER TABLE \"ci_builds_metadata\" DROP CONSTRAINT \"ci_builds_metadata_pkey\" CASCADE\n")
ci: -> 0.0008s
ci: -- rename_index(:ci_builds_metadata, :index_ci_builds_metadata_on_id_unique, :ci_builds_metadata_pkey)
ci: -> 0.0003s
ci: -- quote_table_name(:ci_builds_metadata)
ci: -> 0.0000s
ci: -- quote_table_name(:ci_builds_metadata_pkey)
ci: -> 0.0000s
ci: -- quote_table_name(:ci_builds_metadata_pkey)
ci: -> 0.0000s
ci: -- execute("ALTER TABLE \"ci_builds_metadata\" ADD CONSTRAINT \"ci_builds_metadata_pkey\" PRIMARY KEY USING INDEX \"ci_builds_metadata_pkey\"\n")
ci: -> 0.0004s
ci: == 20220922140645 SwapPrimaryKey: reverted (0.0241s) ==========================
Indexes:
- "ci_builds_metadata_pkey" PRIMARY KEY, btree (id)
+ "ci_builds_metadata_pkey" PRIMARY KEY, btree (id, partition_id)
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Edited by Max Orefice