From: Andrew Dunstan Date: Fri, 27 Feb 2026 13:07:10 +0000 (-0500) Subject: pg_restore: add --no-globals option to skip globals X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c19983cc0816001ad849a9f0bcaf2ea8321b93d;p=thirdparty%2Fpostgresql.git pg_restore: add --no-globals option to skip globals 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 With small tweaks by me. Discussion: https://postgr.es/m/CAKYtNArdcc5kx1MdTtTKFNYiauo3=zCA-NB0LmBCW-RU_kSb3A@mail.gmail.com --- diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index 4a21a089840..c7ed947968c 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -294,7 +294,23 @@ PostgreSQL documentation , , , or - . + , + . + + + + + + + + + Do not restore global objects (roles and tablespaces). When + / is not specified, + databases that do not already exist on the target server are skipped. + + + This option is only relevant when restoring from a non-plain-text + archive made using pg_dumpall. diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index f85cab4dc8e..752d859e264 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -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; diff --git a/src/bin/pg_dump/t/001_basic.pl b/src/bin/pg_dump/t/001_basic.pl index a895bc314b0..930ef4915c5 100644 --- a/src/bin/pg_dump/t/001_basic.pl +++ b/src/bin/pg_dump/t/001_basic.pl @@ -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(); diff --git a/src/bin/pg_dump/t/007_pg_dumpall.pl b/src/bin/pg_dump/t/007_pg_dumpall.pl index 04eba494b4e..c16c27d7387 100644 --- a/src/bin/pg_dump/t/007_pg_dumpall.pl +++ b/src/bin/pg_dump/t/007_pg_dumpall.pl @@ -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);');