From 5305aa42460f6b4c943773f6d43d36cd7ad6a40e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96nder=20Kalac=C4=B1?= Date: Thu, 6 Jan 2022 09:48:34 +0100 Subject: [PATCH] Do not drop sequences when dropping metadata (#5584) Dropping sequences means we need to recreate and hence losing the sequence. With this commit, we keep the existing sequences such that resyncing wouldn't drop the sequence. We do that by breaking the dependency of the sequence from the table. --- .../distributed/commands/alter_table.c | 15 + .../distributed/metadata/metadata_sync.c | 10 +- .../distributed/sql/citus--10.2-4--11.0-1.sql | 2 + .../sql/downgrades/citus--11.0-1--10.2-4.sql | 1 + .../11.0-1.sql | 8 + .../latest.sql | 8 + .../distributed/worker/worker_drop_protocol.c | 116 +++++- src/include/distributed/metadata_sync.h | 5 +- src/test/regress/expected/multi_extension.out | 3 +- .../regress/expected/multi_metadata_sync.out | 29 +- .../resync_metadata_with_sequences.out | 356 ++++++++++++++++++ .../expected/start_stop_metadata_sync.out | 2 +- .../expected/upgrade_list_citus_objects.out | 3 +- src/test/regress/multi_mx_schedule | 1 + .../sql/resync_metadata_with_sequences.sql | 132 +++++++ 15 files changed, 674 insertions(+), 17 deletions(-) create mode 100644 src/backend/distributed/sql/udfs/worker_drop_sequence_dependency/11.0-1.sql create mode 100644 src/backend/distributed/sql/udfs/worker_drop_sequence_dependency/latest.sql create mode 100644 src/test/regress/expected/resync_metadata_with_sequences.out create mode 100644 src/test/regress/sql/resync_metadata_with_sequences.sql diff --git a/src/backend/distributed/commands/alter_table.c b/src/backend/distributed/commands/alter_table.c index 223a06318ea..6ecb3113000 100644 --- a/src/backend/distributed/commands/alter_table.c +++ b/src/backend/distributed/commands/alter_table.c @@ -1372,6 +1372,21 @@ ReplaceTable(Oid sourceId, Oid targetId, List *justBeforeDropCommands, schemaName, targetName); SendCommandToWorkersWithMetadata(workerChangeSequenceDependencyCommand); } + else if (ShouldSyncTableMetadata(sourceId)) + { + /* + * We are converting a citus local table to a distributed/reference table, + * so we should prevent dropping the sequence on the table. Otherwise, we'd + * lose track of the previous changes in the sequence. + */ + StringInfo command = makeStringInfo(); + + appendStringInfo(command, + "SELECT pg_catalog.worker_drop_sequence_dependency('%s');", + quote_qualified_identifier(schemaName, sourceName)); + + SendCommandToWorkersWithMetadata(command->data); + } } char *justBeforeDropCommand = NULL; diff --git a/src/backend/distributed/metadata/metadata_sync.c b/src/backend/distributed/metadata/metadata_sync.c index ecd01a2ab4e..0bc6c34eab3 100644 --- a/src/backend/distributed/metadata/metadata_sync.c +++ b/src/backend/distributed/metadata/metadata_sync.c @@ -898,8 +898,16 @@ MetadataDropCommands(void) dropSnapshotCommandList = list_concat(dropSnapshotCommandList, detachPartitionCommandList); + /* + * We are re-creating the metadata, so not lose track of the + * sequences by preventing them dropped via DROP TABLE. + */ + dropSnapshotCommandList = + lappend(dropSnapshotCommandList, + BREAK_CITUS_TABLE_SEQUENCE_DEPENDENCY_COMMAND); + dropSnapshotCommandList = lappend(dropSnapshotCommandList, - REMOVE_ALL_CLUSTERED_TABLES_COMMAND); + REMOVE_ALL_CITUS_TABLES_COMMAND); dropSnapshotCommandList = lappend(dropSnapshotCommandList, DELETE_ALL_NODES); dropSnapshotCommandList = lappend(dropSnapshotCommandList, diff --git a/src/backend/distributed/sql/citus--10.2-4--11.0-1.sql b/src/backend/distributed/sql/citus--10.2-4--11.0-1.sql index 1419ce1b220..b4b6cc5329d 100644 --- a/src/backend/distributed/sql/citus--10.2-4--11.0-1.sql +++ b/src/backend/distributed/sql/citus--10.2-4--11.0-1.sql @@ -8,6 +8,8 @@ #include "udfs/citus_internal_add_object_metadata/11.0-1.sql" #include "udfs/citus_run_local_command/11.0-1.sql" +#include "udfs/worker_drop_sequence_dependency/11.0-1.sql" + DROP FUNCTION IF EXISTS pg_catalog.master_apply_delete_command(text); DROP FUNCTION pg_catalog.master_get_table_metadata(text); diff --git a/src/backend/distributed/sql/downgrades/citus--11.0-1--10.2-4.sql b/src/backend/distributed/sql/downgrades/citus--11.0-1--10.2-4.sql index 8651d945e36..df823be930e 100644 --- a/src/backend/distributed/sql/downgrades/citus--11.0-1--10.2-4.sql +++ b/src/backend/distributed/sql/downgrades/citus--11.0-1--10.2-4.sql @@ -45,3 +45,4 @@ DROP FUNCTION pg_catalog.citus_check_cluster_node_health (); DROP FUNCTION pg_catalog.citus_internal_add_object_metadata(text, text[], text[], integer, integer); DROP FUNCTION pg_catalog.citus_run_local_command(text); +DROP FUNCTION pg_catalog.worker_drop_sequence_dependency(text); diff --git a/src/backend/distributed/sql/udfs/worker_drop_sequence_dependency/11.0-1.sql b/src/backend/distributed/sql/udfs/worker_drop_sequence_dependency/11.0-1.sql new file mode 100644 index 00000000000..f39cd90751b --- /dev/null +++ b/src/backend/distributed/sql/udfs/worker_drop_sequence_dependency/11.0-1.sql @@ -0,0 +1,8 @@ +DROP FUNCTION IF EXISTS pg_catalog.worker_drop_sequence_dependency(table_name text); + +CREATE OR REPLACE FUNCTION pg_catalog.worker_drop_sequence_dependency(table_name text) + RETURNS VOID + LANGUAGE C STRICT + AS 'MODULE_PATHNAME', $$worker_drop_sequence_dependency$$; +COMMENT ON FUNCTION pg_catalog.worker_drop_sequence_dependency(table_name text) + IS 'drop the Citus tables sequence dependency'; diff --git a/src/backend/distributed/sql/udfs/worker_drop_sequence_dependency/latest.sql b/src/backend/distributed/sql/udfs/worker_drop_sequence_dependency/latest.sql new file mode 100644 index 00000000000..f39cd90751b --- /dev/null +++ b/src/backend/distributed/sql/udfs/worker_drop_sequence_dependency/latest.sql @@ -0,0 +1,8 @@ +DROP FUNCTION IF EXISTS pg_catalog.worker_drop_sequence_dependency(table_name text); + +CREATE OR REPLACE FUNCTION pg_catalog.worker_drop_sequence_dependency(table_name text) + RETURNS VOID + LANGUAGE C STRICT + AS 'MODULE_PATHNAME', $$worker_drop_sequence_dependency$$; +COMMENT ON FUNCTION pg_catalog.worker_drop_sequence_dependency(table_name text) + IS 'drop the Citus tables sequence dependency'; diff --git a/src/backend/distributed/worker/worker_drop_protocol.c b/src/backend/distributed/worker/worker_drop_protocol.c index a78e2d7a7ce..c6494a2f21b 100644 --- a/src/backend/distributed/worker/worker_drop_protocol.c +++ b/src/backend/distributed/worker/worker_drop_protocol.c @@ -17,6 +17,10 @@ #include "access/heapam.h" #include "access/xact.h" #include "catalog/dependency.h" +#include "catalog/pg_depend.h" +#if PG_VERSION_NUM < PG_VERSION_13 +#include "catalog/pg_depend_d.h" +#endif #include "catalog/pg_foreign_server.h" #include "distributed/citus_ruleutils.h" #include "distributed/distribution_column.h" @@ -29,9 +33,14 @@ #include "utils/builtins.h" #include "utils/fmgroids.h" - PG_FUNCTION_INFO_V1(worker_drop_distributed_table); +PG_FUNCTION_INFO_V1(worker_drop_sequence_dependency); + +#if PG_VERSION_NUM < PG_VERSION_13 +static long deleteDependencyRecordsForSpecific(Oid classId, Oid objectId, char deptype, + Oid refclassId, Oid refobjectId); +#endif /* * worker_drop_distributed_table drops the distributed table with the given oid, @@ -153,3 +162,108 @@ worker_drop_distributed_table(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } + + +/* + * worker_drop_sequence_dependency is a UDF that removes the dependency + * of all the sequences for the given table. + * + * The main purpose of this UDF is to prevent dropping the sequences while + * re-creating the same table such as changing the shard count, converting + * a citus local table to a distributed table or re-syncing the metadata. + */ +Datum +worker_drop_sequence_dependency(PG_FUNCTION_ARGS) +{ + text *relationName = PG_GETARG_TEXT_P(0); + Oid relationId = ResolveRelationId(relationName, true); + + if (!OidIsValid(relationId)) + { + ereport(NOTICE, (errmsg("relation %s does not exist, skipping", + text_to_cstring(relationName)))); + PG_RETURN_VOID(); + } + + EnsureTableOwner(relationId); + + /* break the dependent sequences from the table */ + #if PG_VERSION_NUM >= PG_VERSION_13 + List *ownedSequences = getOwnedSequences(relationId); + #else + List *ownedSequences = getOwnedSequences(relationId, InvalidAttrNumber); + #endif + + Oid ownedSequenceOid = InvalidOid; + foreach_oid(ownedSequenceOid, ownedSequences) + { + /* the caller doesn't want to drop the sequence, so break the dependency */ + deleteDependencyRecordsForSpecific(RelationRelationId, ownedSequenceOid, + DEPENDENCY_AUTO, RelationRelationId, + relationId); + } + + if (list_length(ownedSequences) > 0) + { + /* if we delete at least one dependency, let next commands know */ + CommandCounterIncrement(); + } + + PG_RETURN_VOID(); +} + + +/* *INDENT-OFF* */ +#if PG_VERSION_NUM < PG_VERSION_13 + +/* + * This function is already available on PG 13+. + * deleteDependencyRecordsForSpecific -- delete all records with given depender + * classId/objectId, dependee classId/objectId, of the given deptype. + * Returns the number of records deleted. + */ +static long +deleteDependencyRecordsForSpecific(Oid classId, Oid objectId, char deptype, + Oid refclassId, Oid refobjectId) +{ + long count = 0; + Relation depRel; + ScanKeyData key[2]; + HeapTuple tup; + + depRel = table_open(DependRelationId, RowExclusiveLock); + + ScanKeyInit(&key[0], + Anum_pg_depend_classid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(classId)); + ScanKeyInit(&key[1], + Anum_pg_depend_objid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(objectId)); + + SysScanDesc scan = + systable_beginscan(depRel, DependDependerIndexId, true, + NULL, 2, key); + + while (HeapTupleIsValid(tup = systable_getnext(scan))) + { + Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup); + + if (depform->refclassid == refclassId && + depform->refobjid == refobjectId && + depform->deptype == deptype) + { + CatalogTupleDelete(depRel, &tup->t_self); + count++; + } + } + + systable_endscan(scan); + + table_close(depRel, RowExclusiveLock); + + return count; +} +#endif +/* *INDENT-ON* */ diff --git a/src/include/distributed/metadata_sync.h b/src/include/distributed/metadata_sync.h index b39b90502d4..324c8a86444 100644 --- a/src/include/distributed/metadata_sync.h +++ b/src/include/distributed/metadata_sync.h @@ -67,8 +67,11 @@ extern Oid GetAttributeTypeOid(Oid relationId, AttrNumber attnum); #define DELETE_ALL_NODES "TRUNCATE pg_dist_node CASCADE" #define DELETE_ALL_DISTRIBUTED_OBJECTS "TRUNCATE citus.pg_dist_object" -#define REMOVE_ALL_CLUSTERED_TABLES_COMMAND \ +#define REMOVE_ALL_CITUS_TABLES_COMMAND \ "SELECT worker_drop_distributed_table(logicalrelid::regclass::text) FROM pg_dist_partition" +#define BREAK_CITUS_TABLE_SEQUENCE_DEPENDENCY_COMMAND \ + "SELECT pg_catalog.worker_drop_sequence_dependency(logicalrelid::regclass::text) FROM pg_dist_partition" + #define DISABLE_DDL_PROPAGATION "SET citus.enable_ddl_propagation TO 'off'" #define ENABLE_DDL_PROPAGATION "SET citus.enable_ddl_propagation TO 'on'" #define DISABLE_OBJECT_PROPAGATION "SET citus.enable_object_propagation TO 'off'" diff --git a/src/test/regress/expected/multi_extension.out b/src/test/regress/expected/multi_extension.out index ec3b806ccf1..701b5e26fb0 100644 --- a/src/test/regress/expected/multi_extension.out +++ b/src/test/regress/expected/multi_extension.out @@ -1005,7 +1005,8 @@ SELECT * FROM multi_extension.print_extension_changes(); | function citus_disable_node(text,integer,boolean) void | function citus_internal_add_object_metadata(text,text[],text[],integer,integer) void | function citus_run_local_command(text) void -(9 rows) + | function worker_drop_sequence_dependency(text) void +(10 rows) DROP TABLE multi_extension.prev_objects, multi_extension.extension_diff; -- show running version diff --git a/src/test/regress/expected/multi_metadata_sync.out b/src/test/regress/expected/multi_metadata_sync.out index 6db1c40f292..f1cedaf1ce9 100644 --- a/src/test/regress/expected/multi_metadata_sync.out +++ b/src/test/regress/expected/multi_metadata_sync.out @@ -41,14 +41,15 @@ SELECT * FROM pg_dist_partition WHERE partmethod='h' AND repmodel='s'; -- Show that, with no MX tables, metadata snapshot contains only the delete commands, -- pg_dist_node entries and reference tables SELECT unnest(master_metadata_snapshot()) order by 1; - unnest + unnest --------------------------------------------------------------------- INSERT INTO pg_dist_node (nodeid, groupid, nodename, nodeport, noderack, hasmetadata, metadatasynced, isactive, noderole, nodecluster, shouldhaveshards) VALUES (1, 1, 'localhost', 57637, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE),(2, 2, 'localhost', 57638, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE) + SELECT pg_catalog.worker_drop_sequence_dependency(logicalrelid::regclass::text) FROM pg_dist_partition SELECT worker_drop_distributed_table(logicalrelid::regclass::text) FROM pg_dist_partition TRUNCATE citus.pg_dist_object TRUNCATE pg_dist_node CASCADE WITH distributed_object_data(typetext, objnames, objargs, distargumentindex, colocationid) AS (VALUES ('role', ARRAY['postgres']::text[], ARRAY[]::text[], -1, 0), ('database', ARRAY['regression']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['public']::text[], ARRAY[]::text[], -1, 0)) SELECT citus_internal_add_object_metadata(typetext, objnames, objargs, distargumentindex::int, colocationid::int) FROM distributed_object_data; -(5 rows) +(6 rows) -- this function is dropped in Citus10, added here for tests CREATE OR REPLACE FUNCTION pg_catalog.master_create_distributed_table(table_name regclass, @@ -97,6 +98,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; CREATE TABLE public.mx_test_table (col_1 integer, col_2 text NOT NULL, col_3 bigint DEFAULT nextval('public.mx_test_table_col_3_seq'::regclass) NOT NULL, col_4 bigint DEFAULT nextval('public.user_defined_seq'::regclass)) INSERT INTO pg_dist_node (nodeid, groupid, nodename, nodeport, noderack, hasmetadata, metadatasynced, isactive, noderole, nodecluster, shouldhaveshards) VALUES (1, 1, 'localhost', 57637, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE),(2, 2, 'localhost', 57638, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE) SELECT citus_internal_add_partition_metadata ('public.mx_test_table'::regclass, 'h', 'col_1', 0, 's') + SELECT pg_catalog.worker_drop_sequence_dependency(logicalrelid::regclass::text) FROM pg_dist_partition SELECT pg_catalog.worker_record_sequence_dependency('public.mx_test_table_col_3_seq'::regclass,'public.mx_test_table'::regclass,'col_3') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS public.mx_test_table_col_3_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS public.user_defined_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') @@ -107,7 +109,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; WITH distributed_object_data(typetext, objnames, objargs, distargumentindex, colocationid) AS (VALUES ('sequence', ARRAY['public', 'user_defined_seq']::text[], ARRAY[]::text[], -1, 0), ('sequence', ARRAY['public', 'mx_test_table_col_3_seq']::text[], ARRAY[]::text[], -1, 0), ('role', ARRAY['postgres']::text[], ARRAY[]::text[], -1, 0), ('database', ARRAY['regression']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['public']::text[], ARRAY[]::text[], -1, 0)) SELECT citus_internal_add_object_metadata(typetext, objnames, objargs, distargumentindex::int, colocationid::int) FROM distributed_object_data; WITH placement_data(shardid, shardstate, shardlength, groupid, placementid) AS (VALUES (1310000, 1, 0, 1, 100000), (1310001, 1, 0, 2, 100001), (1310002, 1, 0, 1, 100002), (1310003, 1, 0, 2, 100003), (1310004, 1, 0, 1, 100004), (1310005, 1, 0, 2, 100005), (1310006, 1, 0, 1, 100006), (1310007, 1, 0, 2, 100007)) SELECT citus_internal_add_placement_metadata(shardid, shardstate, shardlength, groupid, placementid) FROM placement_data; WITH shard_data(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) AS (VALUES ('public.mx_test_table'::regclass, 1310000, 't'::"char", '-2147483648', '-1610612737'), ('public.mx_test_table'::regclass, 1310001, 't'::"char", '-1610612736', '-1073741825'), ('public.mx_test_table'::regclass, 1310002, 't'::"char", '-1073741824', '-536870913'), ('public.mx_test_table'::regclass, 1310003, 't'::"char", '-536870912', '-1'), ('public.mx_test_table'::regclass, 1310004, 't'::"char", '0', '536870911'), ('public.mx_test_table'::regclass, 1310005, 't'::"char", '536870912', '1073741823'), ('public.mx_test_table'::regclass, 1310006, 't'::"char", '1073741824', '1610612735'), ('public.mx_test_table'::regclass, 1310007, 't'::"char", '1610612736', '2147483647')) SELECT citus_internal_add_shard_metadata(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) FROM shard_data; -(18 rows) +(19 rows) -- Show that CREATE INDEX commands are included in the metadata snapshot CREATE INDEX mx_index ON mx_test_table(col_2); @@ -123,6 +125,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; CREATE TABLE public.mx_test_table (col_1 integer, col_2 text NOT NULL, col_3 bigint DEFAULT nextval('public.mx_test_table_col_3_seq'::regclass) NOT NULL, col_4 bigint DEFAULT nextval('public.user_defined_seq'::regclass)) INSERT INTO pg_dist_node (nodeid, groupid, nodename, nodeport, noderack, hasmetadata, metadatasynced, isactive, noderole, nodecluster, shouldhaveshards) VALUES (1, 1, 'localhost', 57637, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE),(2, 2, 'localhost', 57638, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE) SELECT citus_internal_add_partition_metadata ('public.mx_test_table'::regclass, 'h', 'col_1', 0, 's') + SELECT pg_catalog.worker_drop_sequence_dependency(logicalrelid::regclass::text) FROM pg_dist_partition SELECT pg_catalog.worker_record_sequence_dependency('public.mx_test_table_col_3_seq'::regclass,'public.mx_test_table'::regclass,'col_3') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS public.mx_test_table_col_3_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS public.user_defined_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') @@ -133,7 +136,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; WITH distributed_object_data(typetext, objnames, objargs, distargumentindex, colocationid) AS (VALUES ('sequence', ARRAY['public', 'user_defined_seq']::text[], ARRAY[]::text[], -1, 0), ('sequence', ARRAY['public', 'mx_test_table_col_3_seq']::text[], ARRAY[]::text[], -1, 0), ('role', ARRAY['postgres']::text[], ARRAY[]::text[], -1, 0), ('database', ARRAY['regression']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['public']::text[], ARRAY[]::text[], -1, 0)) SELECT citus_internal_add_object_metadata(typetext, objnames, objargs, distargumentindex::int, colocationid::int) FROM distributed_object_data; WITH placement_data(shardid, shardstate, shardlength, groupid, placementid) AS (VALUES (1310000, 1, 0, 1, 100000), (1310001, 1, 0, 2, 100001), (1310002, 1, 0, 1, 100002), (1310003, 1, 0, 2, 100003), (1310004, 1, 0, 1, 100004), (1310005, 1, 0, 2, 100005), (1310006, 1, 0, 1, 100006), (1310007, 1, 0, 2, 100007)) SELECT citus_internal_add_placement_metadata(shardid, shardstate, shardlength, groupid, placementid) FROM placement_data; WITH shard_data(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) AS (VALUES ('public.mx_test_table'::regclass, 1310000, 't'::"char", '-2147483648', '-1610612737'), ('public.mx_test_table'::regclass, 1310001, 't'::"char", '-1610612736', '-1073741825'), ('public.mx_test_table'::regclass, 1310002, 't'::"char", '-1073741824', '-536870913'), ('public.mx_test_table'::regclass, 1310003, 't'::"char", '-536870912', '-1'), ('public.mx_test_table'::regclass, 1310004, 't'::"char", '0', '536870911'), ('public.mx_test_table'::regclass, 1310005, 't'::"char", '536870912', '1073741823'), ('public.mx_test_table'::regclass, 1310006, 't'::"char", '1073741824', '1610612735'), ('public.mx_test_table'::regclass, 1310007, 't'::"char", '1610612736', '2147483647')) SELECT citus_internal_add_shard_metadata(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) FROM shard_data; -(19 rows) +(20 rows) -- Show that schema changes are included in the metadata snapshot CREATE SCHEMA mx_testing_schema; @@ -150,6 +153,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; CREATE TABLE mx_testing_schema.mx_test_table (col_1 integer, col_2 text NOT NULL, col_3 bigint DEFAULT nextval('mx_testing_schema.mx_test_table_col_3_seq'::regclass) NOT NULL, col_4 bigint DEFAULT nextval('public.user_defined_seq'::regclass)) INSERT INTO pg_dist_node (nodeid, groupid, nodename, nodeport, noderack, hasmetadata, metadatasynced, isactive, noderole, nodecluster, shouldhaveshards) VALUES (1, 1, 'localhost', 57637, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE),(2, 2, 'localhost', 57638, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE) SELECT citus_internal_add_partition_metadata ('mx_testing_schema.mx_test_table'::regclass, 'h', 'col_1', 0, 's') + SELECT pg_catalog.worker_drop_sequence_dependency(logicalrelid::regclass::text) FROM pg_dist_partition SELECT pg_catalog.worker_record_sequence_dependency('mx_testing_schema.mx_test_table_col_3_seq'::regclass,'mx_testing_schema.mx_test_table'::regclass,'col_3') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS mx_testing_schema.mx_test_table_col_3_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS public.user_defined_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') @@ -160,7 +164,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; WITH distributed_object_data(typetext, objnames, objargs, distargumentindex, colocationid) AS (VALUES ('sequence', ARRAY['public', 'user_defined_seq']::text[], ARRAY[]::text[], -1, 0), ('sequence', ARRAY['mx_testing_schema', 'mx_test_table_col_3_seq']::text[], ARRAY[]::text[], -1, 0), ('role', ARRAY['postgres']::text[], ARRAY[]::text[], -1, 0), ('database', ARRAY['regression']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['public']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['mx_testing_schema']::text[], ARRAY[]::text[], -1, 0)) SELECT citus_internal_add_object_metadata(typetext, objnames, objargs, distargumentindex::int, colocationid::int) FROM distributed_object_data; WITH placement_data(shardid, shardstate, shardlength, groupid, placementid) AS (VALUES (1310000, 1, 0, 1, 100000), (1310001, 1, 0, 2, 100001), (1310002, 1, 0, 1, 100002), (1310003, 1, 0, 2, 100003), (1310004, 1, 0, 1, 100004), (1310005, 1, 0, 2, 100005), (1310006, 1, 0, 1, 100006), (1310007, 1, 0, 2, 100007)) SELECT citus_internal_add_placement_metadata(shardid, shardstate, shardlength, groupid, placementid) FROM placement_data; WITH shard_data(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) AS (VALUES ('mx_testing_schema.mx_test_table'::regclass, 1310000, 't'::"char", '-2147483648', '-1610612737'), ('mx_testing_schema.mx_test_table'::regclass, 1310001, 't'::"char", '-1610612736', '-1073741825'), ('mx_testing_schema.mx_test_table'::regclass, 1310002, 't'::"char", '-1073741824', '-536870913'), ('mx_testing_schema.mx_test_table'::regclass, 1310003, 't'::"char", '-536870912', '-1'), ('mx_testing_schema.mx_test_table'::regclass, 1310004, 't'::"char", '0', '536870911'), ('mx_testing_schema.mx_test_table'::regclass, 1310005, 't'::"char", '536870912', '1073741823'), ('mx_testing_schema.mx_test_table'::regclass, 1310006, 't'::"char", '1073741824', '1610612735'), ('mx_testing_schema.mx_test_table'::regclass, 1310007, 't'::"char", '1610612736', '2147483647')) SELECT citus_internal_add_shard_metadata(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) FROM shard_data; -(19 rows) +(20 rows) -- Show that append distributed tables are not included in the metadata snapshot CREATE TABLE non_mx_test_table (col_1 int, col_2 text); @@ -183,6 +187,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; CREATE TABLE mx_testing_schema.mx_test_table (col_1 integer, col_2 text NOT NULL, col_3 bigint DEFAULT nextval('mx_testing_schema.mx_test_table_col_3_seq'::regclass) NOT NULL, col_4 bigint DEFAULT nextval('public.user_defined_seq'::regclass)) INSERT INTO pg_dist_node (nodeid, groupid, nodename, nodeport, noderack, hasmetadata, metadatasynced, isactive, noderole, nodecluster, shouldhaveshards) VALUES (1, 1, 'localhost', 57637, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE),(2, 2, 'localhost', 57638, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE) SELECT citus_internal_add_partition_metadata ('mx_testing_schema.mx_test_table'::regclass, 'h', 'col_1', 0, 's') + SELECT pg_catalog.worker_drop_sequence_dependency(logicalrelid::regclass::text) FROM pg_dist_partition SELECT pg_catalog.worker_record_sequence_dependency('mx_testing_schema.mx_test_table_col_3_seq'::regclass,'mx_testing_schema.mx_test_table'::regclass,'col_3') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS mx_testing_schema.mx_test_table_col_3_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS public.user_defined_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') @@ -193,7 +198,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; WITH distributed_object_data(typetext, objnames, objargs, distargumentindex, colocationid) AS (VALUES ('sequence', ARRAY['public', 'user_defined_seq']::text[], ARRAY[]::text[], -1, 0), ('sequence', ARRAY['mx_testing_schema', 'mx_test_table_col_3_seq']::text[], ARRAY[]::text[], -1, 0), ('role', ARRAY['postgres']::text[], ARRAY[]::text[], -1, 0), ('database', ARRAY['regression']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['public']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['mx_testing_schema']::text[], ARRAY[]::text[], -1, 0)) SELECT citus_internal_add_object_metadata(typetext, objnames, objargs, distargumentindex::int, colocationid::int) FROM distributed_object_data; WITH placement_data(shardid, shardstate, shardlength, groupid, placementid) AS (VALUES (1310000, 1, 0, 1, 100000), (1310001, 1, 0, 2, 100001), (1310002, 1, 0, 1, 100002), (1310003, 1, 0, 2, 100003), (1310004, 1, 0, 1, 100004), (1310005, 1, 0, 2, 100005), (1310006, 1, 0, 1, 100006), (1310007, 1, 0, 2, 100007)) SELECT citus_internal_add_placement_metadata(shardid, shardstate, shardlength, groupid, placementid) FROM placement_data; WITH shard_data(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) AS (VALUES ('mx_testing_schema.mx_test_table'::regclass, 1310000, 't'::"char", '-2147483648', '-1610612737'), ('mx_testing_schema.mx_test_table'::regclass, 1310001, 't'::"char", '-1610612736', '-1073741825'), ('mx_testing_schema.mx_test_table'::regclass, 1310002, 't'::"char", '-1073741824', '-536870913'), ('mx_testing_schema.mx_test_table'::regclass, 1310003, 't'::"char", '-536870912', '-1'), ('mx_testing_schema.mx_test_table'::regclass, 1310004, 't'::"char", '0', '536870911'), ('mx_testing_schema.mx_test_table'::regclass, 1310005, 't'::"char", '536870912', '1073741823'), ('mx_testing_schema.mx_test_table'::regclass, 1310006, 't'::"char", '1073741824', '1610612735'), ('mx_testing_schema.mx_test_table'::regclass, 1310007, 't'::"char", '1610612736', '2147483647')) SELECT citus_internal_add_shard_metadata(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) FROM shard_data; -(19 rows) +(20 rows) -- Show that range distributed tables are not included in the metadata snapshot UPDATE pg_dist_partition SET partmethod='r' WHERE logicalrelid='non_mx_test_table'::regclass; @@ -209,6 +214,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; CREATE TABLE mx_testing_schema.mx_test_table (col_1 integer, col_2 text NOT NULL, col_3 bigint DEFAULT nextval('mx_testing_schema.mx_test_table_col_3_seq'::regclass) NOT NULL, col_4 bigint DEFAULT nextval('public.user_defined_seq'::regclass)) INSERT INTO pg_dist_node (nodeid, groupid, nodename, nodeport, noderack, hasmetadata, metadatasynced, isactive, noderole, nodecluster, shouldhaveshards) VALUES (1, 1, 'localhost', 57637, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE),(2, 2, 'localhost', 57638, 'default', FALSE, FALSE, TRUE, 'primary'::noderole, 'default', TRUE) SELECT citus_internal_add_partition_metadata ('mx_testing_schema.mx_test_table'::regclass, 'h', 'col_1', 0, 's') + SELECT pg_catalog.worker_drop_sequence_dependency(logicalrelid::regclass::text) FROM pg_dist_partition SELECT pg_catalog.worker_record_sequence_dependency('mx_testing_schema.mx_test_table_col_3_seq'::regclass,'mx_testing_schema.mx_test_table'::regclass,'col_3') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS mx_testing_schema.mx_test_table_col_3_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS public.user_defined_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') @@ -219,7 +225,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; WITH distributed_object_data(typetext, objnames, objargs, distargumentindex, colocationid) AS (VALUES ('sequence', ARRAY['public', 'user_defined_seq']::text[], ARRAY[]::text[], -1, 0), ('sequence', ARRAY['mx_testing_schema', 'mx_test_table_col_3_seq']::text[], ARRAY[]::text[], -1, 0), ('role', ARRAY['postgres']::text[], ARRAY[]::text[], -1, 0), ('database', ARRAY['regression']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['public']::text[], ARRAY[]::text[], -1, 0), ('schema', ARRAY['mx_testing_schema']::text[], ARRAY[]::text[], -1, 0)) SELECT citus_internal_add_object_metadata(typetext, objnames, objargs, distargumentindex::int, colocationid::int) FROM distributed_object_data; WITH placement_data(shardid, shardstate, shardlength, groupid, placementid) AS (VALUES (1310000, 1, 0, 1, 100000), (1310001, 1, 0, 2, 100001), (1310002, 1, 0, 1, 100002), (1310003, 1, 0, 2, 100003), (1310004, 1, 0, 1, 100004), (1310005, 1, 0, 2, 100005), (1310006, 1, 0, 1, 100006), (1310007, 1, 0, 2, 100007)) SELECT citus_internal_add_placement_metadata(shardid, shardstate, shardlength, groupid, placementid) FROM placement_data; WITH shard_data(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) AS (VALUES ('mx_testing_schema.mx_test_table'::regclass, 1310000, 't'::"char", '-2147483648', '-1610612737'), ('mx_testing_schema.mx_test_table'::regclass, 1310001, 't'::"char", '-1610612736', '-1073741825'), ('mx_testing_schema.mx_test_table'::regclass, 1310002, 't'::"char", '-1073741824', '-536870913'), ('mx_testing_schema.mx_test_table'::regclass, 1310003, 't'::"char", '-536870912', '-1'), ('mx_testing_schema.mx_test_table'::regclass, 1310004, 't'::"char", '0', '536870911'), ('mx_testing_schema.mx_test_table'::regclass, 1310005, 't'::"char", '536870912', '1073741823'), ('mx_testing_schema.mx_test_table'::regclass, 1310006, 't'::"char", '1073741824', '1610612735'), ('mx_testing_schema.mx_test_table'::regclass, 1310007, 't'::"char", '1610612736', '2147483647')) SELECT citus_internal_add_shard_metadata(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) FROM shard_data; -(19 rows) +(20 rows) -- Test start_metadata_sync_to_node UDF -- Ensure that hasmetadata=false for all nodes @@ -300,7 +306,7 @@ SELECT * FROM pg_dist_node ORDER BY nodeid; (4 rows) SELECT * FROM pg_dist_partition WHERE logicalrelid::text LIKE 'mx_testing_schema%' ORDER BY logicalrelid; - logicalrelid | partmethod | partkey | colocationid | repmodel | autoconverted + logicalrelid | partmethod | partkey | colocationid | repmodel | autoconverted --------------------------------------------------------------------- mx_testing_schema.mx_test_table | h | {VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 0 | s | f (1 row) @@ -437,7 +443,7 @@ SELECT * FROM pg_dist_node ORDER BY nodeid; (4 rows) SELECT * FROM pg_dist_partition WHERE logicalrelid::text LIKE 'mx_testing_schema%' ORDER BY logicalrelid; - logicalrelid | partmethod | partkey | colocationid | repmodel | autoconverted + logicalrelid | partmethod | partkey | colocationid | repmodel | autoconverted --------------------------------------------------------------------- mx_testing_schema.mx_test_table | h | {VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 0 | s | f (1 row) @@ -1692,7 +1698,7 @@ ALTER TABLE test_table ADD COLUMN id2 int DEFAULT nextval('mx_test_sequence_1'); ALTER TABLE test_table ALTER COLUMN id2 DROP DEFAULT; ALTER TABLE test_table ALTER COLUMN id2 SET DEFAULT nextval('mx_test_sequence_1'); SELECT unnest(master_metadata_snapshot()) order by 1; - unnest + unnest --------------------------------------------------------------------- ALTER SEQUENCE mx_testing_schema.mx_test_table_col_3_seq OWNER TO postgres ALTER SEQUENCE public.mx_test_sequence_0 OWNER TO postgres @@ -1731,6 +1737,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; SELECT citus_internal_add_partition_metadata ('public.dist_table_1'::regclass, 'h', 'a', 10005, 's') SELECT citus_internal_add_partition_metadata ('public.mx_ref'::regclass, 'n', NULL, 10003, 't') SELECT citus_internal_add_partition_metadata ('public.test_table'::regclass, 'h', 'id', 10005, 's') + SELECT pg_catalog.worker_drop_sequence_dependency(logicalrelid::regclass::text) FROM pg_dist_partition SELECT pg_catalog.worker_record_sequence_dependency('mx_testing_schema.mx_test_table_col_3_seq'::regclass,'mx_testing_schema.mx_test_table'::regclass,'col_3') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS mx_testing_schema.mx_test_table_col_3_seq AS bigint INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1 NO CYCLE','bigint') SELECT worker_apply_sequence_command ('CREATE SEQUENCE IF NOT EXISTS public.mx_test_sequence_0 AS integer INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1 NO CYCLE','integer') @@ -1758,7 +1765,7 @@ SELECT unnest(master_metadata_snapshot()) order by 1; WITH shard_data(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) AS (VALUES ('public.dist_table_1'::regclass, 1310074, 't'::"char", '-2147483648', '-1073741825'), ('public.dist_table_1'::regclass, 1310075, 't'::"char", '-1073741824', '-1'), ('public.dist_table_1'::regclass, 1310076, 't'::"char", '0', '1073741823'), ('public.dist_table_1'::regclass, 1310077, 't'::"char", '1073741824', '2147483647')) SELECT citus_internal_add_shard_metadata(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) FROM shard_data; WITH shard_data(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) AS (VALUES ('public.mx_ref'::regclass, 1310073, 't'::"char", NULL, NULL)) SELECT citus_internal_add_shard_metadata(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) FROM shard_data; WITH shard_data(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) AS (VALUES ('public.test_table'::regclass, 1310083, 't'::"char", '-2147483648', '-1073741825'), ('public.test_table'::regclass, 1310084, 't'::"char", '-1073741824', '-1'), ('public.test_table'::regclass, 1310085, 't'::"char", '0', '1073741823'), ('public.test_table'::regclass, 1310086, 't'::"char", '1073741824', '2147483647')) SELECT citus_internal_add_shard_metadata(relationname, shardid, storagetype, shardminvalue, shardmaxvalue) FROM shard_data; -(64 rows) +(65 rows) -- shouldn't work since test_table is MX ALTER TABLE test_table ADD COLUMN id3 bigserial; diff --git a/src/test/regress/expected/resync_metadata_with_sequences.out b/src/test/regress/expected/resync_metadata_with_sequences.out new file mode 100644 index 00000000000..b977f0a8d6e --- /dev/null +++ b/src/test/regress/expected/resync_metadata_with_sequences.out @@ -0,0 +1,356 @@ +CREATE SCHEMA resync_metadata_with_sequences; +SET search_path TO resync_metadata_with_sequences; +CREATE TABLE test_serial(a bigserial PRIMARY KEY); +SELECT create_distributed_table('test_serial', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE SEQUENCE myseq; +CREATE TABLE test_sequence(a bigint DEFAULT nextval('myseq')); +SELECT create_distributed_table('test_sequence', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE SEQUENCE myseq_ref; +CREATE TABLE test_serial_ref(a bigserial PRIMARY KEY, b bigint DEFAULT nextval('myseq_ref')); +SELECT create_reference_table('test_serial_ref'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 1 | 1 +(1 row) + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 2 | 2 +(1 row) + +SET client_min_messages TO ERROR; +SELECT 1 FROM citus_add_node('localhost', :master_port, groupid:=0); + ?column? +--------------------------------------------------------------------- + 1 +(1 row) + +CREATE SEQUENCE myseq_locl_to_dist; +CREATE TABLE test_local_to_dist(a bigserial PRIMARY KEY, b bigint DEFAULT nextval('myseq_locl_to_dist')); +SELECT citus_add_local_table_to_metadata('test_local_to_dist'); + citus_add_local_table_to_metadata +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 1 | 1 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 2 | 2 +(1 row) + +SET citus.shard_replication_factor TO 1; +CREATE SEQUENCE other_id_seq; +CREATE TABLE sensors( +measureid bigserial, +other_id bigint DEFAULT nextval('other_id_seq'), +eventdatetime date) PARTITION BY RANGE(eventdatetime); +CREATE TABLE sensors_old PARTITION OF sensors FOR VALUES FROM ('2000-01-01') TO ('2020-01-01'); +CREATE TABLE sensors_2020_01_01 PARTITION OF sensors FOR VALUES FROM ('2020-01-01') TO ('2020-02-01'); +CREATE TABLE sensors_news PARTITION OF sensors FOR VALUES FROM ('2020-05-01') TO ('2025-01-01'); +SELECT create_distributed_table('sensors', 'measureid', colocate_with:='none'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; +INSERT INTO test_serial VALUES(DEFAULT) RETURNING *; + a +--------------------------------------------------------------------- + 3940649673949185 +(1 row) + +INSERT INTO test_serial VALUES(DEFAULT) RETURNING *; + a +--------------------------------------------------------------------- + 3940649673949186 +(1 row) + +INSERT into test_sequence VALUES(DEFAULT) RETURNING *; + a +--------------------------------------------------------------------- + 3940649673949185 +(1 row) + +INSERT into test_sequence VALUES(DEFAULT) RETURNING *; + a +--------------------------------------------------------------------- + 3940649673949186 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949185 | 3940649673949185 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949186 | 3940649673949186 +(1 row) + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949185 | 3940649673949185 +(1 row) + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949186 | 3940649673949186 +(1 row) + +INSERT INTO sensors VALUES (DEFAULT, DEFAULT, '2010-01-01') RETURNING *; + measureid | other_id | eventdatetime +--------------------------------------------------------------------- + 3940649673949185 | 3940649673949185 | 01-01-2010 +(1 row) + +INSERT INTO sensors_news VALUES (DEFAULT, DEFAULT, '2021-01-01') RETURNING *; + measureid | other_id | eventdatetime +--------------------------------------------------------------------- + 3940649673949186 | 3940649673949186 | 01-01-2021 +(1 row) + +\c - - - :master_port +SELECT start_metadata_sync_to_node('localhost', :worker_1_port); + start_metadata_sync_to_node +--------------------------------------------------------------------- + +(1 row) + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; +-- can continue inserting with the existing sequence/serial +INSERT INTO test_serial VALUES(DEFAULT) RETURNING *; + a +--------------------------------------------------------------------- + 3940649673949187 +(1 row) + +INSERT INTO test_serial VALUES(DEFAULT) RETURNING *; + a +--------------------------------------------------------------------- + 3940649673949188 +(1 row) + +INSERT into test_sequence VALUES(DEFAULT) RETURNING *; + a +--------------------------------------------------------------------- + 3940649673949187 +(1 row) + +INSERT into test_sequence VALUES(DEFAULT) RETURNING *; + a +--------------------------------------------------------------------- + 3940649673949188 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949187 | 3940649673949187 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949188 | 3940649673949188 +(1 row) + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949187 | 3940649673949187 +(1 row) + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949188 | 3940649673949188 +(1 row) + +INSERT INTO sensors VALUES (DEFAULT, DEFAULT, '2010-01-01') RETURNING *; + measureid | other_id | eventdatetime +--------------------------------------------------------------------- + 3940649673949187 | 3940649673949187 | 01-01-2010 +(1 row) + +INSERT INTO sensors_news VALUES (DEFAULT, DEFAULT, '2021-01-01') RETURNING *; + measureid | other_id | eventdatetime +--------------------------------------------------------------------- + 3940649673949188 | 3940649673949188 | 01-01-2021 +(1 row) + +\c - - - :master_port +SET search_path tO resync_metadata_with_sequences; +SELECT create_distributed_table('test_local_to_dist', 'a', colocate_with:='none'); +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$resync_metadata_with_sequences.test_local_to_dist$$) + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3 | 3 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 4 | 4 +(1 row) + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949189 | 3940649673949189 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949190 | 3940649673949190 +(1 row) + +\c - - - :master_port +SET search_path tO resync_metadata_with_sequences; +SELECT alter_distributed_table('test_local_to_dist', shard_count:=6); +NOTICE: creating a new table for resync_metadata_with_sequences.test_local_to_dist +NOTICE: moving the data of resync_metadata_with_sequences.test_local_to_dist +NOTICE: dropping the old resync_metadata_with_sequences.test_local_to_dist +NOTICE: renaming the new table to resync_metadata_with_sequences.test_local_to_dist + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SET citus.shard_replication_factor TO 1; +SELECT alter_distributed_table('sensors', shard_count:=5); +NOTICE: converting the partitions of resync_metadata_with_sequences.sensors +NOTICE: creating a new table for resync_metadata_with_sequences.sensors_old +NOTICE: moving the data of resync_metadata_with_sequences.sensors_old +NOTICE: dropping the old resync_metadata_with_sequences.sensors_old +NOTICE: renaming the new table to resync_metadata_with_sequences.sensors_old +NOTICE: creating a new table for resync_metadata_with_sequences.sensors_2020_01_01 +NOTICE: moving the data of resync_metadata_with_sequences.sensors_2020_01_01 +NOTICE: dropping the old resync_metadata_with_sequences.sensors_2020_01_01 +NOTICE: renaming the new table to resync_metadata_with_sequences.sensors_2020_01_01 +NOTICE: creating a new table for resync_metadata_with_sequences.sensors_news +NOTICE: moving the data of resync_metadata_with_sequences.sensors_news +NOTICE: dropping the old resync_metadata_with_sequences.sensors_news +NOTICE: renaming the new table to resync_metadata_with_sequences.sensors_news +NOTICE: creating a new table for resync_metadata_with_sequences.sensors +NOTICE: dropping the old resync_metadata_with_sequences.sensors +NOTICE: renaming the new table to resync_metadata_with_sequences.sensors + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 5 | 5 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 6 | 6 +(1 row) + +INSERT INTO sensors VALUES (DEFAULT, DEFAULT, '2010-01-01') RETURNING *; + measureid | other_id | eventdatetime +--------------------------------------------------------------------- + 1 | 1 | 01-01-2010 +(1 row) + +INSERT INTO sensors_news VALUES (DEFAULT, DEFAULT, '2021-01-01') RETURNING *; + measureid | other_id | eventdatetime +--------------------------------------------------------------------- + 2 | 2 | 01-01-2021 +(1 row) + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949191 | 3940649673949191 +(1 row) + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + a | b +--------------------------------------------------------------------- + 3940649673949192 | 3940649673949192 +(1 row) + +INSERT INTO sensors VALUES (DEFAULT, DEFAULT, '2010-01-01') RETURNING *; + measureid | other_id | eventdatetime +--------------------------------------------------------------------- + 3940649673949189 | 3940649673949189 | 01-01-2010 +(1 row) + +INSERT INTO sensors_news VALUES (DEFAULT, DEFAULT, '2021-01-01') RETURNING *; + measureid | other_id | eventdatetime +--------------------------------------------------------------------- + 3940649673949190 | 3940649673949190 | 01-01-2021 +(1 row) + +\c - - - :master_port +SET search_path tO resync_metadata_with_sequences; +DROP TABLE test_serial, test_sequence; +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; +-- show that we only have the sequences left after +-- dropping the tables (e.g., bigserial is dropped) +select count(*) from pg_sequences where schemaname ilike '%resync_metadata_with_sequences%'; + count +--------------------------------------------------------------------- + 7 +(1 row) + +\c - - - :master_port +SET client_min_messages TO ERROR; +SELECT 1 FROM citus_remove_node('localhost', :master_port); + ?column? +--------------------------------------------------------------------- + 1 +(1 row) + +DROP SCHEMA resync_metadata_with_sequences CASCADE; diff --git a/src/test/regress/expected/start_stop_metadata_sync.out b/src/test/regress/expected/start_stop_metadata_sync.out index f38e43710cf..37bb731940f 100644 --- a/src/test/regress/expected/start_stop_metadata_sync.out +++ b/src/test/regress/expected/start_stop_metadata_sync.out @@ -156,7 +156,7 @@ SELECT * FROM test_matview; (1 row) SELECT * FROM pg_dist_partition WHERE logicalrelid::text LIKE 'events%' ORDER BY logicalrelid::text; - logicalrelid | partmethod | partkey | colocationid | repmodel | autoconverted + logicalrelid | partmethod | partkey | colocationid | repmodel | autoconverted --------------------------------------------------------------------- events | h | {VAR :varno 1 :varattno 1 :vartype 1184 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 1390012 | s | f events_2021_feb | h | {VAR :varno 1 :varattno 1 :vartype 1184 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 1390012 | s | f diff --git a/src/test/regress/expected/upgrade_list_citus_objects.out b/src/test/regress/expected/upgrade_list_citus_objects.out index c5183849536..e3881859436 100644 --- a/src/test/regress/expected/upgrade_list_citus_objects.out +++ b/src/test/regress/expected/upgrade_list_citus_objects.out @@ -204,6 +204,7 @@ ORDER BY 1; function worker_create_schema(bigint,text) function worker_create_truncate_trigger(regclass) function worker_drop_distributed_table(text) + function worker_drop_sequence_dependency(text) function worker_fetch_foreign_file(text,text,bigint,text[],integer[]) function worker_fetch_partition_file(bigint,integer,integer,integer,text,integer) function worker_fix_partition_shard_index_names(regclass,text,text) @@ -263,5 +264,5 @@ ORDER BY 1; view citus_worker_stat_activity view pg_dist_shard_placement view time_partitions -(247 rows) +(248 rows) diff --git a/src/test/regress/multi_mx_schedule b/src/test/regress/multi_mx_schedule index 08828af4b3d..dadf9fa562c 100644 --- a/src/test/regress/multi_mx_schedule +++ b/src/test/regress/multi_mx_schedule @@ -57,6 +57,7 @@ test: multi_mx_insert_select_repartition test: locally_execute_intermediate_results test: multi_mx_alter_distributed_table test: update_colocation_mx +test: resync_metadata_with_sequences # should be executed sequentially because it modifies metadata test: local_shard_execution_dropped_column diff --git a/src/test/regress/sql/resync_metadata_with_sequences.sql b/src/test/regress/sql/resync_metadata_with_sequences.sql new file mode 100644 index 00000000000..b83caff7f6c --- /dev/null +++ b/src/test/regress/sql/resync_metadata_with_sequences.sql @@ -0,0 +1,132 @@ +CREATE SCHEMA resync_metadata_with_sequences; +SET search_path TO resync_metadata_with_sequences; + +CREATE TABLE test_serial(a bigserial PRIMARY KEY); +SELECT create_distributed_table('test_serial', 'a'); + +CREATE SEQUENCE myseq; +CREATE TABLE test_sequence(a bigint DEFAULT nextval('myseq')); +SELECT create_distributed_table('test_sequence', 'a'); + +CREATE SEQUENCE myseq_ref; +CREATE TABLE test_serial_ref(a bigserial PRIMARY KEY, b bigint DEFAULT nextval('myseq_ref')); +SELECT create_reference_table('test_serial_ref'); + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + +SET client_min_messages TO ERROR; +SELECT 1 FROM citus_add_node('localhost', :master_port, groupid:=0); + +CREATE SEQUENCE myseq_locl_to_dist; +CREATE TABLE test_local_to_dist(a bigserial PRIMARY KEY, b bigint DEFAULT nextval('myseq_locl_to_dist')); +SELECT citus_add_local_table_to_metadata('test_local_to_dist'); +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + +SET citus.shard_replication_factor TO 1; +CREATE SEQUENCE other_id_seq; +CREATE TABLE sensors( +measureid bigserial, +other_id bigint DEFAULT nextval('other_id_seq'), +eventdatetime date) PARTITION BY RANGE(eventdatetime); + +CREATE TABLE sensors_old PARTITION OF sensors FOR VALUES FROM ('2000-01-01') TO ('2020-01-01'); +CREATE TABLE sensors_2020_01_01 PARTITION OF sensors FOR VALUES FROM ('2020-01-01') TO ('2020-02-01'); +CREATE TABLE sensors_news PARTITION OF sensors FOR VALUES FROM ('2020-05-01') TO ('2025-01-01'); +SELECT create_distributed_table('sensors', 'measureid', colocate_with:='none'); + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; + +INSERT INTO test_serial VALUES(DEFAULT) RETURNING *; +INSERT INTO test_serial VALUES(DEFAULT) RETURNING *; + +INSERT into test_sequence VALUES(DEFAULT) RETURNING *; +INSERT into test_sequence VALUES(DEFAULT) RETURNING *; + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + +INSERT INTO sensors VALUES (DEFAULT, DEFAULT, '2010-01-01') RETURNING *; +INSERT INTO sensors_news VALUES (DEFAULT, DEFAULT, '2021-01-01') RETURNING *; + +\c - - - :master_port +SELECT start_metadata_sync_to_node('localhost', :worker_1_port); + + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; + +-- can continue inserting with the existing sequence/serial +INSERT INTO test_serial VALUES(DEFAULT) RETURNING *; +INSERT INTO test_serial VALUES(DEFAULT) RETURNING *; + +INSERT into test_sequence VALUES(DEFAULT) RETURNING *; +INSERT into test_sequence VALUES(DEFAULT) RETURNING *; + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; +INSERT INTO test_serial_ref VALUES(DEFAULT) RETURNING *; + +INSERT INTO sensors VALUES (DEFAULT, DEFAULT, '2010-01-01') RETURNING *; +INSERT INTO sensors_news VALUES (DEFAULT, DEFAULT, '2021-01-01') RETURNING *; + +\c - - - :master_port +SET search_path tO resync_metadata_with_sequences; +SELECT create_distributed_table('test_local_to_dist', 'a', colocate_with:='none'); + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + +\c - - - :master_port +SET search_path tO resync_metadata_with_sequences; + +SELECT alter_distributed_table('test_local_to_dist', shard_count:=6); + +SET citus.shard_replication_factor TO 1; +SELECT alter_distributed_table('sensors', shard_count:=5); + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + +INSERT INTO sensors VALUES (DEFAULT, DEFAULT, '2010-01-01') RETURNING *; +INSERT INTO sensors_news VALUES (DEFAULT, DEFAULT, '2021-01-01') RETURNING *; + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; + +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; +INSERT INTO test_local_to_dist VALUES(DEFAULT) RETURNING *; + +INSERT INTO sensors VALUES (DEFAULT, DEFAULT, '2010-01-01') RETURNING *; +INSERT INTO sensors_news VALUES (DEFAULT, DEFAULT, '2021-01-01') RETURNING *; + +\c - - - :master_port +SET search_path tO resync_metadata_with_sequences; + +DROP TABLE test_serial, test_sequence; + +\c - - - :worker_1_port +SET search_path tO resync_metadata_with_sequences; + +-- show that we only have the sequences left after +-- dropping the tables (e.g., bigserial is dropped) +select count(*) from pg_sequences where schemaname ilike '%resync_metadata_with_sequences%'; + +\c - - - :master_port +SET client_min_messages TO ERROR; +SELECT 1 FROM citus_remove_node('localhost', :master_port); + +DROP SCHEMA resync_metadata_with_sequences CASCADE;