From 354fe7b7874da88f5b58c7245f1efb20757bfe0b Mon Sep 17 00:00:00 2001 From: Vignesh C Date: Tue, 2 Sep 2025 16:35:21 +0530 Subject: [PATCH v20251006_2 6/6] Documentation for sequence synchronization feature. Documentation for sequence synchronization feature. Author: Vignesh C Reviewer: Amit Kapila, Shveta Malik, Dilip Kumar, Peter Smith, Nisha Moond Discussion: https://www.postgresql.org/message-id/CAA4eK1LC+KJiAkSrpE_NwvNdidw9F2os7GERUeSxSKv71gXysQ@mail.gmail.com --- doc/src/sgml/catalogs.sgml | 30 ++- doc/src/sgml/config.sgml | 16 +- doc/src/sgml/func/func-sequence.sgml | 24 ++ doc/src/sgml/logical-replication.sgml | 279 +++++++++++++++++++--- doc/src/sgml/monitoring.sgml | 14 +- doc/src/sgml/ref/alter_subscription.sgml | 62 ++++- doc/src/sgml/ref/create_publication.sgml | 74 ++++-- doc/src/sgml/ref/create_subscription.sgml | 19 +- doc/src/sgml/system-views.sgml | 66 +++++ 9 files changed, 501 insertions(+), 83 deletions(-) diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index e9095bedf21..72d597097a3 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -8186,16 +8186,19 @@ SCRAM-SHA-256$<iteration count>:&l - The catalog pg_subscription_rel contains the - state for each replicated relation in each subscription. This is a - many-to-many mapping. + The catalog pg_subscription_rel stores the + state of each replicated table and sequence for each subscription. This + is a many-to-many mapping. - This catalog only contains tables known to the subscription after running - either CREATE SUBSCRIPTION or - ALTER SUBSCRIPTION ... REFRESH - PUBLICATION. + This catalog only contains tables and sequences known to the subscription + after running: + CREATE SUBSCRIPTION, + + ALTER SUBSCRIPTION ... REFRESH PUBLICATION, or + + ALTER SUBSCRIPTION ... REFRESH PUBLICATION SEQUENCES. @@ -8229,7 +8232,7 @@ SCRAM-SHA-256$<iteration count>:&l (references pg_class.oid) - Reference to relation + Reference to table or sequence @@ -8238,12 +8241,21 @@ SCRAM-SHA-256$<iteration count>:&l srsubstate char - State code: + State code for the table or sequence. + + + State codes for tables: i = initialize, d = data is being copied, f = finished table copy, s = synchronized, r = ready (normal replication) + + + State codes for sequences: + i = initialize, + d = re-synchronize, + r = ready diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index e9b420f3ddb..7138de1acb8 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -5191,9 +5191,9 @@ ANY num_sync ( num_sync ( num_sync ( + + pg_get_sequence_data + + pg_get_sequence_data ( regclass ) + record + ( last_value bigint, + is_called bool, + page_lsn pg_lsn ) + + + Returns information about the sequence. last_value + indicates last sequence value set in sequence by nextval or setval, + is_called indicates whether the sequence has been + used, and page_lsn is the LSN corresponding to the + most recent WAL record that modified this sequence relation. + + + This function requires USAGE + or SELECT privilege on the sequence. + +
diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index 9ccd5ec5006..9313cbfd1fd 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -102,16 +102,20 @@ A publication can be defined on any physical replication primary. The node where a publication is defined is referred to as publisher. A publication is a set of changes - generated from a table or a group of tables, and might also be described as - a change set or replication set. Each publication exists in only one database. + generated from a table, a group of tables or the current state of all + sequences, and might also be described as a change set or replication set. + Each publication exists in only one database. Publications are different from schemas and do not affect how the table is accessed. Each table can be added to multiple publications if needed. - Publications may currently only contain tables and all tables in schema. - Objects must be added explicitly, except when a publication is created for - ALL TABLES. + Publications may currently only contain tables or sequences. Objects must be + added explicitly, except when a publication is created using + FOR TABLES IN SCHEMA, FOR ALL TABLES, + or FOR ALL SEQUENCES. Unlike tables, the current state of + sequences may be synchronized at any time. For more information, refer to + . @@ -1049,24 +1053,24 @@ HINT: To initiate replication, you must manually create the replication slot, e 5) AND (c = 'NSW'::text)) - Publication p2 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f + Publication p2 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root +----------+------------+---------------+---------+---------+---------+-----------+-------------------+---------- + postgres | f | f | t | t | t | t | none | f Tables: "public.t1" "public.t2" WHERE (e = 99) - Publication p3 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f + Publication p3 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root +----------+------------+---------------+---------+---------+---------+-----------+-------------------+---------- + postgres | f | f | t | t | t | t | none | f Tables: "public.t2" WHERE (d = 10) "public.t3" WHERE (g = 10) @@ -1491,10 +1495,10 @@ Publications: for each publication. /* pub # */ \dRp+ - Publication p1 - Owner | All tables | Inserts | Updates | Deletes | Truncates | Generated columns | Via root -----------+------------+---------+---------+---------+-----------+-------------------+---------- - postgres | f | t | t | t | t | none | f + Publication p1 + Owner | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root +----------+------------+---------------+---------+---------+---------+-----------+-------------------+---------- + postgres | f | f | t | t | t | t | none | f Tables: "public.t1" (id, a, b, d) @@ -1743,6 +1747,209 @@ Publications: + + Replicating Sequences + + + To synchronize sequences from a publisher to a subscriber, first publish + them using + CREATE PUBLICATION ... FOR ALL SEQUENCES and then + at the subscriber side: + + + + + + + use CREATE SUBSCRIPTION + to initially synchronize the published sequences. + + + + + use + ALTER SUBSCRIPTION ... REFRESH PUBLICATION + to synchronize only newly added sequences. + + + + + use + ALTER SUBSCRIPTION ... REFRESH PUBLICATION SEQUENCES + to re-synchronize all sequences. + + + + + + + A new sequence synchronization worker will be started + after executing any of the above subscriber commands, and will exit once the + sequences are synchronized. + + + The ability to launch a sequence synchronization worker is limited by the + + max_sync_workers_per_subscription + configuration. + + + + Sequence Definition Mismatches + + During sequence synchronization, the sequence definitions of the publisher + and the subscriber are compared. An ERROR is logged listing all differing + sequences before the process exits. The apply worker detects this failure + and repeatedly respawns the sequence synchronization worker to continue + the synchronization process until all differences are resolved. See also + wal_retrieve_retry_interval. + + + To resolve this, use + ALTER SEQUENCE + to align the subscriber's sequence parameters with those of the publisher. + + + + + Missing Sequences + + During sequence synchronization, if a sequence is dropped on the + publisher, the sequence synchronization worker will identify this and + remove it from sequence synchronization on the subscriber. + + + + + Refreshing Stale Sequences + + Subscriber side sequence values may frequently become out of sync due to + updates on the publisher. + + + To verify, compare the sequence values between the publisher and + subscriber, and if necessary, execute + + ALTER SUBSCRIPTION ... REFRESH PUBLICATION SEQUENCES. + + + + + Examples + + + Create some sequences on the publisher. + +test_pub=# CREATE SEQUENCE s1 START WITH 10 INCREMENT BY 1; +CREATE SEQUENCE +test_pub=# CREATE SEQUENCE s2 START WITH 100 INCREMENT BY 10; +CREATE SEQUENCE + + + + Create the same sequences on the subscriber. + +test_sub=# CREATE SEQUENCE s1 START WITH 10 INCREMENT BY 1 +CREATE SEQUENCE +test_sub=# CREATE SEQUENCE s2 START WITH 100 INCREMENT BY 10; +CREATE SEQUENCE + + + + Update the sequences at the publisher side a few times. + +test_pub=# SELECT nextval('s1'); + nextval +--------- + 10 +(1 row) +test_pub=# SELECT nextval('s1'); + nextval +--------- + 11 +(1 row) +test_pub=# SELECT nextval('s2'); + nextval +--------- + 100 +(1 row) +test_pub=# SELECT nextval('s2'); + nextval +--------- + 110 +(1 row) + + + + Create a publication for the sequences. + +test_pub=# CREATE PUBLICATION pub1 FOR ALL SEQUENCES; +CREATE PUBLICATION + + + + Subscribe to the publication. + +test_sub=# CREATE SUBSCRIPTION sub1 +test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub1' +test_sub-# PUBLICATION pub1; +CREATE SUBSCRIPTION + + + + Observe that initial sequence values are synchronized. + +test_sub=# SELECT * FROM s1; + last_value | log_cnt | is_called +------------+---------+----------- + 11 | 31 | t +(1 row) + +test_sub=# SELECT * FROM s2; + last_value | log_cnt | is_called +------------+---------+----------- + 110 | 31 | t +(1 row) + + + + Update the sequences at the publisher side. + +test_pub=# SELECT nextval('s1'); + nextval +--------- + 12 +(1 row) +test_pub=# SELECT nextval('s2'); + nextval +--------- + 120 +(1 row) + + + + Re-synchronize all the sequences at the subscriber side using + + ALTER SUBSCRIPTION ... REFRESH PUBLICATION SEQUENCES. + +test_sub=# ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION SEQUENCES; +ALTER SUBSCRIPTION + +test_sub=# SELECT * FROM s1; + last_value | log_cnt | is_called +------------+---------+----------- + 12 | 30 | t +(1 row) + +test_sub=# SELECT * FROM s2 + last_value | log_cnt | is_called +------------+---------+----------- + 120 | 30 | t +(1 row) + + + + Conflicts @@ -2088,16 +2295,19 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER - Sequence data is not replicated. The data in serial or identity columns - backed by sequences will of course be replicated as part of the table, - but the sequence itself would still show the start value on the - subscriber. If the subscriber is used as a read-only database, then this - should typically not be a problem. If, however, some kind of switchover - or failover to the subscriber database is intended, then the sequences - would need to be updated to the latest values, either by copying the - current data from the publisher (perhaps - using pg_dump) or by determining a sufficiently high - value from the tables themselves. + Incremental sequence changes are not replicated. Although the data in + serial or identity columns backed by sequences will be replicated as part + of the table, the sequences themselves do not replicate ongoing changes. + On the subscriber, a sequence will retain the last value it synchronized + from the publisher. If the subscriber is used as a read-only database, + then this should typically not be a problem. If, however, some kind of + switchover or failover to the subscriber database is intended, then the + sequences would need to be updated to the latest values, either by + executing + ALTER SUBSCRIPTION ... REFRESH PUBLICATION SEQUENCES + or by copying the current data from the publisher (perhaps using + pg_dump) or by determining a sufficiently high value + from the tables themselves. @@ -2421,8 +2631,8 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_logical_replication_workers must be set to at least the number of subscriptions (for leader apply - workers), plus some reserve for the table synchronization workers and - parallel apply workers. + workers), plus some reserve for the parallel apply workers, table synchronization workers, and a sequence + synchronization worker. @@ -2435,8 +2645,9 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER max_sync_workers_per_subscription - controls the amount of parallelism of the initial data copy during the - subscription initialization or when new tables are added. + controls how many tables can be synchronized in parallel during + subscription initialization or when new tables are added. One additional + worker is also needed for sequence synchronization. diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 786aa2ac5f6..6771d1b4479 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -2030,8 +2030,9 @@ description | Waiting for a newly initialized WAL file to reach durable storage Type of the subscription worker process. Possible types are - apply, parallel apply, and - table synchronization. + apply, parallel apply, + table synchronization, and + sequence synchronization. @@ -2177,6 +2178,15 @@ description | Waiting for a newly initialized WAL file to reach durable storage + + + sequence_sync_error_count bigint + + + Number of times an error occurred during the sequence synchronization + + + sync_error_count bigint diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml index 12f72ba3167..8309ca4b039 100644 --- a/doc/src/sgml/ref/alter_subscription.sgml +++ b/doc/src/sgml/ref/alter_subscription.sgml @@ -26,6 +26,7 @@ ALTER SUBSCRIPTION name SET PUBLICA ALTER SUBSCRIPTION name ADD PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] ALTER SUBSCRIPTION name DROP PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] ALTER SUBSCRIPTION name REFRESH PUBLICATION [ WITH ( refresh_option [= value] [, ... ] ) ] +ALTER SUBSCRIPTION name REFRESH PUBLICATION SEQUENCES ALTER SUBSCRIPTION name ENABLE ALTER SUBSCRIPTION name DISABLE ALTER SUBSCRIPTION name SET ( subscription_parameter [= value] [, ... ] ) @@ -139,9 +140,9 @@ ALTER SUBSCRIPTION name RENAME TO < refresh (boolean) - When false, the command will not try to refresh table information. - REFRESH PUBLICATION should then be executed separately. - The default is true. + When false, the command will not try to refresh table and sequence + information. REFRESH PUBLICATION should then be + executed separately. The default is true. @@ -158,30 +159,51 @@ ALTER SUBSCRIPTION name RENAME TO < REFRESH PUBLICATION - Fetch missing table information from publisher. This will start + Fetch missing table information from the publisher. This will start replication of tables that were added to the subscribed-to publications since CREATE SUBSCRIPTION or the last invocation of REFRESH PUBLICATION. + + Also, fetch missing sequence information from the publisher. + + + + The system catalog pg_subscription_rel + is updated to record all tables and sequences known to the subscription, + that are still part of the publication. + + refresh_option specifies additional options for the - refresh operation. The supported options are: + refresh operation. The only supported option is: copy_data (boolean) - Specifies whether to copy pre-existing data in the publications - that are being subscribed to when the replication starts. - The default is true. + Specifies whether to copy pre-existing data for tables and synchronize + sequences in the publications that are being subscribed to when the replication + starts. The default is true. Previously subscribed tables are not copied, even if a table's row filter WHERE clause has since been modified. + + Previously subscribed sequences are not re-synchronized. To do that, + see + ALTER SUBSCRIPTION ... REFRESH PUBLICATION SEQUENCES. + + + See for recommendations on how + to handle any warnings about sequence definition differences between + the publisher and the subscriber, which might occur when + copy_data = true. + See for details of how copy_data = true can interact with the @@ -200,6 +222,30 @@ ALTER SUBSCRIPTION name RENAME TO < + + REFRESH PUBLICATION SEQUENCES + + + Re-synchronize sequence data with the publisher. Unlike + + ALTER SUBSCRIPTION ... REFRESH PUBLICATION which + only synchronizes newly added sequences, REFRESH PUBLICATION SEQUENCES + will re-synchronize the sequence data for all subscribed sequences. It + does not add or remove the missing publication sequences from the + subscription. + + + See for + recommendations on how to handle any warnings about sequence definition + differences between the publisher and the subscriber. + + + See for recommendations on how to + identify and handle out-of-sync sequences. + + + + ENABLE diff --git a/doc/src/sgml/ref/create_publication.sgml b/doc/src/sgml/ref/create_publication.sgml index 802630f2df1..c0eb5fff8de 100644 --- a/doc/src/sgml/ref/create_publication.sgml +++ b/doc/src/sgml/ref/create_publication.sgml @@ -22,14 +22,18 @@ PostgreSQL documentation CREATE PUBLICATION name - [ FOR ALL TABLES - | FOR publication_object [, ... ] ] + [ FOR { publication_object [, ... ] | all_publication_object [, ... ] } ] [ WITH ( publication_parameter [= value] [, ... ] ) ] where publication_object is one of: TABLE [ ONLY ] table_name [ * ] [ ( column_name [, ... ] ) ] [ WHERE ( expression ) ] [, ... ] TABLES IN SCHEMA { schema_name | CURRENT_SCHEMA } [, ... ] + +where all_publication_object is one of: + + ALL TABLES + ALL SEQUENCES @@ -120,16 +124,6 @@ CREATE PUBLICATION name - - FOR ALL TABLES - - - Marks the publication as one that replicates changes for all tables in - the database, including tables created in the future. - - - - FOR TABLES IN SCHEMA @@ -161,11 +155,37 @@ CREATE PUBLICATION name + + FOR ALL TABLES + + + Marks the publication as one that replicates changes for all tables in + the database, including tables created in the future. + + + + + + FOR ALL SEQUENCES + + + Marks the publication as one that synchronizes changes for all sequences + in the database, including sequences created in the future. + + + + Only persistent sequences are included in the publication. Temporary + sequences and unlogged sequences are excluded from the publication. + + + + WITH ( publication_parameter [= value] [, ... ] ) - This clause specifies optional parameters for a publication. The + This clause specifies optional parameters for a publication when + publishing tables. This clause is not applicable for sequences. The following parameters are supported: @@ -279,10 +299,10 @@ CREATE PUBLICATION name Notes - If FOR TABLE, FOR ALL TABLES or - FOR TABLES IN SCHEMA are not specified, then the - publication starts out with an empty set of tables. That is useful if - tables or schemas are to be added later. + If FOR TABLE, FOR TABLES IN SCHEMA, + FOR ALL TABLES or FOR ALL SEQUENCES + are not specified, then the publication starts out with an empty set of + tables. That is useful if tables or schemas are to be added later. @@ -298,8 +318,9 @@ CREATE PUBLICATION name To add a table to a publication, the invoking user must have ownership - rights on the table. The FOR ALL TABLES and - FOR TABLES IN SCHEMA clauses require the invoking + rights on the table. The FOR TABLES IN SCHEMA, + FOR ALL TABLES and + FOR ALL SEQUENCES clauses require the invoking user to be a superuser. @@ -449,6 +470,21 @@ CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales; CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname); + + + Create a publication that publishes all sequences for synchronization: + +CREATE PUBLICATION all_sequences FOR ALL SEQUENCES; + + + + + Create a publication that publishes all changes in all tables, and + all sequences for synchronization: + +CREATE PUBLICATION all_tables_sequences FOR ALL TABLES, ALL SEQUENCES; + + diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml index ed82cf1809e..05bf2f2f49f 100644 --- a/doc/src/sgml/ref/create_subscription.sgml +++ b/doc/src/sgml/ref/create_subscription.sgml @@ -228,7 +228,7 @@ CREATE SUBSCRIPTION subscription_name for more about send/receive - functions). + functions). This parameter is not applicable for sequences. @@ -265,6 +265,12 @@ CREATE SUBSCRIPTION subscription_namecopy_data = true can interact with the origin parameter. + + See + for recommendations on how to handle any warnings about sequence + definition differences between the publisher and the subscriber, + which might occur when copy_data = true. + @@ -280,6 +286,7 @@ CREATE SUBSCRIPTION subscription_name @@ -310,7 +317,8 @@ CREATE SUBSCRIPTION subscription_name setting within this subscription's apply worker processes. The default value - is off. + is off. This parameter is not applicable for + sequences. @@ -340,7 +348,8 @@ CREATE SUBSCRIPTION subscription_name Specifies whether two-phase commit is enabled for this subscription. - The default is false. + The default is false. This parameter is not + applicable for sequences. @@ -417,6 +426,7 @@ CREATE SUBSCRIPTION subscription_nameorigin to any means that the publisher sends changes regardless of their origin. The default is any. + This parameter is not applicable for sequences. See for details of how @@ -449,7 +459,8 @@ CREATE SUBSCRIPTION subscription_name is enabled, and a physical replication slot named pg_conflict_detection is created on the subscriber to prevent the information for detecting - conflicts from being removed. + conflicts from being removed. This parameter is not applicable for + sequences. diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml index 4187191ea74..7971498fe75 100644 --- a/doc/src/sgml/system-views.sgml +++ b/doc/src/sgml/system-views.sgml @@ -136,6 +136,11 @@ prepared transactions + + pg_publication_sequences + publications and information of their associated sequences + + pg_publication_tables publications and information of their associated tables @@ -2549,6 +2554,67 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx + + <structname>pg_publication_sequences</structname> + + + pg_publication_sequences + + + + The view pg_publication_sequences provides + information about the mapping between publications and sequences. + + + + <structname>pg_publication_sequences</structname> Columns + + + + + Column Type + + + Description + + + + + + + + pubname name + (references pg_publication.pubname) + + + Name of publication + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing sequence + + + + + + sequencename name + (references pg_class.relname) + + + Name of sequence + + + + +
+
+ <structname>pg_publication_tables</structname> -- 2.43.0