Fix downgrades from 10.2-4 to 10.2-2 (#6383)

DESCRIPTION: Fixes a bug in `ALTER EXTENSION citus UPDATE`

We had a series of changes on columnar that made it impossible for a
Citus user to downgrade from 10.2-4 to 10.2-2. Since we test downgrades
to immediate previous versions, we did not capture this in our tests.
Here are the series of changes.

- `10.2-1` introduced a btree index named
`columnar.stripe_first_row_number_idx`
- `10.2-3` had a unique index with the same name. To accomplish that, we
dropped the btree index, and create a unique index with the same name.
- `10.2-4` introduced `columnar_ensure_am_depends_catalog()` that adds
pg_depend entries so that Columnar access method depended on objects
such as `stripe_first_row_number_idx`

If a user upgrades to `>=10.2-4` we create a dependency record, and this
prevents users from downgrading to an earlier version than `10.2-3`
since the downgrade file `columnar--10.2-3--10.2-2.sql` wanted to drop
the unique index and create a btree index instead. However this created
an error because columnar am depended on that index.

We do not usually like to update earlier migration versions, but there
is no other solution that I could think of.

## Notes to reviewer:

Consider reviewing the commits one by one.
- Commit#1 aims to improve downgrade scripts overall.
- Commit#2 documents the failure
- Commit#3 fixes the problem by updating all the files that attempted to
drop `stripe_first_row_number_idx` index.

Related: #6041
pull/6364/head
Hanefi Onaldi 2022-10-04 20:39:50 +03:00 committed by GitHub
commit e0f8666131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 7 deletions

View File

@ -10,6 +10,17 @@
--
-- To do that, drop stripe_first_row_number_idx and create a unique
-- constraint with the same name to keep the code change at minimum.
--
-- If we have a pg_depend entry for this index, we can not drop it as
-- the extension depends on it. Remove the pg_depend entry if it exists.
DELETE FROM pg_depend
WHERE classid = 'pg_am'::regclass::oid
AND objid IN (select oid from pg_am where amname = 'columnar')
AND objsubid = 0
AND refclassid = 'pg_class'::regclass::oid
AND refobjid = 'columnar.stripe_first_row_number_idx'::regclass::oid
AND refobjsubid = 0
AND deptype = 'n';
DROP INDEX columnar.stripe_first_row_number_idx;
ALTER TABLE columnar.stripe ADD CONSTRAINT stripe_first_row_number_idx
UNIQUE (storage_id, first_row_number);

View File

@ -8,5 +8,16 @@ DROP FUNCTION citus_internal.upgrade_columnar_storage(regclass);
DROP FUNCTION citus_internal.downgrade_columnar_storage(regclass);
-- drop "first_row_number" column and the index defined on it
--
-- If we have a pg_depend entry for this index, we can not drop it as
-- the extension depends on it. Remove the pg_depend entry if it exists.
DELETE FROM pg_depend
WHERE classid = 'pg_am'::regclass::oid
AND objid IN (select oid from pg_am where amname = 'columnar')
AND objsubid = 0
AND refclassid = 'pg_class'::regclass::oid
AND refobjid = 'columnar.stripe_first_row_number_idx'::regclass::oid
AND refobjsubid = 0
AND deptype = 'n';
DROP INDEX columnar.stripe_first_row_number_idx;
ALTER TABLE columnar.stripe DROP COLUMN first_row_number;

View File

@ -1,4 +1,14 @@
-- columnar--10.2-3--10.2-2.sql
--
-- If we have a pg_depend entry for this index, we can not drop it as
-- the extension depends on it. Remove the pg_depend entry if it exists.
DELETE FROM pg_depend
WHERE classid = 'pg_am'::regclass::oid
AND objid IN (select oid from pg_am where amname = 'columnar')
AND objsubid = 0
AND refclassid = 'pg_class'::regclass::oid
AND refobjid = 'columnar.stripe_first_row_number_idx'::regclass::oid
AND refobjsubid = 0
AND deptype = 'n';
ALTER TABLE columnar.stripe DROP CONSTRAINT stripe_first_row_number_idx;
CREATE INDEX stripe_first_row_number_idx ON columnar.stripe USING BTREE(storage_id, first_row_number);

View File

@ -909,6 +909,24 @@ SELECT * FROM multi_extension.print_extension_changes();
| function worker_fix_partition_shard_index_names(regclass,text,text) void
(4 rows)
-- There was a bug when downgrading to 10.2-2 from 10.2-4
-- Test that we do not have any issues with this particular downgrade
ALTER EXTENSION citus UPDATE TO '10.2-2';
ALTER EXTENSION citus UPDATE TO '10.2-4';
SELECT * FROM multi_extension.print_extension_changes();
previous_object | current_object
---------------------------------------------------------------------
(0 rows)
-- Test downgrade to 10.2-4 from 10.2-5
ALTER EXTENSION citus UPDATE TO '10.2-5';
ALTER EXTENSION citus UPDATE TO '10.2-4';
-- Should be empty result since upgrade+downgrade should be a no-op
SELECT * FROM multi_extension.print_extension_changes();
previous_object | current_object
---------------------------------------------------------------------
(0 rows)
-- Snapshot of state at 10.2-5
ALTER EXTENSION citus UPDATE TO '10.2-5';
SELECT * FROM multi_extension.print_extension_changes();
@ -916,9 +934,6 @@ SELECT * FROM multi_extension.print_extension_changes();
---------------------------------------------------------------------
(0 rows)
-- Test downgrade to 10.2-4 from 10.2-5
ALTER EXTENSION citus UPDATE TO '10.2-4';
ALTER EXTENSION citus UPDATE TO '10.2-5';
-- Make sure that we defined dependencies from all rel objects (tables,
-- indexes, sequences ..) to columnar table access method ...
SELECT pg_class.oid INTO columnar_schema_members

View File

@ -400,13 +400,21 @@ SELECT * FROM multi_extension.print_extension_changes();
ALTER EXTENSION citus UPDATE TO '10.2-4';
SELECT * FROM multi_extension.print_extension_changes();
-- Snapshot of state at 10.2-5
ALTER EXTENSION citus UPDATE TO '10.2-5';
-- There was a bug when downgrading to 10.2-2 from 10.2-4
-- Test that we do not have any issues with this particular downgrade
ALTER EXTENSION citus UPDATE TO '10.2-2';
ALTER EXTENSION citus UPDATE TO '10.2-4';
SELECT * FROM multi_extension.print_extension_changes();
-- Test downgrade to 10.2-4 from 10.2-5
ALTER EXTENSION citus UPDATE TO '10.2-4';
ALTER EXTENSION citus UPDATE TO '10.2-5';
ALTER EXTENSION citus UPDATE TO '10.2-4';
-- Should be empty result since upgrade+downgrade should be a no-op
SELECT * FROM multi_extension.print_extension_changes();
-- Snapshot of state at 10.2-5
ALTER EXTENSION citus UPDATE TO '10.2-5';
SELECT * FROM multi_extension.print_extension_changes();
-- Make sure that we defined dependencies from all rel objects (tables,
-- indexes, sequences ..) to columnar table access method ...