mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
Add --section option to pg_dump and pg_restore.
Valid values are --pre-data, data and post-data. The option can be given more than once. --schema-only is equivalent to --section=pre-data --section=post-data. --data-only is equivalent to --section=data. Andrew Dunstan, reviewed by Joachim Wieland and Josh Berkus.
This commit is contained in:
parent
4b43b48c9f
commit
a4cd6abcc9
@ -116,9 +116,7 @@ PostgreSQL documentation
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This option is only meaningful for the plain-text format. For
|
This option is equivalent to specifying <option>--section=data</>.
|
||||||
the archive formats, you can specify the option when you
|
|
||||||
call <command>pg_restore</command>.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -408,6 +406,26 @@ PostgreSQL documentation
|
|||||||
To exclude table data for only a subset of tables in the database,
|
To exclude table data for only a subset of tables in the database,
|
||||||
see <option>--exclude-table-data</>.
|
see <option>--exclude-table-data</>.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
This option is equivalent to specifying
|
||||||
|
<option>--section=pre-data --section=post-data</>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--section=<replaceable class="parameter">sectionname</replaceable></option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Only dump the named section. The name can be one of <option>pre-data</>, <option>data</>
|
||||||
|
and <option>post-data</>.
|
||||||
|
This option can be specified more than once. The default is to dump all sections.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Post-data items consist of definitions of indexes, triggers, rules
|
||||||
|
and constraints other than check constraints.
|
||||||
|
Pre-data items consist of all other data definition items.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -93,6 +93,9 @@
|
|||||||
<para>
|
<para>
|
||||||
Restore only the data, not the schema (data definitions).
|
Restore only the data, not the schema (data definitions).
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
This option is equivalent to specifying <option>--section=data</>.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@ -359,6 +362,10 @@
|
|||||||
(Do not confuse this with the <option>--schema</> option, which
|
(Do not confuse this with the <option>--schema</> option, which
|
||||||
uses the word <quote>schema</> in a different meaning.)
|
uses the word <quote>schema</> in a different meaning.)
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
This option is equivalent to specifying
|
||||||
|
<option>--section=pre-data --section=post-data</>.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@ -504,6 +511,22 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--section=<replaceable class="parameter">sectionname</replaceable></option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Only restore the named section. The name can be one of <option>pre-data</>, <option>data</>
|
||||||
|
and <option>post-data</>.
|
||||||
|
This option can be specified more than once. The default is to restore all sections.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Post-data items consist of definitions of indexes, triggers, rules
|
||||||
|
and constraints other than check constraints.
|
||||||
|
Pre-data items consist of all other data definition items.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--use-set-session-authorization</option></term>
|
<term><option>--use-set-session-authorization</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "dumputils.h"
|
#include "dumputils.h"
|
||||||
|
#include "pg_backup.h"
|
||||||
|
|
||||||
#include "parser/keywords.h"
|
#include "parser/keywords.h"
|
||||||
|
|
||||||
@ -1262,3 +1263,32 @@ exit_horribly(const char *modulename, const char *fmt,...)
|
|||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the bitmask in dumpSections according to the first argument.
|
||||||
|
* dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
|
||||||
|
* pg_restore so they can know if this has even been called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
set_section (const char *arg, int *dumpSections)
|
||||||
|
{
|
||||||
|
/* if this is the first, clear all the bits */
|
||||||
|
if (*dumpSections == DUMP_UNSECTIONED)
|
||||||
|
*dumpSections = 0;
|
||||||
|
|
||||||
|
if (strcmp(arg,"pre-data") == 0)
|
||||||
|
*dumpSections |= DUMP_PRE_DATA;
|
||||||
|
else if (strcmp(arg,"data") == 0)
|
||||||
|
*dumpSections |= DUMP_DATA;
|
||||||
|
else if (strcmp(arg,"post-data") == 0)
|
||||||
|
*dumpSections |= DUMP_POST_DATA;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("%s: unknown section name \"%s\")\n"),
|
||||||
|
progname, arg);
|
||||||
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -58,5 +58,6 @@ extern void vwrite_msg(const char *modulename, const char *fmt, va_list ap)
|
|||||||
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
|
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
|
||||||
extern void exit_horribly(const char *modulename, const char *fmt,...)
|
extern void exit_horribly(const char *modulename, const char *fmt,...)
|
||||||
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
|
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
|
||||||
|
extern void set_section (const char *arg, int *dumpSections);
|
||||||
|
|
||||||
#endif /* DUMPUTILS_H */
|
#endif /* DUMPUTILS_H */
|
||||||
|
@ -69,6 +69,14 @@ typedef enum _teSection
|
|||||||
SECTION_POST_DATA /* stuff to be processed after data */
|
SECTION_POST_DATA /* stuff to be processed after data */
|
||||||
} teSection;
|
} teSection;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DUMP_PRE_DATA = 0x01,
|
||||||
|
DUMP_DATA = 0x02,
|
||||||
|
DUMP_POST_DATA = 0x04,
|
||||||
|
DUMP_UNSECTIONED = 0xff
|
||||||
|
} DumpSections;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We may want to have some more user-readable data, but in the mean
|
* We may want to have some more user-readable data, but in the mean
|
||||||
* time this gives us some abstraction and type checking.
|
* time this gives us some abstraction and type checking.
|
||||||
@ -111,6 +119,7 @@ typedef struct _restoreOptions
|
|||||||
int dropSchema;
|
int dropSchema;
|
||||||
char *filename;
|
char *filename;
|
||||||
int schemaOnly;
|
int schemaOnly;
|
||||||
|
int dumpSections;
|
||||||
int verbose;
|
int verbose;
|
||||||
int aclsSkip;
|
int aclsSkip;
|
||||||
int tocSummary;
|
int tocSummary;
|
||||||
|
@ -665,6 +665,7 @@ NewRestoreOptions(void)
|
|||||||
/* set any fields that shouldn't default to zeroes */
|
/* set any fields that shouldn't default to zeroes */
|
||||||
opts->format = archUnknown;
|
opts->format = archUnknown;
|
||||||
opts->promptPassword = TRI_DEFAULT;
|
opts->promptPassword = TRI_DEFAULT;
|
||||||
|
opts->dumpSections = DUMP_UNSECTIONED;
|
||||||
|
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
@ -2120,6 +2121,7 @@ ReadToc(ArchiveHandle *AH)
|
|||||||
int depIdx;
|
int depIdx;
|
||||||
int depSize;
|
int depSize;
|
||||||
TocEntry *te;
|
TocEntry *te;
|
||||||
|
bool in_post_data = false;
|
||||||
|
|
||||||
AH->tocCount = ReadInt(AH);
|
AH->tocCount = ReadInt(AH);
|
||||||
AH->maxDumpId = 0;
|
AH->maxDumpId = 0;
|
||||||
@ -2185,6 +2187,12 @@ ReadToc(ArchiveHandle *AH)
|
|||||||
te->section = SECTION_PRE_DATA;
|
te->section = SECTION_PRE_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* will stay true even for SECTION_NONE items */
|
||||||
|
if (te->section == SECTION_POST_DATA)
|
||||||
|
in_post_data = true;
|
||||||
|
|
||||||
|
te->inPostData = in_post_data;
|
||||||
|
|
||||||
te->defn = ReadStr(AH);
|
te->defn = ReadStr(AH);
|
||||||
te->dropStmt = ReadStr(AH);
|
te->dropStmt = ReadStr(AH);
|
||||||
|
|
||||||
@ -2334,6 +2342,17 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
|
|||||||
if (!ropt->createDB && strcmp(te->desc, "DATABASE") == 0)
|
if (!ropt->createDB && strcmp(te->desc, "DATABASE") == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* skip (all but) post data section as required */
|
||||||
|
/* table data is filtered if necessary lower down */
|
||||||
|
if (ropt->dumpSections != DUMP_UNSECTIONED)
|
||||||
|
{
|
||||||
|
if (!(ropt->dumpSections & DUMP_POST_DATA) && te->inPostData)
|
||||||
|
return 0;
|
||||||
|
if (!(ropt->dumpSections & DUMP_PRE_DATA) && ! te->inPostData && strcmp(te->desc, "TABLE DATA") != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check options for selective dump/restore */
|
/* Check options for selective dump/restore */
|
||||||
if (ropt->schemaNames)
|
if (ropt->schemaNames)
|
||||||
{
|
{
|
||||||
|
@ -287,6 +287,9 @@ typedef struct _tocEntry
|
|||||||
void *dataDumperArg; /* Arg for above routine */
|
void *dataDumperArg; /* Arg for above routine */
|
||||||
void *formatData; /* TOC Entry data specific to file format */
|
void *formatData; /* TOC Entry data specific to file format */
|
||||||
|
|
||||||
|
/* in post data? not quite the same as section, might be SECTION_NONE */
|
||||||
|
bool inPostData;
|
||||||
|
|
||||||
/* working state (needed only for parallel restore) */
|
/* working state (needed only for parallel restore) */
|
||||||
struct _tocEntry *par_prev; /* list links for pending/ready items; */
|
struct _tocEntry *par_prev; /* list links for pending/ready items; */
|
||||||
struct _tocEntry *par_next; /* these are NULL if not in either list */
|
struct _tocEntry *par_next; /* these are NULL if not in either list */
|
||||||
|
@ -91,6 +91,7 @@ PGconn *g_conn; /* the database connection */
|
|||||||
/* various user-settable parameters */
|
/* various user-settable parameters */
|
||||||
bool schemaOnly;
|
bool schemaOnly;
|
||||||
bool dataOnly;
|
bool dataOnly;
|
||||||
|
int dumpSections; /* bitmask of chosen sections */
|
||||||
bool aclsSkip;
|
bool aclsSkip;
|
||||||
const char *lockWaitTimeout;
|
const char *lockWaitTimeout;
|
||||||
|
|
||||||
@ -250,7 +251,6 @@ static void do_sql_command(PGconn *conn, const char *query);
|
|||||||
static void check_sql_result(PGresult *res, PGconn *conn, const char *query,
|
static void check_sql_result(PGresult *res, PGconn *conn, const char *query,
|
||||||
ExecStatusType expected);
|
ExecStatusType expected);
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -332,6 +332,7 @@ main(int argc, char **argv)
|
|||||||
{"no-tablespaces", no_argument, &outputNoTablespaces, 1},
|
{"no-tablespaces", no_argument, &outputNoTablespaces, 1},
|
||||||
{"quote-all-identifiers", no_argument, "e_all_identifiers, 1},
|
{"quote-all-identifiers", no_argument, "e_all_identifiers, 1},
|
||||||
{"role", required_argument, NULL, 3},
|
{"role", required_argument, NULL, 3},
|
||||||
|
{"section", required_argument, NULL, 5},
|
||||||
{"serializable-deferrable", no_argument, &serializable_deferrable, 1},
|
{"serializable-deferrable", no_argument, &serializable_deferrable, 1},
|
||||||
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
|
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
|
||||||
{"no-security-labels", no_argument, &no_security_labels, 1},
|
{"no-security-labels", no_argument, &no_security_labels, 1},
|
||||||
@ -349,6 +350,7 @@ main(int argc, char **argv)
|
|||||||
strcpy(g_opaque_type, "opaque");
|
strcpy(g_opaque_type, "opaque");
|
||||||
|
|
||||||
dataOnly = schemaOnly = false;
|
dataOnly = schemaOnly = false;
|
||||||
|
dumpSections = DUMP_UNSECTIONED;
|
||||||
lockWaitTimeout = NULL;
|
lockWaitTimeout = NULL;
|
||||||
|
|
||||||
progname = get_progname(argv[0]);
|
progname = get_progname(argv[0]);
|
||||||
@ -494,6 +496,10 @@ main(int argc, char **argv)
|
|||||||
simple_string_list_append(&tabledata_exclude_patterns, optarg);
|
simple_string_list_append(&tabledata_exclude_patterns, optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 5: /* section */
|
||||||
|
set_section(optarg, &dumpSections);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -524,6 +530,22 @@ main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((dataOnly || schemaOnly) && dumpSections != DUMP_UNSECTIONED)
|
||||||
|
{
|
||||||
|
write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used with --section\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataOnly)
|
||||||
|
dumpSections = DUMP_DATA;
|
||||||
|
else if (schemaOnly)
|
||||||
|
dumpSections = DUMP_PRE_DATA | DUMP_POST_DATA;
|
||||||
|
else if ( dumpSections != DUMP_UNSECTIONED)
|
||||||
|
{
|
||||||
|
dataOnly = dumpSections == DUMP_DATA;
|
||||||
|
schemaOnly = !(dumpSections & DUMP_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
if (dataOnly && outputClean)
|
if (dataOnly && outputClean)
|
||||||
{
|
{
|
||||||
write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
|
write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
|
||||||
@ -871,6 +893,7 @@ help(const char *progname)
|
|||||||
printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
|
printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
|
||||||
printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
|
printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
|
||||||
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(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
|
printf(_(" --serializable-deferrable wait until the dump can run without anomalies\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"
|
||||||
@ -7093,6 +7116,28 @@ collectComments(Archive *fout, CommentItem **items)
|
|||||||
static void
|
static void
|
||||||
dumpDumpableObject(Archive *fout, DumpableObject *dobj)
|
dumpDumpableObject(Archive *fout, DumpableObject *dobj)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool skip = false;
|
||||||
|
|
||||||
|
switch (dobj->objType)
|
||||||
|
{
|
||||||
|
case DO_INDEX:
|
||||||
|
case DO_TRIGGER:
|
||||||
|
case DO_CONSTRAINT:
|
||||||
|
case DO_FK_CONSTRAINT:
|
||||||
|
case DO_RULE:
|
||||||
|
skip = !(dumpSections & DUMP_POST_DATA);
|
||||||
|
break;
|
||||||
|
case DO_TABLE_DATA:
|
||||||
|
skip = !(dumpSections & DUMP_DATA);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
skip = !(dumpSections & DUMP_PRE_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (dobj->objType)
|
switch (dobj->objType)
|
||||||
{
|
{
|
||||||
case DO_NAMESPACE:
|
case DO_NAMESPACE:
|
||||||
|
@ -118,6 +118,7 @@ main(int argc, char **argv)
|
|||||||
{"no-data-for-failed-tables", no_argument, &no_data_for_failed_tables, 1},
|
{"no-data-for-failed-tables", no_argument, &no_data_for_failed_tables, 1},
|
||||||
{"no-tablespaces", no_argument, &outputNoTablespaces, 1},
|
{"no-tablespaces", no_argument, &outputNoTablespaces, 1},
|
||||||
{"role", required_argument, NULL, 2},
|
{"role", required_argument, NULL, 2},
|
||||||
|
{"section", required_argument, NULL, 3},
|
||||||
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
|
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
|
||||||
{"no-security-labels", no_argument, &no_security_labels, 1},
|
{"no-security-labels", no_argument, &no_security_labels, 1},
|
||||||
|
|
||||||
@ -272,6 +273,10 @@ main(int argc, char **argv)
|
|||||||
opts->use_role = optarg;
|
opts->use_role = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 3: /* section */
|
||||||
|
set_section(optarg, &(opts->dumpSections));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -294,6 +299,30 @@ main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts->dataOnly && opts->schemaOnly)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("%s: options -s/--schema-only and -a/--data-only cannot be used together\n"),
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((opts->dataOnly || opts->schemaOnly) && (opts->dumpSections != DUMP_UNSECTIONED))
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("%s: options -s/--schema-only and -a/--data-only cannot be used with --section\n"),
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts->dataOnly)
|
||||||
|
opts->dumpSections = DUMP_DATA;
|
||||||
|
else if (opts->schemaOnly)
|
||||||
|
opts->dumpSections = DUMP_PRE_DATA | DUMP_POST_DATA;
|
||||||
|
else if ( opts->dumpSections != DUMP_UNSECTIONED)
|
||||||
|
{
|
||||||
|
opts->dataOnly = opts->dumpSections == DUMP_DATA;
|
||||||
|
opts->schemaOnly = !(opts->dumpSections & DUMP_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
/* Should get at most one of -d and -f, else user is confused */
|
/* Should get at most one of -d and -f, else user is confused */
|
||||||
if (opts->dbname)
|
if (opts->dbname)
|
||||||
{
|
{
|
||||||
@ -434,6 +463,7 @@ usage(const char *progname)
|
|||||||
" created\n"));
|
" created\n"));
|
||||||
printf(_(" --no-security-labels do not restore security labels\n"));
|
printf(_(" --no-security-labels do not restore security labels\n"));
|
||||||
printf(_(" --no-tablespaces do not restore tablespace assignments\n"));
|
printf(_(" --no-tablespaces do not restore tablespace assignments\n"));
|
||||||
|
printf(_(" --section=SECTION restore named section (pre-data, data or post-data)\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"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user