]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
pg_restore: add --no-globals option to skip globals
authorAndrew Dunstan <andrew@dunslane.net>
Fri, 27 Feb 2026 13:07:10 +0000 (08:07 -0500)
committerAndrew Dunstan <andrew@dunslane.net>
Wed, 4 Mar 2026 21:53:29 +0000 (16:53 -0500)
This is a followup to commit 763aaa06f03 Add non-text output formats to
pg_dumpall.

Add a --no-globals option to pg_restore that skips restoring global
objects (roles and tablespaces) when restoring from a pg_dumpall
archive.  When -C/--create is not specified, databases that do not
already exist on the target server are also skipped.

This is useful when restoring only specific databases from a pg_dumpall
archive without needing the global objects to be restored first.

Author: Mahendra Singh Thalor <mahi6run@gmail.com>

With small tweaks by me.

Discussion: https://postgr.es/m/CAKYtNArdcc5kx1MdTtTKFNYiauo3=zCA-NB0LmBCW-RU_kSb3A@mail.gmail.com

doc/src/sgml/ref/pg_restore.sgml
src/bin/pg_dump/pg_restore.c
src/bin/pg_dump/t/001_basic.pl
src/bin/pg_dump/t/007_pg_dumpall.pl

index 4a21a08984092fe39e969ab0f4a2a024582bc006..c7ed947968c0a8d981253b8b3926e22cbc9be9eb 100644 (file)
@@ -294,7 +294,23 @@ PostgreSQL documentation
         <option>--exit-on-error</option>,
         <option>--single-transaction</option>,
         <option>--clean</option>, or
-        <option>--transaction-size</option>.
+        <option>--transaction-size</option>,
+        <option>--no-globals</option>.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><option>--no-globals</option></term>
+      <listitem>
+       <para>
+        Do not restore global objects (roles and tablespaces).  When
+        <option>-C</option>/<option>--create</option> is not specified,
+        databases that do not already exist on the target server are skipped.
+       </para>
+       <para>
+        This option is only relevant when restoring from a non-plain-text
+        archive made using <application>pg_dumpall</application>.
        </para>
       </listitem>
      </varlistentry>
index f85cab4dc8e76a20667149d9a23cd9487bb9209e..752d859e264b854b779e542ab4626a685b2c78c7 100644 (file)
@@ -107,6 +107,7 @@ main(int argc, char **argv)
        static int      no_schema = 0;
        static int      no_security_labels = 0;
        static int      no_statistics = 0;
+       static int      no_globals = 0;
        static int      no_subscriptions = 0;
        static int      strict_names = 0;
        static int      statistics_only = 0;
@@ -164,6 +165,7 @@ main(int argc, char **argv)
                {"no-publications", no_argument, &no_publications, 1},
                {"no-schema", no_argument, &no_schema, 1},
                {"no-security-labels", no_argument, &no_security_labels, 1},
+               {"no-globals", no_argument, &no_globals, 1},
                {"no-subscriptions", no_argument, &no_subscriptions, 1},
                {"no-statistics", no_argument, &no_statistics, 1},
                {"statistics", no_argument, &with_statistics, 1},
@@ -489,6 +491,10 @@ main(int argc, char **argv)
                pg_fatal("options %s and %s cannot be used together",
                                 "--statistics", "-g/--globals-only");
 
+       if (no_globals && globals_only)
+               pg_fatal("options %s and %s cannot be used together",
+                                "--no-globals", "-g/--globals-only");
+
        /*
         * -C is not compatible with -1, because we can't create a database inside
         * a transaction block.
@@ -614,9 +620,10 @@ main(int argc, char **argv)
 
                /*
                 * To restore from a pg_dumpall archive, -C (create database) option
-                * must be specified unless we are only restoring globals.
+                * must be specified unless we are only restoring globals or we are
+                * skipping globals.
                 */
-               if (!globals_only && opts->createDB != 1)
+               if (!no_globals && !globals_only && opts->createDB != 1)
                {
                        pg_log_error("option %s must be specified when restoring an archive created by pg_dumpall",
                                                 "-C/--create");
@@ -626,13 +633,16 @@ main(int argc, char **argv)
                }
 
                /*
-                * Always restore global objects, even if --exclude-database results
-                * in zero databases to process. If 'globals-only' is set, exit
-                * immediately.
+                * Restore global objects, even if --exclude-database results in zero
+                * databases to process. If 'globals-only' is set, exit immediately.
                 */
                snprintf(global_path, MAXPGPATH, "%s/toc.glo", inputFileSpec);
 
