From e63e32cf8fb8e30d0d656c64b4b54d479035c2c9 Mon Sep 17 00:00:00 2001 From: Vignesh C Date: Fri, 19 Jun 2026 19:14:27 +0530 Subject: [PATCH v9] Include sequences in publications created by pg_createsubscriber pg_createsubscriber creates a publication on the publisher to establish logical replication between the original primary and the converted subscriber. Currently, the publication is created with FOR ALL TABLES, which ensures that table data changes are replicated during the upgrade process. However, sequence state is not replicated as part of this workflow. Recent additions to logical replication introduced support for publishing all sequences and synchronizing sequence state through subscription refresh. By creating publications with FOR ALL TABLES, ALL SEQUENCES, pg_createsubscriber can take advantage of these capabilities and allow sequence state to be synchronized before the upgraded node is promoted. This change modifies pg_createsubscriber to include ALL SEQUENCES in the publication it creates. Administrators can then run ALTER SUBSCRIPTION ... REFRESH SEQUENCES after the upgrade to synchronize sequence state, ensuring a more complete and reliable upgrade workflow. --- doc/src/sgml/ref/pg_createsubscriber.sgml | 56 +++++++++++++------ src/bin/pg_basebackup/pg_createsubscriber.c | 4 +- .../t/040_pg_createsubscriber.pl | 22 +++++++- 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/doc/src/sgml/ref/pg_createsubscriber.sgml b/doc/src/sgml/ref/pg_createsubscriber.sgml index 3b3038d1891..26fe31fc8ae 100644 --- a/doc/src/sgml/ref/pg_createsubscriber.sgml +++ b/doc/src/sgml/ref/pg_createsubscriber.sgml @@ -48,11 +48,16 @@ PostgreSQL documentation pg_createsubscriber creates a new logical - replica from a physical standby server. All tables in the specified - database are included in the logical - replication setup. A pair of - publication and subscription objects are created for each database. It - must be run at the target server. + replica from a physical standby server. By default, + pg_createsubscriber configures + logical replication by + automatically creating internal publication and subscription objects. When + using internally generated publications, a publication and subscription are + created for each database, and the publications include all tables and + sequences in their respective databases. When user-specified publications + are used, the subscriptions replicate only the objects included in those + publications. pg_createsubscriber must be run at + the target server. @@ -61,7 +66,12 @@ PostgreSQL documentation replication setup and pg_createsubscriber is how the data synchronization is done. pg_createsubscriber does not copy the initial table data. It does only the synchronization phase, - which ensures each table is brought up to a synchronized state. + which ensures each table is brought up to a synchronized state. Internally + generated publications include all sequences in the database, but their + values are not automatically synchronized. For user-specified publications, + sequences are only replicated if they were explicitly added to those + publications prior to running the tool, and as with the default mode, + sequence values must be manually synchronized when needed. @@ -75,7 +85,13 @@ PostgreSQL documentation synchronization. For details, see the CREATE SUBSCRIPTION copy_data option. + + + To synchronize sequence values, run + + ALTER SUBSCRIPTION ... REFRESH SEQUENCES on each + subscription at the target server. @@ -275,10 +291,10 @@ PostgreSQL documentation publications: - The FOR ALL TABLES publications established for this - subscriber are always dropped; specifying this object type causes all - other publications replicated from the source server to be dropped as - well. + The FOR ALL TABLES, ALL SEQUENCES publications + established for this subscriber are always dropped; specifying this + object type causes all other publications replicated from the source + server to be dropped as well. @@ -323,7 +339,8 @@ PostgreSQL documentation If a specified publication already exists on the publisher, it is reused. It is useful to partially replicate the database if the specified publication includes a list of tables. If the publication does not exist, - it is automatically created with FOR ALL TABLES. Use + it is automatically created with + FOR ALL TABLES, ALL SEQUENCES. Use option to preview which publications will be reused and which will be created. @@ -531,12 +548,17 @@ PostgreSQL documentation - Create a publication and replication slot for each specified database on - the source server. Each publication is created using FOR ALL - TABLES. If the option - is not specified, the publication has the following name pattern: - pg_createsubscriber_%u_%x (parameter: + Create a publication and replication slot for each specified database + on the source server. If the option is + specified, the user-specified publication is used, which includes the + objects defined by that publication. Otherwise, + pg_createsubscriber creates a publication + using + FOR ALL TABLES and ALL + SEQUENCES. These generated publications have the + following name pattern: + pg_createsubscriber_%u_%x (parameters: database oid, random int). If the option is not specified, the replication slot has the following name pattern: diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c index 20b354aed56..cdaa5ad434a 100644 --- a/src/bin/pg_basebackup/pg_createsubscriber.c +++ b/src/bin/pg_basebackup/pg_createsubscriber.c @@ -1788,7 +1788,7 @@ wait_for_end_recovery(const char *conninfo, const struct CreateSubscriberOptions } /* - * Create a publication that includes all tables in the database. + * Create a publication that includes all tables and sequences in the database. */ static void create_publication(PGconn *conn, struct LogicalRepInfo *dbinfo) @@ -1840,7 +1840,7 @@ create_publication(PGconn *conn, struct LogicalRepInfo *dbinfo) pg_log_info("creating publication \"%s\" in database \"%s\"", dbinfo->pubname, dbinfo->dbname); - appendPQExpBuffer(str, "CREATE PUBLICATION %s FOR ALL TABLES", + appendPQExpBuffer(str, "CREATE PUBLICATION %s FOR ALL TABLES, ALL SEQUENCES", ipubname_esc); pg_log_debug("command is: %s", str->data); diff --git a/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl b/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl index 9252d1c3c5c..94cf47ae683 100644 --- a/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl +++ b/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl @@ -434,11 +434,16 @@ command_fails_like( qr/options --publication and -a\/--all cannot be used together/, 'fail if --publication is used with --all'); -# run pg_createsubscriber with '--all' option +# Remove any existing internal log files so that only the output from the +# following pg_createsubscriber invocation is verified. +unlink $_ for @internal_log_files; + +# run pg_createsubscriber with '--all' with debug verbose logging enabled my ($stdout, $stderr) = run_command( [ 'pg_createsubscriber', '--verbose', + '--verbose', '--dry-run', '--recovery-timeout' => $PostgreSQL::Test::Utils::timeout_default, '--pgdata' => $node_s->data_dir, @@ -446,6 +451,7 @@ my ($stdout, $stderr) = run_command( '--socketdir' => $node_s->host, '--subscriber-port' => $node_s->port, '--all', + '--logdir' => $logdir, ], 'run pg_createsubscriber with --all'); @@ -458,6 +464,20 @@ is(scalar(() = $stderr =~ /would create the replication slot/g), is(scalar(() = $stderr =~ /would create subscription/g), 3, "verify subscriptions are created for all databases"); +# Read the internal log generated by the above invocation. +@internal_log_files = glob "$logdir/*/pg_createsubscriber_internal.log"; +is(scalar(@internal_log_files), + 1, "pg_createsubscriber_internal.log file was recreated"); + +$internal_log = slurp_file($internal_log_files[0]); + +# Verify that the generated CREATE PUBLICATION command includes both +# FOR ALL TABLES and ALL SEQUENCES. +like( + $internal_log, + qr/CREATE PUBLICATION "pg_createsubscriber_[^"]+" FOR ALL TABLES, ALL SEQUENCES/, + "log shows CREATE PUBLICATION with both all tables and all sequences"); + # Create a user-defined publication, and a table that is not a member of that # publication. $node_p->safe_psql( -- 2.50.1 (Apple Git-155)