-
Notifications
You must be signed in to change notification settings - Fork 51
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Describe the feature
It would be great if pg-schema-diff can support swapping primary keys instead of dropping and re-adding.
For example (I used pg-schema-diff 1.0.2 for this), here is a before schema:
CREATE SEQUENCE test_id_seq START WITH 1 NO MINVALUE NO MAXVALUE CACHE 1;
CREATE TABLE test (
id BIGINT DEFAULT nextval('test_id_seq') NOT NULL,
project_id BIGINT NOT NULL,
PRIMARY KEY (id)
);and an after schema:
CREATE SEQUENCE test_id_seq START WITH 1 NO MINVALUE NO MAXVALUE CACHE 1;
CREATE TABLE test (
id BIGINT DEFAULT nextval('test_id_seq') NOT NULL,
project_id BIGINT NOT NULL,
PRIMARY KEY (project_id, id)
);This is the diff it generates:
/*
Statement 0
- ACQUIRES_ACCESS_EXCLUSIVE_LOCK: Index drops will lock out all accesses to the table. They should be fast.
- INDEX_DROPPED: Dropping this index means queries that use this index might perform worse because they will no longer will be able to leverage it.
*/
SET SESSION statement_timeout = 3000;
SET SESSION lock_timeout = 3000;
ALTER TABLE "public"."test" DROP CONSTRAINT "test_pkey";
/*
Statement 1
- INDEX_BUILD: This might affect database performance. Concurrent index builds require a non-trivial amount of CPU, potentially affecting database performance. They also can take a while but do not lock out writes.
*/
SET SESSION statement_timeout = 1200000;
SET SESSION lock_timeout = 3000;
CREATE UNIQUE INDEX CONCURRENTLY test_pkey ON public.test USING btree (project_id, id);
/*
Statement 2
*/
SET SESSION statement_timeout = 3000;
SET SESSION lock_timeout = 3000;
ALTER TABLE "public"."test" ADD CONSTRAINT "test_pkey" PRIMARY KEY USING INDEX "test_pkey";However, I think a swap can be done instead with something like:
-- test_pkey_v2 is used as an example, but a temp name like used in other pg-schema-diff operations would work
CREATE UNIQUE INDEX CONCURRENTLY test_pkey_v2 ON public.test USING btree (project_id, id);
ALTER TABLE "public"."test" DROP CONSTRAINT "test_pkey", ADD CONSTRAINT "test_pkey" PRIMARY KEY USING INDEX "test_pkey_v2";Motivation
The primary key replacement would be atomic and the table would never be in a state without a primary key + index triggering full scans.
kyrsideris
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request