mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
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
This commit is contained in:
parent
832054044f
commit
be1cc8f46f
@ -847,6 +847,27 @@ PostgreSQL documentation
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--snapshot=<replaceable class="parameter">snapshotname</replaceable></option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Use the specifed synchronized snapshot when making a dump of the
|
||||||
|
database (see
|
||||||
|
<xref linkend="functions-snapshot-synchronization-table"> for more
|
||||||
|
details).
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This option is useful when needing to synchronize the dump with
|
||||||
|
a logical replication slot (see <xref linkend="logicaldecoding">)
|
||||||
|
or with a concurrent session.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
In the case of a parallel dump, the snapshot name defined by this
|
||||||
|
option is used rather than taking a new snapshot.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--serializable-deferrable</option></term>
|
<term><option>--serializable-deferrable</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -126,7 +126,8 @@ static const CatalogId nilCatalogId = {0, 0};
|
|||||||
|
|
||||||
static void help(const char *progname);
|
static void help(const char *progname);
|
||||||
static void setup_connection(Archive *AH, DumpOptions *dopt,
|
static void setup_connection(Archive *AH, DumpOptions *dopt,
|
||||||
const char *dumpencoding, char *use_role);
|
const char *dumpencoding, const char *dumpsnapshot,
|
||||||
|
char *use_role);
|
||||||
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
|
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
|
||||||
static void expand_schema_name_patterns(Archive *fout,
|
static void expand_schema_name_patterns(Archive *fout,
|
||||||
SimpleStringList *patterns,
|
SimpleStringList *patterns,
|
||||||
@ -269,6 +270,7 @@ main(int argc, char **argv)
|
|||||||
RestoreOptions *ropt;
|
RestoreOptions *ropt;
|
||||||
Archive *fout; /* the script file */
|
Archive *fout; /* the script file */
|
||||||
const char *dumpencoding = NULL;
|
const char *dumpencoding = NULL;
|
||||||
|
const char *dumpsnapshot = NULL;
|
||||||
char *use_role = NULL;
|
char *use_role = NULL;
|
||||||
int numWorkers = 1;
|
int numWorkers = 1;
|
||||||
trivalue prompt_password = TRI_DEFAULT;
|
trivalue prompt_password = TRI_DEFAULT;
|
||||||
@ -329,6 +331,7 @@ main(int argc, char **argv)
|
|||||||
{"role", required_argument, NULL, 3},
|
{"role", required_argument, NULL, 3},
|
||||||
{"section", required_argument, NULL, 5},
|
{"section", required_argument, NULL, 5},
|
||||||
{"serializable-deferrable", no_argument, &dopt->serializable_deferrable, 1},
|
{"serializable-deferrable", no_argument, &dopt->serializable_deferrable, 1},
|
||||||
|
{"snapshot", required_argument, NULL, 6},
|
||||||
{"use-set-session-authorization", no_argument, &dopt->use_setsessauth, 1},
|
{"use-set-session-authorization", no_argument, &dopt->use_setsessauth, 1},
|
||||||
{"no-security-labels", no_argument, &dopt->no_security_labels, 1},
|
{"no-security-labels", no_argument, &dopt->no_security_labels, 1},
|
||||||
{"no-synchronized-snapshots", no_argument, &dopt->no_synchronized_snapshots, 1},
|
{"no-synchronized-snapshots", no_argument, &dopt->no_synchronized_snapshots, 1},
|
||||||
@ -506,6 +509,10 @@ main(int argc, char **argv)
|
|||||||
set_dump_section(optarg, &dopt->dumpSections);
|
set_dump_section(optarg, &dopt->dumpSections);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 6: /* snapshot */
|
||||||
|
dumpsnapshot = pg_strdup(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
||||||
exit_nicely(1);
|
exit_nicely(1);
|
||||||
@ -614,7 +621,7 @@ main(int argc, char **argv)
|
|||||||
* death.
|
* death.
|
||||||
*/
|
*/
|
||||||
ConnectDatabase(fout, dopt->dbname, dopt->pghost, dopt->pgport, dopt->username, prompt_password);
|
ConnectDatabase(fout, dopt->dbname, dopt->pghost, dopt->pgport, dopt->username, prompt_password);
|
||||||
setup_connection(fout, dopt, dumpencoding, use_role);
|
setup_connection(fout, dopt, dumpencoding, dumpsnapshot, use_role);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable security label support if server version < v9.1.x (prevents
|
* Disable security label support if server version < v9.1.x (prevents
|
||||||
@ -658,6 +665,11 @@ main(int argc, char **argv)
|
|||||||
"Run with --no-synchronized-snapshots instead if you do not need\n"
|
"Run with --no-synchronized-snapshots instead if you do not need\n"
|
||||||
"synchronized snapshots.\n");
|
"synchronized snapshots.\n");
|
||||||
|
|
||||||
|
/* check the version when a snapshot is explicitly specified by user */
|
||||||
|
if (dumpsnapshot && fout->remoteVersion < 90200)
|
||||||
|
exit_horribly(NULL,
|
||||||
|
"Exported snapshots are not supported by this server version.\n");
|
||||||
|
|
||||||
/* Find the last built-in OID, if needed */
|
/* Find the last built-in OID, if needed */
|
||||||
if (fout->remoteVersion < 70300)
|
if (fout->remoteVersion < 70300)
|
||||||
{
|
{
|
||||||
@ -888,6 +900,7 @@ help(const char *progname)
|
|||||||
printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
|
printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
|
||||||
printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
|
printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
|
||||||
printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
|
printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
|
||||||
|
printf(_(" --snapshot=SNAPSHOT use given synchronous snapshot for the dump\n"));
|
||||||
printf(_(" --use-set-session-authorization\n"
|
printf(_(" --use-set-session-authorization\n"
|
||||||
" use SET SESSION AUTHORIZATION commands instead of\n"
|
" use SET SESSION AUTHORIZATION commands instead of\n"
|
||||||
" ALTER OWNER commands to set ownership\n"));
|
" ALTER OWNER commands to set ownership\n"));
|
||||||
@ -907,7 +920,8 @@ help(const char *progname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_connection(Archive *AH, DumpOptions *dopt, const char *dumpencoding, char *use_role)
|
setup_connection(Archive *AH, DumpOptions *dopt, const char *dumpencoding,
|
||||||
|
const char *dumpsnapshot, char *use_role)
|
||||||
{
|
{
|
||||||
PGconn *conn = GetConnection(AH);
|
PGconn *conn = GetConnection(AH);
|
||||||
const char *std_strings;
|
const char *std_strings;
|
||||||
@ -1015,22 +1029,25 @@ setup_connection(Archive *AH, DumpOptions *dopt, const char *dumpencoding, char
|
|||||||
ExecuteSqlStatement(AH,
|
ExecuteSqlStatement(AH,
|
||||||
"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
|
"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* define an export snapshot, either chosen by user or needed for
|
||||||
|
* parallel dump.
|
||||||
|
*/
|
||||||
|
if (dumpsnapshot)
|
||||||
|
AH->sync_snapshot_id = strdup(dumpsnapshot);
|
||||||
|
|
||||||
|
if (AH->sync_snapshot_id)
|
||||||
if (AH->numWorkers > 1 && AH->remoteVersion >= 90200 && !dopt->no_synchronized_snapshots)
|
|
||||||
{
|
{
|
||||||
if (AH->sync_snapshot_id)
|
PQExpBuffer query = createPQExpBuffer();
|
||||||
{
|
appendPQExpBuffer(query, "SET TRANSACTION SNAPSHOT ");
|
||||||
PQExpBuffer query = createPQExpBuffer();
|
appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
|
||||||
|
ExecuteSqlStatement(AH, query->data);
|
||||||
appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
|
destroyPQExpBuffer(query);
|
||||||
appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
|
|
||||||
ExecuteSqlStatement(AH, query->data);
|
|
||||||
destroyPQExpBuffer(query);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
AH->sync_snapshot_id = get_synchronized_snapshot(AH);
|
|
||||||
}
|
}
|
||||||
|
else if (AH->numWorkers > 1 &&
|
||||||
|
AH->remoteVersion >= 90200 &&
|
||||||
|
!dopt->no_synchronized_snapshots)
|
||||||
|
AH->sync_snapshot_id = get_synchronized_snapshot(AH);
|
||||||
|
|
||||||
if (AH->remoteVersion >= 90500)
|
if (AH->remoteVersion >= 90500)
|
||||||
{
|
{
|
||||||
@ -1044,7 +1061,7 @@ setup_connection(Archive *AH, DumpOptions *dopt, const char *dumpencoding, char
|
|||||||
static void
|
static void
|
||||||
setupDumpWorker(Archive *AHX, DumpOptions *dopt, RestoreOptions *ropt)
|
setupDumpWorker(Archive *AHX, DumpOptions *dopt, RestoreOptions *ropt)
|
||||||
{
|
{
|
||||||
setup_connection(AHX, dopt, NULL, NULL);
|
setup_connection(AHX, dopt, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
Loading…
x
Reference in New Issue
Block a user