Skip to content

Commit 0b16f15

Browse files
petereegor-rogov
authored andcommitted
pg_basebackup: Add --slot option
This option specifies a replication slot for WAL streaming (-X stream), so that there can be continuous replication slot use between WAL streaming during the base backup and the start of regular streaming replication. Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
1 parent cac452e commit 0b16f15

File tree

4 files changed

+62
-6
lines changed

4 files changed

+62
-6
lines changed

doc/src/sgml/ref/pg_basebackup.sgml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,35 @@ doc/src/sgml/ref/pg_basebackup.sgml
215215
<listitem>
216216

217217
<para>
218-
Write a minimal <filename>recovery.conf</filename> in the output directory (or into
219-
the base archive file when using tar format) to ease setting
220-
up a standby server.
218+
Write a minimal <filename>recovery.conf</filename> in the output
219+
directory (or into the base archive file when using tar format) to
220+
ease setting up a standby server.
221+
The <filename>recovery.conf</filename> file will record the connection
222+
settings and, if specified, the replication slot
223+
that <application>pg_basebackup</application> is using, so that the
224+
streaming replication will use the same settings later on.
221225
</para>
222226

223227
</listitem>
224228
</varlistentry>
225229

230+
<varlistentry>
231+
<term><option>-S <replaceable>slotname</replaceable></option></term>
232+
<term><option>--slot=<replaceable class="parameter">slotname</replaceable></option></term>
233+
<listitem>
234+
<para>
235+
This option can only be used together with <literal>-X
236+
stream</literal>. It causes the WAL streaming to use the specified
237+
replication slot. If the base backup is intended to be used as a
238+
streaming replication standby using replication slots, it should then
239+
use the same replication slot name
240+
in <filename>recovery.conf</filename>. That way, it is ensured that
241+
the server does not remove any necessary WAL data in the time between
242+
the end of the base backup and the start of streaming replication.
243+
</para>
244+
</listitem>
245+
</varlistentry>
246+
226247
<varlistentry>
227248
<term><option>-T <replaceable class="parameter">olddir</replaceable>=<replaceable class="parameter">newdir</replaceable></option></term>
228249
<term><option>--tablespace-mapping=<replaceable class="parameter">olddir</replaceable>=<replaceable class="parameter">newdir</replaceable></option></term>

src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ usage(void)
239239
" (in kB/s, or use suffix \"k\" or \"M\")\n"));
240240
printf(_(" -R, --write-recovery-conf\n"
241241
" write recovery.conf after backup\n"));
242+
printf(_(" -S, --slot=SLOTNAME replication slot to use\n"));
242243
printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
243244
" relocate tablespace in OLDDIR to NEWDIR\n"));
244245
printf(_(" -x, --xlog include required WAL files in backup (fetch mode)\n"));
@@ -1526,6 +1527,13 @@ GenerateRecoveryConf(PGconn *conn)
15261527
appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped);
15271528
free(escaped);
15281529

1530+
if (replication_slot)
1531+
{
1532+
escaped = escape_quotes(replication_slot);
1533+
appendPQExpBuffer(recoveryconfcontents, "primary_slot_name = '%s'\n", replication_slot);
1534+
free(escaped);
1535+
}
1536+
15291537
if (PQExpBufferBroken(recoveryconfcontents) ||
15301538
PQExpBufferDataBroken(conninfo_buf))
15311539
{
@@ -1924,6 +1932,7 @@ main(int argc, char **argv)
19241932
{"checkpoint", required_argument, NULL, 'c'},
19251933
{"max-rate", required_argument, NULL, 'r'},
19261934
{"write-recovery-conf", no_argument, NULL, 'R'},
1935+
{"slot", required_argument, NULL, 'S'},
19271936
{"tablespace-mapping", required_argument, NULL, 'T'},
19281937
{"xlog", no_argument, NULL, 'x'},
19291938
{"xlog-method", required_argument, NULL, 'X'},
@@ -1964,7 +1973,7 @@ main(int argc, char **argv)
19641973
}
19651974
}
19661975

1967-
while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:zZ:d:c:h:p:U:s:wWvP",
1976+
while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:zZ:d:c:h:p:U:s:S:wWvP",
19681977
long_options, &option_index)) != -1)
19691978
{
19701979
switch (c)
@@ -1991,6 +2000,9 @@ main(int argc, char **argv)
19912000
case 'R':
19922001
writerecoveryconf = true;
19932002
break;
2003+
case 'S':
2004+
replication_slot = pg_strdup(optarg);
2005+
break;
19942006
case 'T':
19952007
tablespace_list_append(optarg);
19962008
break;
@@ -2155,6 +2167,16 @@ main(int argc, char **argv)
21552167
exit(1);
21562168
}
21572169

2170+
if (replication_slot && !streamwal)
2171+
{
2172+
fprintf(stderr,
2173+
_("%s: replication slots can only be used with WAL streaming\n"),
2174+
progname);
2175+
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2176+
progname);
2177+
exit(1);
2178+
}
2179+
21582180
if (strcmp(xlog_dir, "") != 0)
21592181
{
21602182
if (format != 'p')

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use Cwd;
44
use Config;
55
use TestLib;
6-
use Test::More tests => 46;
6+
use Test::More tests => 51;
77

88
program_help_ok('pg_basebackup');
99
program_version_ok('pg_basebackup');
@@ -169,3 +169,17 @@
169169
'pg_basebackup with replication slot fails without -X stream');
170170
command_fails([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_fail", '-X', 'stream', '-S', 'slot1' ],
171171
'pg_basebackup fails with nonexistent replication slot');
172+
173+
psql 'postgres', q{SELECT * FROM pg_create_physical_replication_slot('slot1')};
174+
my $lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'};
175+
is($lsn, '', 'restart LSN of new slot is null');
176+
command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl", '-X', 'stream', '-S', 'slot1' ],
177+
'pg_basebackup -X stream with replication slot runs');
178+
$lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'};
179+
like($lsn, qr!^0/[0-9A-Z]{8}$!, 'restart LSN of slot has advanced');
180+
181+
command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_R", '-X', 'stream', '-S', 'slot1', '-R' ],
182+
'pg_basebackup with replication slot and -R runs');
183+
like(slurp_file("$tempdir/backupxs_sl_R/recovery.conf"),
184+
qr/^primary_slot_name = 'slot1'$/m,
185+
'recovery.conf sets primary_slot_name');

src/test/perl/TestLib.pm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ sub psql
227227
print("# Running SQL command: $sql\n");
228228
run [ 'psql', '-X', '-A', '-t', '-q', '-d', $dbname, '-f', '-' ], '<', \$sql, '>', \$stdout, '2>', \$stderr or die;
229229
chomp $stdout;
230-
$stdout =~ s/\r//g if $Config{osname} eq 'msys';
231230
return $stdout;
232231
}
233232

0 commit comments

Comments
 (0)