Skip to content

Commit 4ecdd41

Browse files
pg_rewind: Add dbname to primary_conninfo when using --write-recovery-conf.
This commit enhances pg_rewind's --write-recovery-conf option to include the dbname in the generated primary_conninfo value when specified in the --source-server option. With this modification, the rewound server can connect to the primary server without manual configuration file modifications when sync_replication_slots is enabled. Reviewed-by: Hayato Kuroda <[email protected]> Reviewed-by: Peter Smith <[email protected]> Discussion: https://postgr.es/m/CAD21AoAkW=Ht0k9dVoBTCcqLiiZ2MXhVr+d=j2T_EZMerGrLWQ@mail.gmail.com
1 parent cdc1471 commit 4ecdd41

File tree

8 files changed

+81
-76
lines changed

8 files changed

+81
-76
lines changed

doc/src/sgml/ref/pg_rewind.sgml

+4-2
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,10 @@ PostgreSQL documentation
186186
<para>
187187
Create <filename>standby.signal</filename> and append connection
188188
settings to <filename>postgresql.auto.conf</filename> in the output
189-
directory. <literal>--source-server</literal> is mandatory with
190-
this option.
189+
directory. The dbname will be recorded only if the dbname was
190+
specified explicitly in the connection string or <link linkend="libpq-envars">
191+
environment variable</link>. <literal>--source-server</literal> is
192+
mandatory with this option.
191193
</para>
192194
</listitem>
193195
</varlistentry>

src/bin/pg_basebackup/pg_basebackup.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1818,7 +1818,7 @@ BaseBackup(char *compression_algorithm, char *compression_detail,
18181818
if (writerecoveryconf)
18191819
recoveryconfcontents = GenerateRecoveryConfig(conn,
18201820
replication_slot,
1821-
GetDbnameFromConnectionOptions());
1821+
GetDbnameFromConnectionOptions(connection_string));
18221822

18231823
/*
18241824
* Run IDENTIFY_SYSTEM so we can get the timeline

src/bin/pg_basebackup/streamutil.c

-69
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
int WalSegSz;
3333

3434
static bool RetrieveDataDirCreatePerm(PGconn *conn);
35-
static char *FindDbnameInConnParams(PQconninfoOption *conn_opts);
3635

3736
/* SHOW command for replication connection was introduced in version 10 */
3837
#define MINIMUM_VERSION_FOR_SHOW_CMD 100000
@@ -269,74 +268,6 @@ GetConnection(void)
269268
return tmpconn;
270269
}
271270

272-
/*
273-
* FindDbnameInConnParams
274-
*
275-
* This is a helper function for GetDbnameFromConnectionOptions(). Extract
276-
* the value of dbname from PQconninfoOption parameters, if it's present.
277-
* Returns a strdup'd result or NULL.
278-
*/
279-
static char *
280-
FindDbnameInConnParams(PQconninfoOption *conn_opts)
281-
{
282-
PQconninfoOption *conn_opt;
283-
284-
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
285-
{
286-
if (strcmp(conn_opt->keyword, "dbname") == 0 &&
287-
conn_opt->val != NULL && conn_opt->val[0] != '\0')
288-
return pg_strdup(conn_opt->val);
289-
}
290-
return NULL;
291-
}
292-
293-
/*
294-
* GetDbnameFromConnectionOptions
295-
*
296-
* This is a special purpose function to retrieve the dbname from either the
297-
* connection_string specified by the user or from the environment variables.
298-
*
299-
* We follow GetConnection() to fetch the dbname from various connection
300-
* options.
301-
*
302-
* Returns NULL, if dbname is not specified by the user in the above
303-
* mentioned connection options.
304-
*/
305-
char *
306-
GetDbnameFromConnectionOptions(void)
307-
{
308-
PQconninfoOption *conn_opts;
309-
char *err_msg = NULL;
310-
char *dbname;
311-
312-
/* First try to get the dbname from connection string. */
313-
if (connection_string)
314-
{
315-
conn_opts = PQconninfoParse(connection_string, &err_msg);
316-
if (conn_opts == NULL)
317-
pg_fatal("%s", err_msg);
318-
319-
dbname = FindDbnameInConnParams(conn_opts);
320-
321-
PQconninfoFree(conn_opts);
322-
if (dbname)
323-
return dbname;
324-
}
325-
326-
/*
327-
* Next try to get the dbname from default values that are available from
328-
* the environment.
329-
*/
330-
conn_opts = PQconndefaults();
331-
if (conn_opts == NULL)
332-
pg_fatal("out of memory");
333-
334-
dbname = FindDbnameInConnParams(conn_opts);
335-
336-
PQconninfoFree(conn_opts);
337-
return dbname;
338-
}
339-
340271
/*
341272
* From version 10, explicitly set wal segment size using SHOW wal_segment_size
342273
* since ControlFile is not accessible here.

src/bin/pg_basebackup/streamutil.h

-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ extern PGconn *conn;
3131

3232
extern PGconn *GetConnection(void);
3333

34-
extern char *GetDbnameFromConnectionOptions(void);
35-
3634
/* Replication commands */
3735
extern bool CreateReplicationSlot(PGconn *conn, const char *slot_name,
3836
const char *plugin, bool is_temporary,

src/bin/pg_rewind/pg_rewind.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,8 @@ main(int argc, char **argv)
451451
pg_log_info("no rewind required");
452452
if (writerecoveryconf && !dry_run)
453453
WriteRecoveryConfig(conn, datadir_target,
454-
GenerateRecoveryConfig(conn, NULL, NULL));
454+
GenerateRecoveryConfig(conn, NULL,
455+
GetDbnameFromConnectionOptions(connstr_source)));
455456
exit(0);
456457
}
457458

