Skip to content

Commit e7b020f

Browse files
committed
Make pg_basebackup use temporary replication slots
Temporary replication slots will be used by default when wal streaming is used and no slot name is specified with -S. If a slot name is specified, then a permanent slot with that name is used. If --no-slot is specified, then no permanent or temporary slot will be used. Temporary slots are only used on 10.0 and newer, of course.
1 parent 8fa6019 commit e7b020f

File tree

9 files changed

+101
-8
lines changed

9 files changed

+101
-8
lines changed

doc/src/sgml/ref/pg_basebackup.sgml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,31 @@ PostgreSQL documentation
240240
the server does not remove any necessary WAL data in the time between
241241
the end of the base backup and the start of streaming replication.
242242
</para>
243+
<para>
244+
If this option is not specified and the server supports temporary
245+
replication slots (version 10 and later), then a temporary replication
246+
slot is automatically used for WAL streaming.
247+
</para>
248+
</listitem>
249+
</varlistentry>
250+
251+
<varlistentry>
252+
<term><option>--no-slot</option></term>
253+
<listitem>
254+
<para>
255+
This option prevents the creation of a temporary replication slot
256+
during the backup even if it's supported by the server.
257+
</para>
258+
<para>
259+
Temporary replication slots are created by default if no slot name
260+
is given with the option <option>-S</option> when using log streaming.
261+
</para>
262+
<para>
263+
The main purpose of this option is to allow taking a base backup when
264+
the server is out of free replication slots. Using replication slots
265+
is almost always preferred, because it prevents needed WAL from being
266+
removed by the server during the backup.
267+
</para>
243268
</listitem>
244269
</varlistentry>
245270

src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ typedef struct TablespaceList
6161
*/
6262
#define MINIMUM_VERSION_FOR_PG_WAL 100000
6363

64+
/*
65+
* Temporary replication slots are supported from version 10.
66+
*/
67+
#define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000
68+
6469
/*
6570
* Different ways to include WAL
6671
*/
@@ -88,6 +93,8 @@ static bool do_sync = true;
8893
static int standby_message_timeout = 10 * 1000; /* 10 sec = default */
8994
static pg_time_t last_progress_report = 0;
9095
static int32 maxrate = 0; /* no limit by default */
96+
static char *replication_slot = NULL;
97+
static bool temp_replication_slot = true;
9198

9299
static bool success = false;
93100
static bool made_new_pgdata = false;
@@ -332,6 +339,7 @@ usage(void)
332339
printf(_(" -R, --write-recovery-conf\n"
333340
" write recovery.conf after backup\n"));
334341
printf(_(" -S, --slot=SLOTNAME replication slot to use\n"));
342+
printf(_(" --no-slot prevent creation of temporary replication slot\n"));
335343
printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
336344
" relocate tablespace in OLDDIR to NEWDIR\n"));
337345
printf(_(" -X, --xlog-method=none|fetch|stream\n"
@@ -460,6 +468,7 @@ typedef struct
460468
char xlog[MAXPGPATH]; /* directory or tarfile depending on mode */
461469
char *sysidentifier;
462470
int timeline;
471+
bool temp_slot;
463472
} logstreamer_param;
464473

465474
static int
@@ -479,6 +488,10 @@ LogStreamerMain(logstreamer_param *param)
479488
stream.do_sync = do_sync;
480489
stream.mark_done = true;
481490
stream.partial_suffix = NULL;
491+
stream.replication_slot = replication_slot;
492+
stream.temp_slot = param->temp_slot;
493+
if (stream.temp_slot && !stream.replication_slot)
494+
stream.replication_slot = psprintf("pg_basebackup_%d", (int) getpid());
482495

483496
if (format == 'p')
484497
stream.walmethod = CreateWalDirectoryMethod(param->xlog, do_sync);
@@ -565,6 +578,11 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
565578
PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
566579
"pg_xlog" : "pg_wal");
567580

581+
/* Temporary replication slots are only supported in 10 and newer */
582+
if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_TEMP_SLOTS)
583+
param->temp_slot = false;
584+
else
585+
param->temp_slot = temp_replication_slot;
568586

569587
if (format == 'p')
570588
{
@@ -2063,11 +2081,13 @@ main(int argc, char **argv)
20632081
{"verbose", no_argument, NULL, 'v'},
20642082
{"progress", no_argument, NULL, 'P'},
20652083
{"xlogdir", required_argument, NULL, 1},
2084+
{"no-slot", no_argument, NULL, 2},
20662085
{NULL, 0, NULL, 0}
20672086
};
20682087
int c;
20692088

20702089
int option_index;
2090+
bool no_slot = false;
20712091

20722092
progname = get_progname(argv[0]);
20732093
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
@@ -2117,7 +2137,16 @@ main(int argc, char **argv)
21172137
writerecoveryconf = true;
21182138
break;
21192139
case 'S':
2140+
2141+
/*
2142+
* When specifying replication slot name, use a permanent
2143+
* slot.
2144+
*/
21202145
replication_slot = pg_strdup(optarg);
2146+
temp_replication_slot = false;
2147+
break;
2148+
case 2:
2149+
no_slot = true;
21212150
break;
21222151
case 'T':
21232152
tablespace_list_append(optarg);
@@ -2277,7 +2306,7 @@ main(int argc, char **argv)
22772306
exit(1);
22782307
}
22792308

