Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a145f42

Browse files
author
Amit Kapila
committed
Allow dbname to be written as part of connstring via pg_basebackup's -R option.
Commit cca97ce allowed dbname in pg_basebackup connstring and in this commit we allow it to be written in postgresql.auto.conf when -R option is used. The database name in the connection string will be used by the logical replication slot synchronization on standby. The dbname will be recorded only if specified explicitly in the connection string or environment variable. Masahiko Sawada hasn't reviewed the code in detail but endorsed the idea. Author: Vignesh C, Kuroda Hayato Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/CAB8KJ=hdKdg+UeXhReeHpHA6N6v3e0qFF+ZsPFHk9_ThWKf=2A@mail.gmail.com
1 parent 30e1442 commit a145f42

File tree

8 files changed

+127
-8
lines changed

8 files changed

+127
-8
lines changed

doc/src/sgml/ref/pg_basebackup.sgml

+8-2
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,11 @@ PostgreSQL documentation
243243
The <filename>postgresql.auto.conf</filename> file will record the connection
244244
settings and, if specified, the replication slot
245245
that <application>pg_basebackup</application> is using, so that
246-
streaming replication will use the same settings later on.
246+
streaming replication and <link linkend="logicaldecoding-replication-slots-synchronization">
247+
logical replication slot synchronization</link> will use the same
248+
settings later on. The dbname will be recorded only if the dbname was
249+
specified explicitly in the connection string or <link linkend="libpq-envars">
250+
environment variable</link>.
247251
</para>
248252

249253
</listitem>
@@ -809,7 +813,9 @@ PostgreSQL documentation
809813
name in the connection string will be ignored
810814
by <productname>PostgreSQL</productname>. Middleware, or proxies, used in
811815
connecting to <productname>PostgreSQL</productname> might however
812-
utilize the value.
816+
utilize the value. The database name specified in connection string can
817+
also be used by <link linkend="logicaldecoding-replication-slots-synchronization">
818+
logical replication slot synchronization</link>.
813819
</para>
814820
</listitem>
815821
</varlistentry>

src/bin/pg_basebackup/pg_basebackup.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -1807,10 +1807,18 @@ BaseBackup(char *compression_algorithm, char *compression_detail,
18071807
}
18081808

18091809
/*
1810-
* Build contents of configuration file if requested
1810+
* Build contents of configuration file if requested.
1811+
*
1812+
* Note that we don't use the dbname from key-value pair in conn as that
1813+
* would have been filled by the default dbname (dbname=replication) in
1814+
* case the user didn't specify the one. The dbname written in the config
1815+
* file as part of primary_conninfo would be used by slotsync worker which
1816+
* doesn't use a replication connection so the default won't work for it.
18111817
*/
18121818
if (writerecoveryconf)
1813-
recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot);
1819+
recoveryconfcontents = GenerateRecoveryConfig(conn,
1820+
replication_slot,
1821+
GetDbnameFromConnectionOptions());
18141822

18151823
/*
18161824
* Run IDENTIFY_SYSTEM so we can get the timeline

src/bin/pg_basebackup/streamutil.c

+70
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
int WalSegSz;
3535

3636
static bool RetrieveDataDirCreatePerm(PGconn *conn);
37+
static void FindDbnameInConnParams(PQconninfoOption *conn_opts, char **dbname);
3738

3839
/* SHOW command for replication connection was introduced in version 10 */
3940
#define MINIMUM_VERSION_FOR_SHOW_CMD 100000
@@ -267,6 +268,75 @@ GetConnection(void)
267268
return tmpconn;
268269
}
269270

