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)
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