-               n_errors = restore_global_objects(global_path, tmpopts);
+               if (!no_globals)
+                       n_errors = restore_global_objects(global_path, tmpopts);
+               else
+                       pg_log_info("skipping restore of global objects because %s was specified",
+                                               "--no-globals");
 
                if (globals_only)
                        pg_log_info("database restoring skipped because option %s was specified",
@@ -829,6 +839,7 @@ usage(const char *progname)
        printf(_("  --no-security-labels         do not restore security labels\n"));
        printf(_("  --no-statistics              do not restore statistics\n"));
        printf(_("  --no-subscriptions           do not restore subscriptions\n"));
+       printf(_("  --no-globals                 do not restore global objects (roles and tablespaces)\n"));
        printf(_("  --no-table-access-method     do not restore table access methods\n"));
        printf(_("  --no-tablespaces             do not restore tablespace assignments\n"));
        printf(_("  --restrict-key=RESTRICT_KEY  use provided string as psql \\restrict key\n"));
@@ -1349,6 +1360,13 @@ restore_all_databases(const char *inputFileSpec,
                        }
                        else
                        {
+                               if (!tmpopts->createDB)
+                               {
+                                       pg_log_info("skipping restore of database \"%s\": database does not exist and %s was not specified",
+                                                               dbidname->str, "-C/--create");
+                                       continue;
+                               }
+
                                /* We'll have to create it */
                                tmpopts->createDB = 1;
                                tmpopts->cparams.dbname = connected_db;
index a895bc314b0044bc090e6e55d1625cc49895b747..930ef4915c5280f3de2f7752bf9d80fb93a32716 100644 (file)
@@ -255,9 +255,13 @@ command_fails_like(
        'pg_dumpall: --restrict-key can only be used with plain dump format');
 
 command_fails_like(
-       [ 'pg_dumpall', '--format', 'd', '--globals-only', '--clean', '-f', 'dumpfile' ],
+       [
+               'pg_dumpall', '--format', 'd', '--globals-only',
+               '--clean', '-f', 'dumpfile'
+       ],
        qr/\Qpg_dumpall: error: options --clean and -g\/--globals-only cannot be used together in non-text dump\E/,
-       'pg_dumpall: --clean and -g/--globals-only cannot be used together in non-text dump');
+       'pg_dumpall: --clean and -g/--globals-only cannot be used together in non-text dump'
+);
 
 command_fails_like(
        [ 'pg_dumpall', '--format', 'd' ],
@@ -299,4 +303,12 @@ command_fails_like(
        qr/\Qpg_restore: error: option -g\/--globals-only can be used only when restoring an archive created by pg_dumpall\E/,
        'When option --globals-only is used in pg_restore with the dump of pg_dump'
 );
+
+command_fails_like(
+       [
+               'pg_restore', '--globals-only', '--no-globals', '-d', 'xxx',
+               'dumpdir'
+       ],
+       qr/\Qpg_restore: error: options --no-globals and -g\/--globals-only cannot be used together\E/,
+       'options --no-globals and --globals-only cannot be used together');
 done_testing();
index 04eba494b4e07dc9a041d09ec2d127c4ee11204f..c16c27d7387c2030a4ae3cd304ad6c918d52245e 100644 (file)
@@ -299,6 +299,24 @@ my %pgdumpall_runs = (
                like => qr/
             ^\s*\QCREATE ROLE dumpall;\E\s*\n
                        /xm
+       },
+
+       restore_no_globals => {
+               setup_sql => "CREATE TABLE no_globals_test(a int, b text);
+               INSERT INTO no_globals_test VALUES (1, 'hello'), (2, 'world');",
+               dump_cmd => [
+                       'pg_dumpall',
+                       '--format' => 'directory',
+                       '--file' => "$tempdir/restore_no_globals",
+               ],
+               restore_cmd => [
+                       'pg_restore', '-C', '--no-globals',
+                       '--format' => 'directory',
+                       '--file' => "$tempdir/restore_no_globals.sql",
+                       "$tempdir/restore_no_globals",
+               ],
+               like => qr/^\n\QCOPY public.no_globals_test (a, b) FROM stdin;\E/xm,
+               unlike => qr/^\QCREATE ROLE dumpall;\E/xm,
        },);
 
 # First execute the setup_sql
@@ -578,7 +596,8 @@ like(
        'map.dat contains expected preamble');
 
 # verify commenting out a line in map.dat skips that database
-$node->safe_psql($run_db, 'CREATE DATABASE comment_test_db;
+$node->safe_psql(
+       $run_db, 'CREATE DATABASE comment_test_db;
 \c comment_test_db
 CREATE TABLE comment_test_table (id int);');