271+
/*
272+
* FindDbnameInConnParams
273+
*
274+
* This is a helper function for GetDbnameFromConnectionOptions(). Extract
275+
* the value of dbname from PQconninfoOption parameters.
276+
*/
277+
static void
278+
FindDbnameInConnParams(PQconninfoOption *conn_opts, char **dbname)
279+
{
280+
PQconninfoOption *conn_opt;
281+
282+
Assert(dbname != NULL);
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+
*dbname = pg_strdup(conn_opt->val);
289+
}
290+
}
291+
292+
/*
293+
* GetDbnameFromConnectionOptions
294+
*
295+
* This is a special purpose function to retrieve the dbname from either the
296+
* connection_string specified by the user or from the environment variables.
297+
*
298+
* We follow GetConnection() to fetch the dbname from various connection
299+
* options.
300+
*
301+
* Returns NULL, if dbname is not specified by the user in the above
302+
* mentioned connection options.
303+
*/
304+
char *
305+
GetDbnameFromConnectionOptions(void)
306+
{
307+
PQconninfoOption *conn_opts = NULL;
308+
char *err_msg = NULL;
309+
char *dbname = NULL;
310+
311+
/* First try to get the dbname from connection string. */
312+
if (connection_string)
313+
{
314+
conn_opts = PQconninfoParse(connection_string, &err_msg);
315+
if (conn_opts == NULL)
316+
pg_fatal("%s", err_msg);
317+
318+
FindDbnameInConnParams(conn_opts, &dbname);
319+
if (dbname)
320+
{
321+
PQconninfoFree(conn_opts);
322+
return dbname;
323+
}
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+
FindDbnameInConnParams(conn_opts, &dbname);
335+
336+
PQconninfoFree(conn_opts);
337+
return dbname;
338+
}
339+
270340
/*
271341
* From version 10, explicitly set wal segment size using SHOW wal_segment_size
272342
* since ControlFile is not accessible here.

src/bin/pg_basebackup/streamutil.h

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

3232
extern PGconn *GetConnection(void);
3333

34+
extern char *GetDbnameFromConnectionOptions(void);
35+
3436
/* Replication commands */
3537
extern bool CreateReplicationSlot(PGconn *conn, const char *slot_name,
3638
const char *plugin, bool is_temporary,

src/bin/pg_basebackup/t/010_pg_basebackup.pl

+13
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,19 @@
783783
is($checksum, 'on', 'checksums are enabled');
784784
rmtree("$tempdir/backupxs_sl_R");
785785

786+
$node->command_ok(
787+
[
788+
@pg_basebackup_defs, '-D', "$tempdir/backup_dbname_R", '-X',
789+
'stream', '-d', "dbname=db1", '-R',
790+
],
791+
'pg_basebackup with dbname and -R runs');
792+
like(
793+
slurp_file("$tempdir/backup_dbname_R/postgresql.auto.conf"),
794+
qr/dbname=db1/m,
795+
'recovery conf file sets dbname');
796+
797+
rmtree("$tempdir/backup_dbname_R");
798+
786799
# create tables to corrupt and get their relfilenodes
787800
my $file_corrupt1 = $node->safe_psql('postgres',
788801
q{CREATE TABLE corrupt1 AS SELECT a FROM generate_series(1,10000) AS a; ALTER TABLE corrupt1 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt1')}

src/bin/pg_rewind/pg_rewind.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ 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));
454+
GenerateRecoveryConfig(conn, NULL, NULL));
455455
exit(0);
456456
}
457457

@@ -525,7 +525,7 @@ main(int argc, char **argv)
525525
/* Also update the standby configuration, if requested. */
526526
if (writerecoveryconf && !dry_run)
527527
WriteRecoveryConfig(conn, datadir_target,
528-
GenerateRecoveryConfig(conn, NULL));
528+
GenerateRecoveryConfig(conn, NULL, NULL));
529529

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

src/fe_utils/recovery_gen.c

+20-1
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@ static char *escape_quotes(const char *src);
1818
/*
1919
* Write recovery configuration contents into a fresh PQExpBuffer, and
2020
* return it.
21+
*
22+
* This accepts the dbname which will be appended to the primary_conninfo.
23+
* The dbname will be ignored by walreciever process but slotsync worker uses
24+
* it to connect to the primary server.
2125
*/
2226
PQExpBuffer
23-
GenerateRecoveryConfig(PGconn *pgconn, const char *replication_slot)
27+
GenerateRecoveryConfig(PGconn *pgconn, const char *replication_slot,
28+
char *dbname)
2429
{
2530
PQconninfoOption *connOptions;
2631
PQExpBufferData conninfo_buf;
@@ -66,6 +71,20 @@ GenerateRecoveryConfig(PGconn *pgconn, const char *replication_slot)
6671
appendPQExpBuffer(&conninfo_buf, "%s=", opt->keyword);
6772
appendConnStrVal(&conninfo_buf, opt->val);
6873
}
74+
75+
if (dbname)
76+
{
77+
/*
78+
* If dbname is specified in the connection, append the dbname. This
79+
* will be used later for logical replication slot synchronization.
80+
*/
81+
if (conninfo_buf.len != 0)
82+
appendPQExpBufferChar(&conninfo_buf, ' ');
83+
84+
appendPQExpBuffer(&conninfo_buf, "%s=", "dbname");
85+
appendConnStrVal(&conninfo_buf, dbname);
86+
}
87+
6988
if (PQExpBufferDataBroken(conninfo_buf))
7089
pg_fatal("out of memory");
7190

src/include/fe_utils/recovery_gen.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
#define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000
2222

2323
extern PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn,
24-
const char *replication_slot);
24+
const char *replication_slot,
25+
char *dbname);
2526
extern void WriteRecoveryConfig(PGconn *pgconn, const char *target_dir,
2627
PQExpBuffer contents);
2728

0 commit comments

Comments
 (0)