Skip to content

Commit f092de0

Browse files
committed
Add --exclude-database option to pg_dumpall
This option functions similarly to pg_dump's --exclude-table option, but for database names. The option can be given once, and the argument can be a pattern including wildcard characters. Author: Andrew Dunstan. Reviewd-by: Fabien Coelho and Michael Paquier Discussion: https://postgr.es/m/43a54a47-4aa7-c70e-9ca6-648f436dd6e6@2ndQuadrant.com
1 parent 9c32e4c commit f092de0

File tree

5 files changed

+124
-2
lines changed

5 files changed

+124
-2
lines changed

doc/src/sgml/ref/pg_dumpall.sgml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,27 @@ PostgreSQL documentation
311311
</listitem>
312312
</varlistentry>
313313

314+
315+
<varlistentry>
316+
<term><option>--exclude-database=<replaceable class="parameter">pattern</replaceable></option></term>
317+
<listitem>
318+
<para>
319+
Do not dump databases whose name matches
320+
<replaceable class="parameter">pattern</replaceable>.
321+
Multiple patterns can be excluded by writing multiple
322+
<option>--exclude-database</option> switches. The
323+
<replaceable class="parameter">pattern</replaceable> parameter is
324+
interpreted as a pattern according to the same rules used by
325+
<application>psql</application>'s <literal>\d</literal>
326+
commands (see <xref
327+
linkend="app-psql-patterns" endterm="app-psql-patterns-title"/>),
328+
so multiple databases can also be excluded by writing wildcard
329+
characters in the pattern. When using wildcards, be careful to
330+
quote the pattern if needed to prevent shell wildcard expansion.
331+
</para>
332+
</listitem>
333+
</varlistentry>
334+
314335
<varlistentry>
315336
<term><option>--if-exists</option></term>
316337
<listitem>

src/bin/pg_dump/pg_dump.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,8 @@ expand_schema_name_patterns(Archive *fout,
13011301

13021302
/*
13031303
* Find the OIDs of all tables matching the given list of patterns,
1304-
* and append them to the given OID list.
1304+
* and append them to the given OID list. See also expand_dbname_patterns()
1305+
* in pg_dumpall.c
13051306
*/
13061307
static void
13071308
expand_table_name_patterns(Archive *fout,

src/bin/pg_dump/pg_dumpall.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ static PGconn *connectDatabase(const char *dbname, const char *connstr, const ch
5252
static char *constructConnStr(const char **keywords, const char **values);
5353
static PGresult *executeQuery(PGconn *conn, const char *query);
5454
static void executeCommand(PGconn *conn, const char *query);
55+
static void expand_dbname_patterns(PGconn *conn, SimpleStringList *patterns,
56+
SimpleStringList *names);
5557

5658
static char pg_dump_bin[MAXPGPATH];
5759
static const char *progname;
@@ -87,6 +89,9 @@ static char role_catalog[10];
8789
static FILE *OPF;
8890
static char *filename = NULL;
8991

92+
static SimpleStringList database_exclude_patterns = {NULL, NULL};
93+
static SimpleStringList database_exclude_names = {NULL, NULL};
94+
9095
#define exit_nicely(code) exit(code)
9196

9297
int
@@ -123,6 +128,7 @@ main(int argc, char *argv[])
123128
{"column-inserts", no_argument, &column_inserts, 1},
124129
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
125130
{"disable-triggers", no_argument, &disable_triggers, 1},
131+
{"exclude-database", required_argument, NULL, 6},
126132
{"extra-float-digits", required_argument, NULL, 5},
127133
{"if-exists", no_argument, &if_exists, 1},
128134
{"inserts", no_argument, &inserts, 1},
@@ -324,6 +330,10 @@ main(int argc, char *argv[])
324330
appendShellString(pgdumpopts, optarg);
325331
break;
326332

333+
case 6:
334+
simple_string_list_append(&database_exclude_patterns, optarg);
335+
break;
336+
327337
default:
328338
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
329339
exit_nicely(1);
@@ -340,6 +350,16 @@ main(int argc, char *argv[])
340350
exit_nicely(1);
341351
}
342352

353+
if (database_exclude_patterns.head != NULL &&
354+
(globals_only || roles_only || tablespaces_only))
355+
{
356+
fprintf(stderr, _("%s: option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only or -t/--tablespaces-only\n"),
357+
progname);
358+
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
359+
progname);
360+
exit_nicely(1);
361+
}
362+
343363
/* Make sure the user hasn't specified a mix of globals-only options */
344364
if (globals_only && roles_only)
345365
{
@@ -454,6 +474,12 @@ main(int argc, char *argv[])
454474
}
455475
}
456476

477+
/*
478+
* Get a list of database names that match the exclude patterns
479+
*/
480+
expand_dbname_patterns(conn, &database_exclude_patterns,
481+
&database_exclude_names);
482+
457483
/*
458484
* Open the output file if required, otherwise use stdout
459485
*/
@@ -620,6 +646,7 @@ help(void)
620646
printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
621647
printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
622648
printf(_(" --disable-triggers disable triggers during data-only restore\n"));
649+
printf(_(" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n"));
623650
printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
624651
printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
625652
printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
@@ -1358,6 +1385,48 @@ dumpUserConfig(PGconn *conn, const char *username)
13581385
destroyPQExpBuffer(buf);
13591386
}
13601387

