From 22c4bcdde3f1c7f7d3122299f9aaf408a38f19f2 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Wed, 29 Jan 2025 11:34:55 -0800 Subject: [PATCH v1] pg_rewind: Add dbname to primary_connifo with --write-recovery-conf. Author: Reviewed-by: Discussion: https://postgr.es/m/ Backpatch-through: --- src/bin/pg_basebackup/pg_basebackup.c | 2 +- src/bin/pg_basebackup/streamutil.c | 69 --------------------------- src/bin/pg_basebackup/streamutil.h | 2 - src/bin/pg_rewind/pg_rewind.c | 6 ++- src/fe_utils/recovery_gen.c | 65 +++++++++++++++++++++++++ src/include/fe_utils/recovery_gen.h | 1 + 6 files changed, 71 insertions(+), 74 deletions(-) diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index dc0c805137a..d4b4e334014 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -1818,7 +1818,7 @@ BaseBackup(char *compression_algorithm, char *compression_detail, if (writerecoveryconf) recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot, - GetDbnameFromConnectionOptions()); + GetDbnameFromConnectionOptions(connection_string)); /* * 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 021ab61fcb0..8e605f43ffe 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -32,7 +32,6 @@ int WalSegSz; static bool RetrieveDataDirCreatePerm(PGconn *conn); -static char *FindDbnameInConnParams(PQconninfoOption *conn_opts); /* SHOW command for replication connection was introduced in version 10 */ #define MINIMUM_VERSION_FOR_SHOW_CMD 100000 @@ -269,74 +268,6 @@ GetConnection(void) return tmpconn; } -/* - * FindDbnameInConnParams - * - * This is a helper function for GetDbnameFromConnectionOptions(). Extract - * the value of dbname from PQconninfoOption parameters, if it's present. - * Returns a strdup'd result or NULL. - */ -static char * -FindDbnameInConnParams(PQconninfoOption *conn_opts) -{ - PQconninfoOption *conn_opt; - - 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') - return pg_strdup(conn_opt->val); - } - return NULL; -} - -/* - * GetDbnameFromConnectionOptions - * - * This is a special purpose function to retrieve the dbname from either the - * connection_string specified by the user or from the environment variables. - * - * We follow GetConnection() to fetch the dbname from various connection - * options. - * - * Returns NULL, if dbname is not specified by the user in the above - * mentioned connection options. - */ -char * -GetDbnameFromConnectionOptions(void) -{ - PQconninfoOption *conn_opts; - char *err_msg = NULL; - char *dbname; - - /* First try to get the dbname from connection string. */ - if (connection_string) - { - conn_opts = PQconninfoParse(connection_string, &err_msg); - if (conn_opts == NULL) - pg_fatal("%s", err_msg); - - dbname = FindDbnameInConnParams(conn_opts); - - PQconninfoFree(conn_opts); - if (dbname) - return dbname; - } - - /* - * Next try to get the dbname from default values that are available from - * the environment. - */ - conn_opts = PQconndefaults(); - if (conn_opts == NULL) - pg_fatal("out of memory"); - - dbname = FindDbnameInConnParams(conn_opts); - - PQconninfoFree(conn_opts); - 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 472193e239f..f917c43517f 100644 --- a/src/bin/pg_basebackup/streamutil.h +++ b/src/bin/pg_basebackup/streamutil.h @@ -31,8 +31,6 @@ extern PGconn *conn; extern PGconn *GetConnection(void); -extern char *GetDbnameFromConnectionOptions(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 cae81cd6cb1..fbd29d81068 100644 --- a/src/bin/pg_rewind/pg_rewind.c +++ b/src/bin/pg_rewind/pg_rewind.c @@ -451,7 +451,8 @@ main(int argc, char **argv) pg_log_info("no rewind required"); if (writerecoveryconf && !dry_run) WriteRecoveryConfig(conn, datadir_target, - GenerateRecoveryConfig(conn, NULL, NULL)); + GenerateRecoveryConfig(conn, NULL, + GetDbnameFromConnectionOptions(connstr_source))); exit(0); } @@ -528,7 +529,8 @@ main(int argc, char **argv) /* Also update the standby configuration, if requested. */ if (writerecoveryconf && !dry_run) WriteRecoveryConfig(conn, datadir_target, - GenerateRecoveryConfig(conn, NULL, NULL)); + GenerateRecoveryConfig(conn, NULL, + GetDbnameFromConnectionOptions(connstr_source))); /* 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 7c172f65a10..eaf2c125c16 100644 --- a/src/fe_utils/recovery_gen.c +++ b/src/fe_utils/recovery_gen.c @@ -168,3 +168,68 @@ escape_quotes(const char *src) pg_fatal("out of memory"); return result; } + +/* + * FindDbnameInConnParams + * + * This is a helper function for GetDbnameFromConnectionOptions(). Extract + * the value of dbname from PQconninfoOption parameters, if it's present. + * Returns a strdup'd result or NULL. + */ +static char * +FindDbnameInConnParams(PQconninfoOption *conn_opts) +{ + PQconninfoOption *conn_opt; + + 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') + return pg_strdup(conn_opt->val); + } + return NULL; +} + +/* + * GetDbnameFromConnectionOptions + * + * This is a special purpose function to retrieve the dbname from either the + * 'connstr' specified by the caller or from the environment variables. + * + * Returns NULL, if dbname is not specified by the user in the above + * mentioned connection options. + */ +char * +GetDbnameFromConnectionOptions(const char *connstr) +{ + PQconninfoOption *conn_opts; + char *err_msg = NULL; + char *dbname; + + /* First try to get the dbname from connection string. */ + if (connstr) + { + conn_opts = PQconninfoParse(connstr, &err_msg); + if (conn_opts == NULL) + pg_fatal("%s", err_msg); + + dbname = FindDbnameInConnParams(conn_opts); + + PQconninfoFree(conn_opts); + if (dbname) + return dbname; + } + + /* + * Next try to get the dbname from default values that are available from + * the environment. + */ + conn_opts = PQconndefaults(); + if (conn_opts == NULL) + pg_fatal("out of memory"); + + dbname = FindDbnameInConnParams(conn_opts); + + PQconninfoFree(conn_opts); + return dbname; +} diff --git a/src/include/fe_utils/recovery_gen.h b/src/include/fe_utils/recovery_gen.h index 6412ffdaffa..c13f2263bcd 100644 --- a/src/include/fe_utils/recovery_gen.h +++ b/src/include/fe_utils/recovery_gen.h @@ -25,5 +25,6 @@ extern PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, char *dbname); extern void WriteRecoveryConfig(PGconn *pgconn, const char *target_dir, PQExpBuffer contents); +extern char *GetDbnameFromConnectionOptions(const char *connstr); #endif /* RECOVERY_GEN_H */ -- 2.43.5