On Thu, 2025-03-06 at 11:15 -0500, Robert Haas wrote: > To be honest, I am a bit surprised that we decided to enable this by > default. It's not obvious to me that statistics should be regarded as > part of the database in the same way that table definitions or table > data are. That said, I'm not overwhelmingly opposed to that choice. > However, even if it's the right choice in theory, we should maybe > rethink if it's going to be too slow or use too much memory.
I don't have a strong opinion about whether stats will be opt-out or opt-in for v18, but if they are opt-in, we would need to adjust the available options a bit. At minimum, we would need to at least add the option "--with- statistics", because right now the only way to explicitly request stats is to say "--statistics-only". To generalize this concept: for each of {schema, data, stats} users might want "yes", "no", or "only". If we use this options scheme, it would be easy to change the default for stats independently of the other options, if necessary, without surprising consequences. Patch attached. This patch does NOT change the default; stats are still opt-out. But it makes it easier for users to start specifying what they want or not explicitly, or to rely on the defaults if they prefer. Note that the patch would mean we go from 2 options in v17: --{schema|data}-only to 9 options in v18: --{with|no}-{schema|data|stats} and --{schema|data|stats}-only I suggest we adjust the options now with something resembling the attached patch and decide on changing the default sometime during beta. Regards, Jeff Davis
From c47fc9e570ddd083097f4bfc708465cf644f48c2 Mon Sep 17 00:00:00 2001 From: Jeff Davis <j...@j-davis.com> Date: Thu, 6 Mar 2025 17:35:41 -0800 Subject: [PATCH v1] Add pg_dump --with-X options. --- doc/src/sgml/ref/pg_dump.sgml | 27 +++++++++++++++++++ doc/src/sgml/ref/pg_dumpall.sgml | 27 +++++++++++++++++++ doc/src/sgml/ref/pg_restore.sgml | 27 +++++++++++++++++++ src/bin/pg_dump/pg_dump.c | 46 +++++++++++++++++++++++++++++--- src/bin/pg_dump/pg_dumpall.c | 12 +++++++++ src/bin/pg_dump/pg_restore.c | 44 +++++++++++++++++++++++++----- 6 files changed, 173 insertions(+), 10 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 1975054d7bf..9eba285687e 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -1223,6 +1223,33 @@ PostgreSQL documentation </listitem> </varlistentry> + <varlistentry> + <term><option>--with-data</option></term> + <listitem> + <para> + Dump data. This is the default. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>--with-schema</option></term> + <listitem> + <para> + Dump schema (data definitions). This is the default. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>--with-statistics</option></term> + <listitem> + <para> + Dump statistics. This is the default. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><option>--on-conflict-do-nothing</option></term> <listitem> diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml index c2fa5be9519..45f127f0dc9 100644 --- a/doc/src/sgml/ref/pg_dumpall.sgml +++ b/doc/src/sgml/ref/pg_dumpall.sgml @@ -551,6 +551,33 @@ exclude database <replaceable class="parameter">PATTERN</replaceable> </listitem> </varlistentry> + <varlistentry> + <term><option>--with-data</option></term> + <listitem> + <para> + Dump data. This is the default. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>--with-schema</option></term> + <listitem> + <para> + Dump schema (data definitions). This is the default. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>--with-statistics</option></term> + <listitem> + <para> + Dump statistics. This is the default. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><option>--no-unlogged-table-data</option></term> <listitem> diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index 199ea3345f3..51e6411c8fe 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -795,6 +795,33 @@ PostgreSQL documentation </listitem> </varlistentry> + <varlistentry> + <term><option>--with-data</option></term> + <listitem> + <para> + Dump data. This is the default. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>--with-schema</option></term> + <listitem> + <para> + Dump schema (data definitions). This is the default. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>--with-statistics</option></term> + <listitem> + <para> + Dump statistics. This is the default. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><option>--section=<replaceable class="parameter">sectionname</replaceable></option></term> <listitem> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 4f4ad2ee150..31c4ac1ee57 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -433,6 +433,9 @@ main(int argc, char **argv) bool data_only = false; bool schema_only = false; bool statistics_only = false; + bool with_data = false; + bool with_schema = false; + bool with_statistics = false; bool no_data = false; bool no_schema = false; bool no_statistics = false; @@ -508,6 +511,9 @@ main(int argc, char **argv) {"no-toast-compression", no_argument, &dopt.no_toast_compression, 1}, {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1}, {"no-sync", no_argument, NULL, 7}, + {"with-data", no_argument, NULL, 22}, + {"with-schema", no_argument, NULL, 23}, + {"with-statistics", no_argument, NULL, 24}, {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1}, {"rows-per-insert", required_argument, NULL, 10}, {"include-foreign-data", required_argument, NULL, 11}, @@ -776,6 +782,18 @@ main(int argc, char **argv) no_statistics = true; break; + case 22: + with_data = true; + break; + + case 23: + with_schema = true; + break; + + case 24: + with_statistics = true; + break; + default: /* getopt_long already emitted a complaint */ pg_log_error_hint("Try \"%s --help\" for more information.", progname); @@ -811,6 +829,7 @@ main(int argc, char **argv) if (dopt.binary_upgrade) dopt.sequence_data = 1; + /* reject conflicting "-only" options */ if (data_only && schema_only) pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together"); if (schema_only && statistics_only) @@ -818,6 +837,7 @@ main(int argc, char **argv) if (data_only && statistics_only) pg_fatal("options -a/--data-only and --statistics-only cannot be used together"); + /* reject conflicting "-only" and "no-" options */ if (data_only && no_data) pg_fatal("options -a/--data-only and --no-data cannot be used together"); if (schema_only && no_schema) @@ -825,6 +845,14 @@ main(int argc, char **argv) if (statistics_only && no_statistics) pg_fatal("options --statistics-only and --no-statistics cannot be used together"); + /* reject conflicting "with-" and "no-" options */ + if (with_data && no_data) + pg_fatal("options --with-data and --no-data cannot be used together"); + if (with_schema && no_schema) + pg_fatal("options --with-schema and --no-schema cannot be used together"); + if (with_statistics && no_statistics) + pg_fatal("options --with-statistics and --no-statistics cannot be used together"); + if (schema_only && foreign_servers_include_patterns.head != NULL) pg_fatal("options -s/--schema-only and --include-foreign-data cannot be used together"); @@ -837,10 +865,20 @@ main(int argc, char **argv) if (dopt.if_exists && !dopt.outputClean) pg_fatal("option --if-exists requires option -c/--clean"); - /* set derivative flags */ - dopt.dumpData = data_only || (!schema_only && !statistics_only && !no_data); - dopt.dumpSchema = schema_only || (!data_only && !statistics_only && !no_schema); - dopt.dumpStatistics = statistics_only || (!data_only && !schema_only && !no_statistics); + /* + * Set derivative flags. An "-only" option may be overridden by an + * explicit "with-" option; e.g. "--schema-only --with-statistics" will + * include schema and statistics. Other ambiguous or nonsensical + * combinations, e.g. "--schema-only --no-schema", will have already + * caused an error in one of the checks above. + */ + dopt.dumpData = ((dopt.dumpData && !schema_only && !statistics_only) || + (data_only || with_data)) && !no_data; + dopt.dumpSchema = ((dopt.dumpSchema && !data_only && !statistics_only) || + (schema_only || with_schema)) && !no_schema; + dopt.dumpStatistics = ((dopt.dumpStatistics && !schema_only && !data_only) || + (statistics_only || with_statistics)) && !no_statistics; + /* * --inserts are already implied above if --column-inserts or diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index e0867242526..a7e8c0d2ad5 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -110,6 +110,9 @@ static int no_subscriptions = 0; static int no_toast_compression = 0; static int no_unlogged_table_data = 0; static int no_role_passwords = 0; +static int with_data = 0; +static int with_schema = 0; +static int with_statistics = 0; static int server_version; static int load_via_partition_root = 0; static int on_conflict_do_nothing = 0; @@ -182,6 +185,9 @@ main(int argc, char *argv[]) {"no-sync", no_argument, NULL, 4}, {"no-toast-compression", no_argument, &no_toast_compression, 1}, {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1}, + {"with-data", no_argument, &with_data, 1}, + {"with-schema", no_argument, &with_schema, 1}, + {"with-statistics", no_argument, &with_statistics, 1}, {"on-conflict-do-nothing", no_argument, &on_conflict_do_nothing, 1}, {"rows-per-insert", required_argument, NULL, 7}, {"statistics-only", no_argument, &statistics_only, 1}, @@ -471,6 +477,12 @@ main(int argc, char *argv[]) appendPQExpBufferStr(pgdumpopts, " --no-toast-compression"); if (no_unlogged_table_data) appendPQExpBufferStr(pgdumpopts, " --no-unlogged-table-data"); + if (with_data) + appendPQExpBufferStr(pgdumpopts, " --with-data"); + if (with_schema) + appendPQExpBufferStr(pgdumpopts, " --with-schema"); + if (with_statistics) + appendPQExpBufferStr(pgdumpopts, " --with-statistics"); if (on_conflict_do_nothing) appendPQExpBufferStr(pgdumpopts, " --on-conflict-do-nothing"); if (statistics_only) diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 13e4dc507e0..f22046127b7 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -81,6 +81,9 @@ main(int argc, char **argv) static int no_subscriptions = 0; static int strict_names = 0; static int statistics_only = 0; + static int with_data = 0; + static int with_schema = 0; + static int with_statistics = 0; struct option cmdopts[] = { {"clean", 0, NULL, 'c'}, @@ -134,6 +137,9 @@ main(int argc, char **argv) {"no-security-labels", no_argument, &no_security_labels, 1}, {"no-subscriptions", no_argument, &no_subscriptions, 1}, {"no-statistics", no_argument, &no_statistics, 1}, + {"with-data", no_argument, &with_data, 1}, + {"with-schema", no_argument, &with_schema, 1}, + {"with-statistics", no_argument, &with_statistics, 1}, {"statistics-only", no_argument, &statistics_only, 1}, {"filter", required_argument, NULL, 4}, @@ -349,12 +355,29 @@ main(int argc, char **argv) opts->useDB = 1; } + /* reject conflicting "-only" options */ if (data_only && schema_only) pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together"); - if (data_only && statistics_only) - pg_fatal("options -a/--data-only and --statistics-only cannot be used together"); if (schema_only && statistics_only) pg_fatal("options -s/--schema-only and --statistics-only cannot be used together"); + if (data_only && statistics_only) + pg_fatal("options -a/--data-only and --statistics-only cannot be used together"); + + /* reject conflicting "-only" and "no-" options */ + if (data_only && no_data) + pg_fatal("options -a/--data-only and --no-data cannot be used together"); + if (schema_only && no_schema) + pg_fatal("options -s/--schema-only and --no-schema cannot be used together"); + if (statistics_only && no_statistics) + pg_fatal("options --statistics-only and --no-statistics cannot be used together"); + + /* reject conflicting "with-" and "no-" options */ + if (with_data && no_data) + pg_fatal("options --with-data and --no-data cannot be used together"); + if (with_schema && no_schema) + pg_fatal("options --with-schema and --no-schema cannot be used together"); + if (with_statistics && no_statistics) + pg_fatal("options --with-statistics and --no-statistics cannot be used together"); if (data_only && opts->dropSchema) pg_fatal("options -c/--clean and -a/--data-only cannot be used together"); @@ -373,10 +396,19 @@ main(int argc, char **argv) if (opts->single_txn && numWorkers > 1) pg_fatal("cannot specify both --single-transaction and multiple jobs"); - /* set derivative flags */ - opts->dumpData = data_only || (!no_data && !schema_only && !statistics_only); - opts->dumpSchema = schema_only || (!no_schema && !data_only && !statistics_only); - opts->dumpStatistics = statistics_only || (!no_statistics && !data_only && !schema_only); + /* + * Set derivative flags. An "-only" option may be overridden by an + * explicit "with-" option; e.g. "--schema-only --with-statistics" will + * include schema and statistics. Other ambiguous or nonsensical + * combinations, e.g. "--schema-only --no-schema", will have already + * caused an error in one of the checks above. + */ + opts->dumpData = ((opts->dumpData && !schema_only && !statistics_only) || + (data_only || with_data)) && !no_data; + opts->dumpSchema = ((opts->dumpSchema && !data_only && !statistics_only) || + (schema_only || with_schema)) && !no_schema; + opts->dumpStatistics = ((opts->dumpStatistics && !schema_only && !data_only) || + (statistics_only || with_statistics)) && !no_statistics; opts->disable_triggers = disable_triggers; opts->enable_row_security = enable_row_security; -- 2.34.1