1388+
/*
1389+
* Find a list of database names that match the given patterns.
1390+
* See also expand_table_name_patterns() in pg_dump.c
1391+
*/
1392+
static void
1393+
expand_dbname_patterns(PGconn *conn,
1394+
SimpleStringList *patterns,
1395+
SimpleStringList *names)
1396+
{
1397+
PQExpBuffer query;
1398+
PGresult *res;
1399+
1400+
if (patterns->head == NULL)
1401+
return; /* nothing to do */
1402+
1403+
query = createPQExpBuffer();
1404+
1405+
/*
1406+
* The loop below runs multiple SELECTs, which might sometimes result in
1407+
* duplicate entries in the name list, but we don't care, since all
1408+
* we're going to do is test membership of the list.
1409+
*/
1410+
1411+
for (SimpleStringListCell *cell = patterns->head; cell; cell = cell->next)
1412+
{
1413+
appendPQExpBuffer(query,
1414+
"SELECT datname FROM pg_catalog.pg_database n\n");
1415+
processSQLNamePattern(conn, query, cell->val, false,
1416+
false, NULL, "datname", NULL, NULL);
1417+
1418+
res = executeQuery(conn, query->data);
1419+
for (int i = 0; i < PQntuples(res); i++)
1420+
{
1421+
simple_string_list_append(names, PQgetvalue(res, i, 0));
1422+
}
1423+
1424+
PQclear(res);
1425+
resetPQExpBuffer(query);
1426+
}
1427+
1428+
destroyPQExpBuffer(query);
1429+
}
13611430

13621431
/*
13631432
* Dump contents of databases.
@@ -1395,6 +1464,15 @@ dumpDatabases(PGconn *conn)
13951464
if (strcmp(dbname, "template0") == 0)
13961465
continue;
13971466

1467+
/* Skip any explicitly excluded database */
1468+
if (simple_string_list_member(&database_exclude_names, dbname))
1469+
{
1470+
if (verbose)
1471+
fprintf(stderr, _("%s: excluding database \"%s\"...\n"),
1472+
progname, dbname);
1473+
continue;
1474+
}
1475+
13981476
if (verbose)
13991477
fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);
14001478

src/bin/pg_dump/t/001_basic.pl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use Config;
55
use PostgresNode;
66
use TestLib;
7-
use Test::More tests => 70;
7+
use Test::More tests => 74;
88

99
my $tempdir = TestLib::tempdir;
1010
my $tempdir_short = TestLib::tempdir_short;
@@ -150,3 +150,14 @@
150150
qr/\Qpg_restore: options -C\/--create and -1\/--single-transaction cannot be used together\E/,
151151
'pg_restore: options -C\/--create and -1\/--single-transaction cannot be used together'
152152
);
153+
154+
command_fails_like(
155+
[ 'pg_dumpall', '--exclude-database' ],
156+
qr/\Qpg_dumpall: option '--exclude-database' requires an argument\E/,
157+
'pg_dumpall: option --exclude-database requires an argument');
158+
159+
# also fails for -r and -t, but it seems pointless to add more tests for those.
160+
command_fails_like(
161+
[ 'pg_dumpall', '--exclude-database=foo', '--globals-only' ],
162+
qr/\Qpg_dumpall: option --exclude-database cannot be used together with -g\/--globals-only\E/,
163+
'pg_dumpall: option --exclude-database cannot be used together with -g/--globals-only');

src/bin/pg_dump/t/002_pg_dump.pl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,12 @@
224224
"--file=$tempdir/pg_dumpall_dbprivs.sql",
225225
],
226226
},
227+
pg_dumpall_exclude => {
228+
dump_cmd => [
229+
'pg_dumpall', '-v', "--file=$tempdir/pg_dumpall_exclude.sql",
230+
'--exclude-database', '*dump*', '--no-sync',
231+
],
232+
},
227233
no_blobs => {
228234
dump_cmd => [
229235
'pg_dump', '--no-sync',
@@ -380,6 +386,7 @@
380386
no_owner => 1,
381387
no_privs => 1,
382388
pg_dumpall_dbprivs => 1,
389+
pg_dumpall_exclude => 1,
383390
schema_only => 1,);
384391

385392
# This is where the actual tests are defined.
@@ -444,6 +451,7 @@
444451
pg_dumpall_dbprivs => 1,
445452
pg_dumpall_globals => 1,
446453
pg_dumpall_globals_clean => 1,
454+
pg_dumpall_exclude => 1,
447455
},
448456
},
449457

@@ -1318,6 +1326,7 @@
13181326
regexp => qr/^CREATE ROLE regress_dump_test_role;/m,
13191327
like => {
13201328
pg_dumpall_dbprivs => 1,
1329+
pg_dumpall_exclude => 1,
13211330
pg_dumpall_globals => 1,
13221331
pg_dumpall_globals_clean => 1,
13231332
},
@@ -2442,6 +2451,7 @@
24422451
no_owner => 1,
24432452
only_dump_test_schema => 1,
24442453
pg_dumpall_dbprivs => 1,
2454+
pg_dumpall_exclude => 1,
24452455
schema_only => 1,
24462456
section_post_data => 1,
24472457
test_schema_plus_blobs => 1,
@@ -2512,6 +2522,7 @@
25122522
no_privs => 1,
25132523
no_owner => 1,
25142524
pg_dumpall_dbprivs => 1,
2525+
pg_dumpall_exclude => 1,
25152526
role => 1,
25162527
schema_only => 1,
25172528
section_post_data => 1,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy