pg_restore: add --no-globals option to skip globals

This is a followup to commit 763aaa06f0 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
This commit is contained in:
Andrew Dunstan 2026-02-27 08:07:10 -05:00
parent c7572cd48d
commit 3c19983cc0
4 changed files with 75 additions and 10 deletions

View 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>

View 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;

View 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();

View 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);');