]> granicus.if.org Git - postgresql/commitdiff
pg_basebackup: Add --slot option
authorPeter Eisentraut <peter_e@gmx.net>
Wed, 22 Jul 2015 01:06:45 +0000 (21:06 -0400)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 29 Jul 2015 00:31:35 +0000 (20:31 -0400)
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>
doc/src/sgml/ref/pg_basebackup.sgml
src/bin/pg_basebackup/pg_basebackup.c
src/bin/pg_basebackup/t/010_pg_basebackup.pl
src/test/perl/TestLib.pm

index cb8b8a3c4999b96310eb22473d785bbffb0150f6..5f8b9b7a3fd570aa375e024cad0161870412859b 100644 (file)
@@ -215,14 +215,35 @@ PostgreSQL documentation
       <listitem>
 
        <para>
-        Write a minimal <filename>recovery.conf</filename> in the output directory (or into
-        the base archive file when using tar format) to ease setting
-        up a standby server.
+        Write a minimal <filename>recovery.conf</filename> in the output
+        directory (or into the base archive file when using tar format) to
+        ease setting up a standby server.
+        The <filename>recovery.conf</filename> file will record the connection
+        settings and, if specified, the replication slot
+        that <application>pg_basebackup</application> is using, so that the
+        streaming replication will use the same settings later on.
        </para>
 
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>-S <replaceable>slotname</replaceable></option></term>
+      <term><option>--slot=<replaceable class="parameter">slotname</replaceable></option></term>
+      <listitem>
+       <para>
+        This option can only be used together with <literal>-X
+        stream</literal>.  It causes the WAL streaming to use the specified
+        replication slot.  If the base backup is intended to be used as a
+        streaming replication standby using replication slots, it should then
+        use the same replication slot name
+        in <filename>recovery.conf</filename>.  That way, it is ensured that
+        the server does not remove any necessary WAL data in the time between
+        the end of the base backup and the start of streaming replication.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-T <replaceable class="parameter">olddir</replaceable>=<replaceable class="parameter">newdir</replaceable></option></term>
       <term><option>--tablespace-mapping=<replaceable class="parameter">olddir</replaceable>=<replaceable class="parameter">newdir</replaceable></option></term>
index 536368020b004545736bf51e2a7379e45fa4b0ae..80de8820ff710a276a97bb17371de8d54a1e4b59 100644 (file)
@@ -239,6 +239,7 @@ usage(void)
          "                         (in kB/s, or use suffix \"k\" or \"M\")\n"));
        printf(_("  -R, --write-recovery-conf\n"
                         "                         write recovery.conf after backup\n"));
+       printf(_("  -S, --slot=SLOTNAME    replication slot to use\n"));
        printf(_("  -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
          "                         relocate tablespace in OLDDIR to NEWDIR\n"));
        printf(_("  -x, --xlog             include required WAL files in backup (fetch mode)\n"));
@@ -1536,6 +1537,13 @@ GenerateRecoveryConf(PGconn *conn)
        appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped);
        free(escaped);
 
+       if (replication_slot)
+       {
+               escaped = escape_quotes(replication_slot);
+               appendPQExpBuffer(recoveryconfcontents, "primary_slot_name = '%s'\n", replication_slot);
+               free(escaped);
+       }
+
        if (PQExpBufferBroken(recoveryconfcontents) ||
                PQExpBufferDataBroken(conninfo_buf))
        {
@@ -1934,6 +1942,7 @@ main(int argc, char **argv)
                {"checkpoint", required_argument, NULL, 'c'},
                {"max-rate", required_argument, NULL, 'r'},
                {"write-recovery-conf", no_argument, NULL, 'R'},
+               {"slot", required_argument, NULL, 'S'},
                {"tablespace-mapping", required_argument, NULL, 'T'},
                {"xlog", no_argument, NULL, 'x'},
                {"xlog-method", required_argument, NULL, 'X'},
@@ -1974,7 +1983,7 @@ main(int argc, char **argv)
                }
        }
 
-       while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:zZ:d:c:h:p:U:s:wWvP",
+       while ((c = getopt_long(argc, argv, "D:F:r:RT:xX:l:zZ:d:c:h:p:U:s:S:wWvP",
                                                        long_options, &option_index)) != -1)
        {
                switch (c)
@@ -2001,6 +2010,9 @@ main(int argc, char **argv)
                        case 'R':
                                writerecoveryconf = true;
                                break;
+                       case 'S':
+                               replication_slot = pg_strdup(optarg);
+                               break;
                        case 'T':
                                tablespace_list_append(optarg);
                                break;
@@ -2165,6 +2177,16 @@ main(int argc, char **argv)
                exit(1);
        }
 
+       if (replication_slot && !streamwal)
+       {
+               fprintf(stderr,
+                               _("%s: replication slots can only be used with WAL streaming\n"),
+                               progname);
+               fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
+                               progname);
+               exit(1);
+       }
+
        if (strcmp(xlog_dir, "") != 0)
        {
                if (format != 'p')
index bf9fdcff6c7d5917e4b734cd26b645c9195000c6..b605fa91c012f51d4ec2d6ea6afa0729c4a1cfeb 100644 (file)
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 use Cwd;
 use TestLib;
-use Test::More tests => 44;
+use Test::More tests => 51;
 
 program_help_ok('pg_basebackup');
 program_version_ok('pg_basebackup');
@@ -37,6 +37,7 @@ command_fails(
        'pg_basebackup fails because of WAL configuration');
 
 open CONF, ">>$tempdir/pgdata/postgresql.conf";
+print CONF "max_replication_slots = 10\n";
 print CONF "max_wal_senders = 10\n";
 print CONF "wal_level = archive\n";
 close CONF;
@@ -156,3 +157,22 @@ ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_xlog")), 'WAL files co
 command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs", '-X', 'stream' ],
        'pg_basebackup -X stream runs');
 ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_xlog")), 'WAL files copied');
+
+command_fails([ 'pg_basebackup', '-D', "$tempdir/fail", '-S', 'slot1' ],
+       'pg_basebackup with replication slot fails without -X stream');
+command_fails([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_fail", '-X', 'stream', '-S', 'slot1' ],
+       'pg_basebackup fails with nonexistent replication slot');
+
+psql 'postgres', q{SELECT * FROM pg_create_physical_replication_slot('slot1')};
+my $lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'};
+is($lsn, '', 'restart LSN of new slot is null');
+command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl", '-X', 'stream', '-S', 'slot1' ],
+       'pg_basebackup -X stream with replication slot runs');
+$lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'};
+like($lsn, qr!^0/[0-9A-Z]{8}$!, 'restart LSN of slot has advanced');
+
+command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_R", '-X', 'stream', '-S', 'slot1', '-R' ],
+       'pg_basebackup with replication slot and -R runs');
+like(slurp_file("$tempdir/backupxs_sl_R/recovery.conf"),
+        qr/^primary_slot_name = 'slot1'$/m,
+        'recovery.conf sets primary_slot_name');
index f0379b72256ee3ae36d92566ee2471c09ce63eae..1f69931fe1afba313690e7bcba8866646e18005b 100644 (file)
@@ -173,8 +173,11 @@ END
 sub psql
 {
        my ($dbname, $sql) = @_;
+       my ($stdout, $stderr);
        print("# Running SQL command: $sql\n");
-       run [ 'psql', '-X', '-q', '-d', $dbname, '-f', '-' ], '<', \$sql or die;
+       run [ 'psql', '-X', '-A', '-t', '-q', '-d', $dbname, '-f', '-' ], '<', \$sql, '>', \$stdout, '2>', \$stderr or die;
+       chomp $stdout;
+       return $stdout;
 }
 
 sub slurp_dir