@@ -528,7 +529,8 @@ main(int argc, char **argv)
528529
/* Also update the standby configuration, if requested. */
529530
if (writerecoveryconf && !dry_run)
530531
WriteRecoveryConfig(conn, datadir_target,
531-
GenerateRecoveryConfig(conn, NULL, NULL));
532+
GenerateRecoveryConfig(conn, NULL,
533+
GetDbnameFromConnectionOptions(connstr_source)));
532534

533535
/* don't need the source connection anymore */
534536
source->destroy(source);

src/bin/pg_rewind/t/RewindTest.pm

+5
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ sub run_pg_rewind
279279
],
280280
'pg_rewind remote');
281281

282+
# Check that pg_rewind with dbname and --write-recovery-conf
283+
# wrote the dbname in the generated primary_conninfo value.
284+
like(slurp_file("$primary_pgdata/postgresql.auto.conf"),
285+
qr/dbname=postgres/m, 'recovery conf file sets dbname');
286+
282287
# Check that standby.signal is here as recovery configuration
283288
# was requested.
284289
ok( -e "$primary_pgdata/standby.signal",

src/fe_utils/recovery_gen.c

+66
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "fe_utils/string_utils.h"
1515

1616
static char *escape_quotes(const char *src);
17+
static char *FindDbnameInConnOpts(PQconninfoOption *conn_opts);
1718

1819
/*
1920
* Write recovery configuration contents into a fresh PQExpBuffer, and
@@ -168,3 +169,68 @@ escape_quotes(const char *src)
168169
pg_fatal("out of memory");
169170
return result;
170171
}
172+
173+
/*
174+
* FindDbnameInConnOpts
175+
*
176+
* This is a helper function for GetDbnameFromConnectionOptions(). Extract
177+
* the value of dbname from PQconninfoOption parameters, if it's present.
178+
* Returns a strdup'd result or NULL.
179+
*/
180+
static char *
181+
FindDbnameInConnOpts(PQconninfoOption *conn_opts)
182+
{
183+
for (PQconninfoOption *conn_opt = conn_opts;
184+
conn_opt->keyword != NULL;
185+
conn_opt++)
186+
{
187+
if (strcmp(conn_opt->keyword, "dbname") == 0 &&
188+
conn_opt->val != NULL && conn_opt->val[0] != '\0')
189+
return pg_strdup(conn_opt->val);
190+
}
191+
return NULL;
192+
}
193+
194+
/*
195+
* GetDbnameFromConnectionOptions
196+
*
197+
* This is a special purpose function to retrieve the dbname from either the
198+
* 'connstr' specified by the caller or from the environment variables.
199+
*
200+
* Returns NULL, if dbname is not specified by the user in the given
201+
* connection options.
202+
*/
203+
char *
204+
GetDbnameFromConnectionOptions(const char *connstr)
205+
{
206+
PQconninfoOption *conn_opts;
207+
char *err_msg = NULL;
208+
char *dbname;
209+
210+
/* First try to get the dbname from connection string. */
211+
if (connstr)
212+
{
213+
conn_opts = PQconninfoParse(connstr, &err_msg);
214+
if (conn_opts == NULL)
215+
pg_fatal("%s", err_msg);
216+
217+
dbname = FindDbnameInConnOpts(conn_opts);
218+
219+
PQconninfoFree(conn_opts);
220+
if (dbname)
221+
return dbname;
222+
}
223+
224+
/*
225+
* Next try to get the dbname from default values that are available from
226+
* the environment.
227+
*/
228+
conn_opts = PQconndefaults();
229+
if (conn_opts == NULL)
230+
pg_fatal("out of memory");
231+
232+
dbname = FindDbnameInConnOpts(conn_opts);
233+
234+
PQconninfoFree(conn_opts);
235+
return dbname;
236+
}

src/include/fe_utils/recovery_gen.h

+1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ extern PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn,
2525
char *dbname);
2626
extern void WriteRecoveryConfig(PGconn *pgconn, const char *target_dir,
2727
PQExpBuffer contents);
28+
extern char *GetDbnameFromConnectionOptions(const char *connstr);
2829

2930
#endif /* RECOVERY_GEN_H */

0 commit comments

Comments
 (0)