2280-
if (replication_slot && includewal != STREAM_WAL)
2309+
if ((replication_slot || no_slot) && includewal != STREAM_WAL)
22812310
{
22822311
fprintf(stderr,
22832312
_("%s: replication slots can only be used with WAL streaming\n"),
@@ -2287,6 +2316,20 @@ main(int argc, char **argv)
22872316
exit(1);
22882317
}
22892318

2319+
if (no_slot)
2320+
{
2321+
if (replication_slot)
2322+
{
2323+
fprintf(stderr,
2324+
_("%s: --no-slot cannot be used with slot name\n"),
2325+
progname);
2326+
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2327+
progname);
2328+
exit(1);
2329+
}
2330+
temp_replication_slot = false;
2331+
}
2332+
22902333
if (strcmp(xlog_dir, "") != 0)
22912334
{
22922335
if (format != 'p')

src/bin/pg_basebackup/pg_receivexlog.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static bool do_create_slot = false;
4141
static bool slot_exists_ok = false;
4242
static bool do_drop_slot = false;
4343
static bool synchronous = false;
44+
static char *replication_slot = NULL;
4445

4546

4647
static void usage(void);
@@ -340,6 +341,8 @@ StreamLog(void)
340341
stream.mark_done = false;
341342
stream.walmethod = CreateWalDirectoryMethod(basedir, stream.do_sync);
342343
stream.partial_suffix = ".partial";
344+
stream.replication_slot = replication_slot;
345+
stream.temp_slot = false;
343346

344347
ReceiveXlogStream(conn, &stream);
345348

src/bin/pg_basebackup/pg_recvlogical.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static bool do_create_slot = false;
4545
static bool slot_exists_ok = false;
4646
static bool do_start_slot = false;
4747
static bool do_drop_slot = false;
48+
static char *replication_slot = NULL;
4849

4950
/* filled pairwise with option, value. value may be NULL */
5051
static char **options;

src/bin/pg_basebackup/receivelog.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,10 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
455455
* synchronous_standby_names, but we've protected them against it so
456456
* far, so let's continue to do so unless specifically requested.
457457
*/
458-
if (replication_slot != NULL)
458+
if (stream->replication_slot != NULL)
459459
{
460460
reportFlushPosition = true;
461-
sprintf(slotcmd, "SLOT \"%s\" ", replication_slot);
461+
sprintf(slotcmd, "SLOT \"%s\" ", stream->replication_slot);
462462
}
463463
else
464464
{
@@ -508,6 +508,24 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
508508
PQclear(res);
509509
}
510510

511+
/*
512+
* Create temporary replication slot if one is needed
513+
*/
514+
if (stream->temp_slot)
515+
{
516+
snprintf(query, sizeof(query),
517+
"CREATE_REPLICATION_SLOT \"%s\" TEMPORARY PHYSICAL RESERVE_WAL",
518+
stream->replication_slot);
519+
res = PQexec(conn, query);
520+
if (PQresultStatus(res) != PGRES_TUPLES_OK)
521+
{
522+
fprintf(stderr, _("%s: could not create temporary replication slot \"%s\": %s"),
523+
progname, stream->replication_slot, PQerrorMessage(conn));
524+
PQclear(res);
525+
return false;
526+
}
527+
}
528+
511529
/*
512530
* initialize flush position to starting point, it's the caller's
513531
* responsibility that that's sane.

src/bin/pg_basebackup/receivelog.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,15 @@ typedef struct StreamCtl
3737
* often */
3838
bool synchronous; /* Flush immediately WAL data on write */
3939
bool mark_done; /* Mark segment as done in generated archive */
40-
bool do_sync; /* Flush to disk to ensure consistent state
41-
* of data */
40+
bool do_sync; /* Flush to disk to ensure consistent state of
41+
* data */
4242

4343
stream_stop_callback stream_stop; /* Stop streaming when returns true */
4444

4545
WalWriteMethod *walmethod; /* How to write the WAL */
4646
char *partial_suffix; /* Suffix appended to partially received files */
47+
char *replication_slot; /* Replication slot to use, or NULL */
48+
bool temp_slot; /* Create temporary replication slot */
4749
} StreamCtl;
4850

4951

src/bin/pg_basebackup/streamutil.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ char *connection_string = NULL;
3838
char *dbhost = NULL;
3939
char *dbuser = NULL;
4040
char *dbport = NULL;
41-
char *replication_slot = NULL;
4241
char *dbname = NULL;
4342
int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */
4443
static bool have_password = false;

src/bin/pg_basebackup/streamutil.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ extern char *dbuser;
2323
extern char *dbport;
2424
extern char *dbname;
2525
extern int dbgetpassword;
26-
extern char *replication_slot;
2726

2827
/* Connection kept global so we can disconnect easily */
2928
extern PGconn *conn;

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use Config;
55
use PostgresNode;
66
use TestLib;
7-
use Test::More tests => 71;
7+
use Test::More tests => 72;
88

99
program_help_ok('pg_basebackup');
1010
program_version_ok('pg_basebackup');
@@ -244,6 +244,9 @@
244244
[ 'pg_basebackup', '-D', "$tempdir/backupxst", '-X', 'stream', '-Ft' ],
245245
'pg_basebackup -X stream runs in tar mode');
246246
ok(-f "$tempdir/backupxst/pg_wal.tar", "tar file was created");
247+
$node->command_ok(
248+
[ 'pg_basebackup', '-D', "$tempdir/backupnoslot", '-X', 'stream', '--no-slot' ],
249+
'pg_basebackup -X stream runs with --no-slot');
247250

248251
$node->command_fails(
249252
[ 'pg_basebackup', '-D', "$tempdir/fail", '-S', 'slot1' ],

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy