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

Commit be1cc8f

Browse files
Add pg_dump --snapshot option
Allows pg_dump to use a snapshot previously defined by a concurrent session that has either used pg_export_snapshot() or obtained a snapshot when creating a logical slot. When this option is used with parallel pg_dump, the snapshot defined by this option is used and no new snapshot is taken. Simon Riggs and Michael Paquier
1 parent 8320540 commit be1cc8f

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

doc/src/sgml/ref/pg_dump.sgml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,27 @@ PostgreSQL documentation
847847
</listitem>
848848
</varlistentry>
849849

850+
<varlistentry>
851+
<term><option>--snapshot=<replaceable class="parameter">snapshotname</replaceable></option></term>
852+
<listitem>
853+
<para>
854+
Use the specifed synchronized snapshot when making a dump of the
855+
database (see
856+
<xref linkend="functions-snapshot-synchronization-table"> for more
857+
details).
858+
</para>
859+
<para>
860+
This option is useful when needing to synchronize the dump with
861+
a logical replication slot (see <xref linkend="logicaldecoding">)
862+
or with a concurrent session.
863+
</para>
864+
<para>
865+
In the case of a parallel dump, the snapshot name defined by this
866+
option is used rather than taking a new snapshot.
867+
</para>
868+
</listitem>
869+
</varlistentry>
870+
850871
<varlistentry>
851872
<term><option>--serializable-deferrable</option></term>
852873
<listitem>

src/bin/pg_dump/pg_dump.c

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ static const CatalogId nilCatalogId = {0, 0};
126126

127127
static void help(const char *progname);
128128
static void setup_connection(Archive *AH, DumpOptions *dopt,
129-
const char *dumpencoding, char *use_role);
129+
const char *dumpencoding, const char *dumpsnapshot,
130+
char *use_role);
130131
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
131132
static void expand_schema_name_patterns(Archive *fout,
132133
SimpleStringList *patterns,
@@ -269,6 +270,7 @@ main(int argc, char **argv)
269270
RestoreOptions *ropt;
270271
Archive *fout; /* the script file */
271272
const char *dumpencoding = NULL;
273+
const char *dumpsnapshot = NULL;
272274
char *use_role = NULL;
273275
int numWorkers = 1;
274276
trivalue prompt_password = TRI_DEFAULT;
@@ -329,6 +331,7 @@ main(int argc, char **argv)
329331
{"role", required_argument, NULL, 3},
330332
{"section", required_argument, NULL, 5},
331333
{"serializable-deferrable", no_argument, &dopt->serializable_deferrable, 1},
334+
{"snapshot", required_argument, NULL, 6},
332335
{"use-set-session-authorization", no_argument, &dopt->use_setsessauth, 1},
333336
{"no-security-labels", no_argument, &dopt->no_security_labels, 1},
334337
{"no-synchronized-snapshots", no_argument, &dopt->no_synchronized_snapshots, 1},
@@ -506,6 +509,10 @@ main(int argc, char **argv)
506509
set_dump_section(optarg, &dopt->dumpSections);
507510
break;
508511

512+
case 6: /* snapshot */
513+
dumpsnapshot = pg_strdup(optarg);
514+
break;
515+
509516
default:
510517
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
511518
exit_nicely(1);
@@ -614,7 +621,7 @@ main(int argc, char **argv)
614621
* death.
615622
*/
616623
ConnectDatabase(fout, dopt->dbname, dopt->pghost, dopt->pgport, dopt->username, prompt_password);
617-
setup_connection(fout, dopt, dumpencoding, use_role);
624+
setup_connection(fout, dopt, dumpencoding, dumpsnapshot, use_role);
618625

619626
/*
620627
* Disable security label support if server version < v9.1.x (prevents
@@ -658,6 +665,11 @@ main(int argc, char **argv)
658665
"Run with --no-synchronized-snapshots instead if you do not need\n"
659666
"synchronized snapshots.\n");
660667

668+
/* check the version when a snapshot is explicitly specified by user */
669+
if (dumpsnapshot && fout->remoteVersion < 90200)
670+
exit_horribly(NULL,
671+
"Exported snapshots are not supported by this server version.\n");
672+
661673
/* Find the last built-in OID, if needed */
662674
if (fout->remoteVersion < 70300)
663675
{
@@ -888,6 +900,7 @@ help(const char *progname)
888900
printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
889901
printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
890902
printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
903+
printf(_(" --snapshot=SNAPSHOT use given synchronous snapshot for the dump\n"));
891904
printf(_(" --use-set-session-authorization\n"
892905
" use SET SESSION AUTHORIZATION commands instead of\n"
893906
" ALTER OWNER commands to set ownership\n"));
@@ -907,7 +920,8 @@ help(const char *progname)
907920
}
908921

909922
static void
910-
setup_connection(Archive *AH, DumpOptions *dopt, const char *dumpencoding, char *use_role)
923+
setup_connection(Archive *AH, DumpOptions *dopt, const char *dumpencoding,
924+
const char *dumpsnapshot, char *use_role)
911925
{
912926
PGconn *conn = GetConnection(AH);
913927
const char *std_strings;
@@ -1015,22 +1029,25 @@ setup_connection(Archive *AH, DumpOptions *dopt, const char *dumpencoding, char
10151029
ExecuteSqlStatement(AH,
10161030
"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
10171031

1032+
/*
1033+
* define an export snapshot, either chosen by user or needed for
1034+
* parallel dump.
1035+
*/
1036+
if (dumpsnapshot)
1037+
AH->sync_snapshot_id = strdup(dumpsnapshot);
10181038

1019-
1020-
if (AH->numWorkers > 1 && AH->remoteVersion >= 90200 && !dopt->no_synchronized_snapshots)
1039+
if (AH->sync_snapshot_id)
10211040
{
1022-
if (AH->sync_snapshot_id)
1023-
{
1024-
PQExpBuffer query = createPQExpBuffer();
1025-
1026-
appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
1027-
appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
1028-
ExecuteSqlStatement(AH, query->data);
1029-
destroyPQExpBuffer(query);
1030-
}
1031-
else
1032-
AH->sync_snapshot_id = get_synchronized_snapshot(AH);
1041+
PQExpBuffer query = createPQExpBuffer();
1042+
appendPQExpBuffer(query, "SET TRANSACTION SNAPSHOT ");
1043+
appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
1044+
ExecuteSqlStatement(AH, query->data);
1045+
destroyPQExpBuffer(query);
10331046
}
1047+
else if (AH->numWorkers > 1 &&
1048+
AH->remoteVersion >= 90200 &&
1049+
!dopt->no_synchronized_snapshots)
1050+
AH->sync_snapshot_id = get_synchronized_snapshot(AH);
10341051

10351052
if (AH->remoteVersion >= 90500)
10361053
{
@@ -1044,7 +1061,7 @@ setup_connection(Archive *AH, DumpOptions *dopt, const char *dumpencoding, char
10441061
static void
10451062
setupDumpWorker(Archive *AHX, DumpOptions *dopt, RestoreOptions *ropt)
10461063
{
1047-
setup_connection(AHX, dopt, NULL, NULL);
1064+
setup_connection(AHX, dopt, NULL, NULL, NULL);
10481065
}
10491066

10501067
static char *

0 commit comments

Comments
 (0)