diff --git a/doc/src/sgml/ref/pg_basebackup.sgml b/doc/src/sgml/ref/pg_basebackup.sgml index 88c689e725..903da73df7 100644 --- a/doc/src/sgml/ref/pg_basebackup.sgml +++ b/doc/src/sgml/ref/pg_basebackup.sgml @@ -243,7 +243,10 @@ PostgreSQL documentation The postgresql.auto.conf file will record the connection settings and, if specified, the replication slot that pg_basebackup is using, so that - streaming replication will use the same settings later on. + streaming replication or + logical replication slot synchronization will use the same + settings later on. The dbname will be recorded only if the dbname was + specified explicitly in the connection string. @@ -807,7 +810,9 @@ PostgreSQL documentation client applications, but because pg_basebackup doesn't connect to any particular database in the cluster, any database name in the connection string will be ignored - by PostgreSQL. Middleware, or proxies, used in + by PostgreSQL. Middleware, proxies, or + + logical replication slot synchronization used in connecting to PostgreSQL might however utilize the value. diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 3a9940097c..8880e0bef6 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -1810,7 +1810,8 @@ BaseBackup(char *compression_algorithm, char *compression_detail, * Build contents of configuration file if requested */ if (writerecoveryconf) - recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot); + recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot, + GetDbnameFromConnectionString()); /* * Run IDENTIFY_SYSTEM so we can get the timeline diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c index 56d1b15951..a88b660c8a 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -267,6 +267,38 @@ GetConnection(void) return tmpconn; } +/* + * GetDbnameFromConnectionString + * + * If database is specified in the connection string, then return the last + * database name specified. If database is not specified in the connection + * string, then return NULL. + */ +char * +GetDbnameFromConnectionString(void) +{ + PQconninfoOption *conn_opts = NULL; + PQconninfoOption *conn_opt; + char *err_msg = NULL; + char *dbname = NULL; + + if (connection_string) + { + conn_opts = PQconninfoParse(connection_string, &err_msg); + if (conn_opts == NULL) + pg_fatal("%s", err_msg); + + for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++) + { + if ((strcmp(conn_opt->keyword, "dbname") == 0) && + conn_opt->val != NULL && conn_opt->val[0] != '\0') + dbname = conn_opt->val; + } + } + + return dbname; +} + /* * From version 10, explicitly set wal segment size using SHOW wal_segment_size * since ControlFile is not accessible here. diff --git a/src/bin/pg_basebackup/streamutil.h b/src/bin/pg_basebackup/streamutil.h index 7a3dd98da3..1ade59247a 100644 --- a/src/bin/pg_basebackup/streamutil.h +++ b/src/bin/pg_basebackup/streamutil.h @@ -31,6 +31,8 @@ extern PGconn *conn; extern PGconn *GetConnection(void); +extern char *GetDbnameFromConnectionString(void); + /* Replication commands */ extern bool CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin, bool is_temporary, diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c index bde90bf60b..8449ae78ef 100644 --- a/src/bin/pg_rewind/pg_rewind.c +++ b/src/bin/pg_rewind/pg_rewind.c @@ -451,7 +451,7 @@ main(int argc, char **argv) pg_log_info("no rewind required"); if (writerecoveryconf && !dry_run) WriteRecoveryConfig(conn, datadir_target, - GenerateRecoveryConfig(conn, NULL)); + GenerateRecoveryConfig(conn, NULL, NULL)); exit(0); } @@ -525,7 +525,7 @@ main(int argc, char **argv) /* Also update the standby configuration, if requested. */ if (writerecoveryconf && !dry_run) WriteRecoveryConfig(conn, datadir_target, - GenerateRecoveryConfig(conn, NULL)); + GenerateRecoveryConfig(conn, NULL, NULL)); /* don't need the source connection anymore */ source->destroy(source); diff --git a/src/fe_utils/recovery_gen.c b/src/fe_utils/recovery_gen.c index 2585f11939..0b5d9abc48 100644 --- a/src/fe_utils/recovery_gen.c +++ b/src/fe_utils/recovery_gen.c @@ -20,7 +20,7 @@ static char *escape_quotes(const char *src); * return it. */ PQExpBuffer -GenerateRecoveryConfig(PGconn *pgconn, char *replication_slot) +GenerateRecoveryConfig(PGconn *pgconn, char *replication_slot, char *dbname) { PQconninfoOption *connOptions; PQExpBufferData conninfo_buf; @@ -66,6 +66,20 @@ GenerateRecoveryConfig(PGconn *pgconn, char *replication_slot) appendPQExpBuffer(&conninfo_buf, "%s=", opt->keyword); appendConnStrVal(&conninfo_buf, opt->val); } + + if (dbname) + { + /* + * If dbname is specified in the connection, append the dbname. This + * will be used later for logical replication slot synchronization. + */ + if (conninfo_buf.len != 0) + appendPQExpBufferChar(&conninfo_buf, ' '); + + appendPQExpBuffer(&conninfo_buf, "%s=", "dbname"); + appendConnStrVal(&conninfo_buf, dbname); + } + if (PQExpBufferDataBroken(conninfo_buf)) pg_fatal("out of memory"); diff --git a/src/include/fe_utils/recovery_gen.h b/src/include/fe_utils/recovery_gen.h index ca2c4800d0..5a986297a5 100644 --- a/src/include/fe_utils/recovery_gen.h +++ b/src/include/fe_utils/recovery_gen.h @@ -21,7 +21,8 @@ #define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000 extern PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, - char *replication_slot); + char *replication_slot, + char *dbname); extern void WriteRecoveryConfig(PGconn *pgconn, char *target_dir, PQExpBuffer contents);