Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)