PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pg_dumpall.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * pg_dumpall.c
4 * pg_dumpall dumps all databases and global objects (roles and
5 * tablespaces) from a PostgreSQL cluster.
6 *
7 * For text format output, globals are written directly and pg_dump is
8 * invoked for each database, with all output going to stdout or a file.
9 *
10 * For non-text formats (custom, directory, tar), a directory is created
11 * containing a toc.glo file with global objects, a map.dat file mapping
12 * database OIDs to names, and a databases/ subdirectory with individual
13 * pg_dump archives for each database.
14 *
15 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
16 * Portions Copyright (c) 1994, Regents of the University of California
17 *
18 * src/bin/pg_dump/pg_dumpall.c
19 *
20 *-------------------------------------------------------------------------
21 */
22
23#include "postgres_fe.h"
24
25#include <time.h>
26#include <unistd.h>
27
28#include "catalog/pg_authid_d.h"
29#include "common/connect.h"
30#include "common/file_perm.h"
31#include "common/file_utils.h"
33#include "common/logging.h"
34#include "common/string.h"
35#include "connectdb.h"
36#include "dumputils.h"
39#include "filter.h"
40#include "getopt_long.h"
41#include "pg_backup_archiver.h"
42
43/* version string we expect back from pg_dump */
44#define PGDUMP_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
45
46typedef struct
47{
50 char *rolename;
52
53#define SH_PREFIX rolename
54#define SH_ELEMENT_TYPE RoleNameEntry
55#define SH_KEY_TYPE char *
56#define SH_KEY rolename
57#define SH_HASH_KEY(tb, key) hash_string(key)
58#define SH_EQUAL(tb, a, b) (strcmp(a, b) == 0)
59#define SH_STORE_HASH
60#define SH_GET_HASH(tb, a) (a)->hashval
61#define SH_SCOPE static inline
62#define SH_RAW_ALLOCATOR pg_malloc0
63#define SH_DECLARE
64#define SH_DEFINE
65#include "lib/simplehash.h"
66
67static void help(void);
68
69static void dropRoles(PGconn *conn);
70static void dumpRoles(PGconn *conn);
71static void dumpRoleMembership(PGconn *conn);
72static void dumpRoleGUCPrivs(PGconn *conn);
73static void dropTablespaces(PGconn *conn);
74static void dumpTablespaces(PGconn *conn);
75static void dropDBs(PGconn *conn);
76static void dumpUserConfig(PGconn *conn, const char *username);
77static void dumpDatabases(PGconn *conn);
78static void dumpTimestamp(const char *msg);
79static int runPgDump(const char *dbname, const char *create_opts, char *dbfile);
80static void buildShSecLabels(PGconn *conn,
81 const char *catalog_name, Oid objectId,
82 const char *objtype, const char *objname,
83 PQExpBuffer buffer);
84static void executeCommand(PGconn *conn, const char *query);
88 SimpleStringList *names);
89static void read_dumpall_filters(const char *filename, SimpleStringList *pattern);
90static ArchiveFormat parseDumpFormat(const char *format);
91static int createDumpId(void);
92
95static const char *connstr = "";
96static bool output_clean = false;
97static bool skip_acls = false;
98static bool verbose = false;
99static bool dosync = true;
100
101static int binary_upgrade = 0;
102static int column_inserts = 0;
104static int disable_triggers = 0;
105static int if_exists = 0;
106static int inserts = 0;
108static int no_tablespaces = 0;
109static int use_setsessauth = 0;
110static int no_comments = 0;
111static int no_policies = 0;
112static int no_publications = 0;
113static int no_security_labels = 0;
114static int no_data = 0;
115static int no_schema = 0;
116static int no_statistics = 0;
117static int no_subscriptions = 0;
118static int no_toast_compression = 0;
120static int no_role_passwords = 0;
121static int with_statistics = 0;
122static int server_version;
125static int statistics_only = 0;
126static int sequence_data = 0;
127
128static char role_catalog[10];
129#define PG_AUTHID "pg_authid"
130#define PG_ROLES "pg_roles "
131
132static FILE *OPF;
133static char *filename = NULL;
134
137
138static char *restrict_key;
139static Archive *fout = NULL;
140static int dumpIdVal = 0;
142static const CatalogId nilCatalogId = {0, 0};
143
144int
145main(int argc, char *argv[])
146{
147 static struct option long_options[] = {
148 {"data-only", no_argument, NULL, 'a'},
149 {"clean", no_argument, NULL, 'c'},
150 {"encoding", required_argument, NULL, 'E'},
151 {"file", required_argument, NULL, 'f'},
152 {"globals-only", no_argument, NULL, 'g'},
153 {"host", required_argument, NULL, 'h'},
154 {"dbname", required_argument, NULL, 'd'},
155 {"database", required_argument, NULL, 'l'},
156 {"no-owner", no_argument, NULL, 'O'},
157 {"port", required_argument, NULL, 'p'},
158 {"roles-only", no_argument, NULL, 'r'},
159 {"schema-only", no_argument, NULL, 's'},
160 {"superuser", required_argument, NULL, 'S'},
161 {"tablespaces-only", no_argument, NULL, 't'},
162 {"username", required_argument, NULL, 'U'},
163 {"verbose", no_argument, NULL, 'v'},
164 {"no-password", no_argument, NULL, 'w'},
165 {"password", no_argument, NULL, 'W'},
166 {"no-privileges", no_argument, NULL, 'x'},
167 {"no-acl", no_argument, NULL, 'x'},
168 {"format", required_argument, NULL, 'F'},
169
170 /*
171 * the following options don't have an equivalent short option letter
172 */
173 {"attribute-inserts", no_argument, &column_inserts, 1},
174 {"binary-upgrade", no_argument, &binary_upgrade, 1},
175 {"column-inserts", no_argument, &column_inserts, 1},
176 {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
177 {"disable-triggers", no_argument, &disable_triggers, 1},
178 {"exclude-database", required_argument, NULL, 6},
179 {"extra-float-digits", required_argument, NULL, 5},
180 {"if-exists", no_argument, &if_exists, 1},
181 {"inserts", no_argument, &inserts, 1},
182 {"lock-wait-timeout", required_argument, NULL, 2},
183 {"no-table-access-method", no_argument, &no_table_access_method, 1},
184 {"no-tablespaces", no_argument, &no_tablespaces, 1},
185 {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
186 {"load-via-partition-root", no_argument, &load_via_partition_root, 1},
187 {"role", required_argument, NULL, 3},
188 {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
189 {"no-comments", no_argument, &no_comments, 1},
190 {"no-data", no_argument, &no_data, 1},
191 {"no-policies", no_argument, &no_policies, 1},
192 {"no-publications", no_argument, &no_publications, 1},
193 {"no-role-passwords", no_argument, &no_role_passwords, 1},
194 {"no-schema", no_argument, &no_schema, 1},
195 {"no-security-labels", no_argument, &no_security_labels, 1},
196 {"no-subscriptions", no_argument, &no_subscriptions, 1},
197 {"no-statistics", no_argument, &no_statistics, 1},
198 {"no-sync", no_argument, NULL, 4},
199 {"no-toast-compression", no_argument, &no_toast_compression, 1},
200 {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1},
201 {"on-conflict-do-nothing", no_argument, &on_conflict_do_nothing, 1},
202 {"rows-per-insert", required_argument, NULL, 7},
203 {"statistics", no_argument, &with_statistics, 1},
204 {"statistics-only", no_argument, &statistics_only, 1},
205 {"filter", required_argument, NULL, 8},
206 {"sequence-data", no_argument, &sequence_data, 1},
207 {"restrict-key", required_argument, NULL, 9},
208
209 {NULL, 0, NULL, 0}
210 };
211
212 char *pghost = NULL;
213 char *pgport = NULL;
214 char *pguser = NULL;
215 char *pgdb = NULL;
216 char *use_role = NULL;
217 const char *dumpencoding = NULL;
218 const char *format_name = "p";
219 trivalue prompt_password = TRI_DEFAULT;
220 bool data_only = false;
221 bool globals_only = false;
222 bool roles_only = false;
223 bool schema_only = false;
224 bool tablespaces_only = false;
225 PGconn *conn;
226 int encoding;
227 int c,
228 ret;
229 int optindex;
230 DumpOptions dopt;
231
232 pg_logging_init(argv[0]);
234 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
235 progname = get_progname(argv[0]);
236
237 if (argc > 1)
238 {
239 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
240 {
241 help();
242 exit_nicely(0);
243 }
244 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
245 {
246 puts("pg_dumpall (PostgreSQL) " PG_VERSION);
247 exit_nicely(0);
248 }
249 }
250
251 if ((ret = find_other_exec(argv[0], "pg_dump", PGDUMP_VERSIONSTR,
252 pg_dump_bin)) < 0)
253 {
254 char full_path[MAXPGPATH];
255
256 if (find_my_exec(argv[0], full_path) < 0)
258
259 if (ret == -1)
260 pg_fatal("program \"%s\" is needed by %s but was not found in the same directory as \"%s\"",
261 "pg_dump", progname, full_path);
262 else
263 pg_fatal("program \"%s\" was found by \"%s\" but was not the same version as %s",
264 "pg_dump", full_path, progname);
265 }
266
268 InitDumpOptions(&dopt);
269
270 while ((c = getopt_long(argc, argv, "acd:E:f:F:gh:l:Op:rsS:tU:vwWx", long_options, &optindex)) != -1)
271 {
272 switch (c)
273 {
274 case 'a':
275 data_only = true;
277 break;
278
279 case 'c':
280 output_clean = true;
281 break;
282
283 case 'd':
285 break;
286
287 case 'E':
291 break;
292
293 case 'f':
297 break;
298 case 'F':
300 break;
301 case 'g':
302 globals_only = true;
303 break;
304
305 case 'h':
307 break;
308
309 case 'l':
311 break;
312
313 case 'O':
315 break;
316
317 case 'p':
319 break;
320
321 case 'r':
322 roles_only = true;
323 break;
324
325 case 's':
326 schema_only = true;
328 break;
329
330 case 'S':
333 break;
334
335 case 't':
336 tablespaces_only = true;
337 break;
338
339 case 'U':
340 pguser = pg_strdup(optarg);
342 break;
343
344 case 'v':
345 verbose = true;
348 break;
349
350 case 'w':
351 prompt_password = TRI_NO;
353 break;
354
355 case 'W':
356 prompt_password = TRI_YES;
358 break;
359
360 case 'x':
361 skip_acls = true;
363 break;
364
365 case 0:
366 break;
367
368 case 2:
369 appendPQExpBufferStr(pgdumpopts, " --lock-wait-timeout ");
371 break;
372
373 case 3:
374 use_role = pg_strdup(optarg);
375 appendPQExpBufferStr(pgdumpopts, " --role ");
376 appendShellString(pgdumpopts, use_role);
377 break;
378
379 case 4:
380 dosync = false;
381 appendPQExpBufferStr(pgdumpopts, " --no-sync");
382 break;
383
384 case 5:
385 appendPQExpBufferStr(pgdumpopts, " --extra-float-digits ");
387 break;
388
389 case 6:
391 break;
392
393 case 7:
394 appendPQExpBufferStr(pgdumpopts, " --rows-per-insert ");
396 break;
397
398 case 8:
400 break;
401
402 case 9:
404 appendPQExpBufferStr(pgdumpopts, " --restrict-key ");
406 break;
407
408 default:
409 /* getopt_long already emitted a complaint */
410 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
411 exit_nicely(1);
412 }
413 }
414
415 /* Complain if any arguments remain */
416 if (optind < argc)
417 {
418 pg_log_error("too many command-line arguments (first is \"%s\")",
419 argv[optind]);
420 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
421 exit_nicely(1);
422 }
423
424 /* --exclude-database is incompatible with global *-only options */
426 globals_only, "-g/--globals-only",
427 roles_only, "-r/--roles-only",
428 tablespaces_only, "-t/--tablespaces-only");
429
430 /* *-only options are incompatible with each other */
431 check_mut_excl_opts(data_only, "-a/--data-only",
432 globals_only, "-g/--globals-only",
433 roles_only, "-r/--roles-only",
434 schema_only, "-s/--schema-only",
435 statistics_only, "--statistics-only",
436 tablespaces_only, "-t/--tablespaces-only");
437
438 /* --no-* and *-only for same thing are incompatible */
439 check_mut_excl_opts(data_only, "-a/--data-only",
440 no_data, "--no-data");
441 check_mut_excl_opts(schema_only, "-s/--schema-only",
442 no_schema, "--no-schema");
443 check_mut_excl_opts(statistics_only, "--statistics-only",
444 no_statistics, "--no-statistics");
445
446 /* --statistics and --no-statistics are incompatible */
447 check_mut_excl_opts(with_statistics, "--statistics",
448 no_statistics, "--no-statistics");
449
450 /* --statistics is incompatible with *-only (except --statistics-only) */
451 check_mut_excl_opts(with_statistics, "--statistics",
452 data_only, "-a/--data-only",
453 globals_only, "-g/--globals-only",
454 roles_only, "-r/--roles-only",
455 schema_only, "-s/--schema-only",
456 tablespaces_only, "-t/--tablespaces-only");
457
458 /* --clean and --data-only are incompatible */
459 check_mut_excl_opts(output_clean, "-c/--clean",
460 data_only, "-a/--data-only");
461
462 if (if_exists && !output_clean)
463 pg_fatal("option %s requires option %s",
464 "--if-exists", "-c/--clean");
465
466 /* Get format for dump. */
468
469 /*
470 * If a non-plain format is specified, a file name is also required as the
471 * path to the main directory.
472 */
473 if (archDumpFormat != archNull &&
474 (!filename || strcmp(filename, "") == 0))
475 {
476 pg_log_error("option %s=d|c|t requires option %s",
477 "-F/--format", "-f/--file");
478 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
479 exit_nicely(1);
480 }
481
482 /* restrict-key is only supported with --format=plain */
484 pg_fatal("option %s can only be used with %s=plain",
485 "--restrict-key", "--format");
486
487 /* --clean and -g/--globals-only cannot be used together in non-text dump */
489 pg_fatal("options %s and %s cannot be used together in non-text dump",
490 "--clean", "-g/--globals-only");
491
492 /*
493 * If password values are not required in the dump, switch to using
494 * pg_roles which is equally useful, just more likely to have unrestricted
495 * access than pg_authid.
496 */
499 else
501
502 /* Add long options to the pg_dump argument list */
503 if (binary_upgrade)
504 appendPQExpBufferStr(pgdumpopts, " --binary-upgrade");
505 if (column_inserts)
506 appendPQExpBufferStr(pgdumpopts, " --column-inserts");
508 appendPQExpBufferStr(pgdumpopts, " --disable-dollar-quoting");
510 appendPQExpBufferStr(pgdumpopts, " --disable-triggers");
511 if (inserts)
512 appendPQExpBufferStr(pgdumpopts, " --inserts");
514 appendPQExpBufferStr(pgdumpopts, " --no-table-access-method");
515 if (no_tablespaces)
516 appendPQExpBufferStr(pgdumpopts, " --no-tablespaces");
518 appendPQExpBufferStr(pgdumpopts, " --quote-all-identifiers");
520 appendPQExpBufferStr(pgdumpopts, " --load-via-partition-root");
521 if (use_setsessauth)
522 appendPQExpBufferStr(pgdumpopts, " --use-set-session-authorization");
523 if (no_comments)
524 appendPQExpBufferStr(pgdumpopts, " --no-comments");
525 if (no_data)
526 appendPQExpBufferStr(pgdumpopts, " --no-data");
527 if (no_policies)
528 appendPQExpBufferStr(pgdumpopts, " --no-policies");
529 if (no_publications)
530 appendPQExpBufferStr(pgdumpopts, " --no-publications");
532 appendPQExpBufferStr(pgdumpopts, " --no-security-labels");
533 if (no_schema)
534 appendPQExpBufferStr(pgdumpopts, " --no-schema");
535 if (no_statistics)
536 appendPQExpBufferStr(pgdumpopts, " --no-statistics");
538 appendPQExpBufferStr(pgdumpopts, " --no-subscriptions");
540 appendPQExpBufferStr(pgdumpopts, " --no-toast-compression");
542 appendPQExpBufferStr(pgdumpopts, " --no-unlogged-table-data");
543 if (with_statistics)
544 appendPQExpBufferStr(pgdumpopts, " --statistics");
546 appendPQExpBufferStr(pgdumpopts, " --on-conflict-do-nothing");
547 if (statistics_only)
548 appendPQExpBufferStr(pgdumpopts, " --statistics-only");
549 if (sequence_data)
550 appendPQExpBufferStr(pgdumpopts, " --sequence-data");
551
552 /*
553 * Open the output file if required, otherwise use stdout. If required,
554 * then create new directory.
555 */
557 {
559
560 /* Create new directory or accept the empty existing directory. */
562 }
563 else if (filename)
564 {
566 if (!OPF)
567 pg_fatal("could not open output file \"%s\": %m",
568 filename);
569 }
570 else
571 OPF = stdout;
572
573 /*
574 * If you don't provide a restrict key, one will be appointed for you.
575 */
576 if (!restrict_key)
578 if (!restrict_key)
579 pg_fatal("could not generate restrict key");
581 pg_fatal("invalid restrict key");
582
583 /*
584 * If there was a database specified on the command line, use that,
585 * otherwise try to connect to database "postgres", and failing that
586 * "template1".
587 */
588 if (pgdb)
589 {
591 prompt_password, false,
593
594 if (!conn)
595 pg_fatal("could not connect to database \"%s\"", pgdb);
596 }
597 else
598 {
599 conn = ConnectDatabase("postgres", connstr, pghost, pgport, pguser,
600 prompt_password, false,
602 if (!conn)
603 conn = ConnectDatabase("template1", connstr, pghost, pgport, pguser,
604 prompt_password, true,
606
607 if (!conn)
608 {
609 pg_log_error("could not connect to databases \"postgres\" or \"template1\"\n"
610 "Please specify an alternative database.");
611 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
612 exit_nicely(1);
613 }
614 }
615
616 /*
617 * Get a list of database names that match the exclude patterns
618 */
621
622 /*
623 * Set the client encoding if requested.
624 */
625 if (dumpencoding)
626 {
628 pg_fatal("invalid client encoding \"%s\" specified",
630 }
631
632 /*
633 * Force standard_conforming_strings on, just in case we are dumping from
634 * an old server that has it disabled. Without this, literals in views,
635 * expressions, etc, would be incorrect for modern servers.
636 */
637 executeCommand(conn, "SET standard_conforming_strings = on");
638
639 /*
640 * Get the active encoding, so we know how to escape strings.
641 */
644
645 /* Set the role if requested */
646 if (use_role)
647 {
649
650 appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
651 executeCommand(conn, query->data);
652 destroyPQExpBuffer(query);
653 }
654
655 /* Force quoting of all identifiers if requested. */
657 executeCommand(conn, "SET quote_all_identifiers = true");
658
659 /* create a archive file for global commands. */
661 {
664 const char *encname;
665 pg_compress_specification compression_spec = {0};
666
667 /*
668 * Check that no global object names contain newlines or carriage
669 * returns, which would break the map.dat file format. This is only
670 * needed for servers older than v19, which started prohibiting such
671 * names.
672 */
673 if (server_version < 190000)
675
676 /* Set file path for global sql commands. */
677 snprintf(global_path, MAXPGPATH, "%s/toc.glo", filename);
678
679 /* Open the output file */
680 fout = CreateArchive(global_path, archCustom, compression_spec,
682
683 /* Make dump options accessible right away */
684 SetArchiveOptions(fout, &dopt, NULL);
685
686 ((ArchiveHandle *) fout)->connection = conn;
687 ((ArchiveHandle *) fout)->public.numWorkers = 1;
688
689 /* Register the cleanup hook */
691
692 /* Let the archiver know how noisy to be */
694
695 /*
696 * We allow the server to be back to 9.2, and up to any minor release
697 * of our own major version. (See also version check in
698 * pg_dumpall.c.)
699 */
700 fout->minRemoteVersion = 90200;
701 fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
702 fout->numWorkers = 1;
703
704 /* Dump default_transaction_read_only. */
705 appendPQExpBufferStr(qry, "SET default_transaction_read_only = off;\n\n");
707 nilCatalogId, /* catalog ID */
708 createDumpId(), /* dump ID */
709 ARCHIVE_OPTS(.tag = "default_transaction_read_only",
710 .description = "default_transaction_read_only",
711 .section = SECTION_PRE_DATA,
712 .createStmt = qry->data));
713 resetPQExpBuffer(qry);
714
715 /* Put the correct encoding into the archive */
717
718 appendPQExpBufferStr(qry, "SET client_encoding = ");
720 appendPQExpBufferStr(qry, ";\n");
722 nilCatalogId, /* catalog ID */
723 createDumpId(), /* dump ID */
724 ARCHIVE_OPTS(.tag = "client_encoding",
725 .description = "client_encoding",
726 .section = SECTION_PRE_DATA,
727 .createStmt = qry->data));
728 resetPQExpBuffer(qry);
729
730 /* Put the correct escape string behavior into the archive. */
731 appendPQExpBuffer(qry, "SET standard_conforming_strings = 'on';\n");
733 nilCatalogId, /* catalog ID */
734 createDumpId(), /* dump ID */
735 ARCHIVE_OPTS(.tag = "standard_conforming_strings",
736 .description = "standard_conforming_strings",
737 .section = SECTION_PRE_DATA,
738 .createStmt = qry->data));
740 }
741 else
742 {
743 fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
744
745 if (verbose)
746 dumpTimestamp("Started on");
747
748 /*
749 * Enter restricted mode to block any unexpected psql meta-commands. A
750 * malicious source might try to inject a variety of things via bogus
751 * responses to queries. While we cannot prevent such sources from
752 * affecting the destination at restore time, we can block psql
753 * meta-commands so that the client machine that runs psql with the
754 * dump output remains unaffected.
755 */
756 fprintf(OPF, "\\restrict %s\n\n", restrict_key);
757
758 /*
759 * We used to emit \connect postgres here, but that served no purpose
760 * other than to break things for installations without a postgres
761 * database. Everything we're restoring here is a global, so
762 * whichever database we're connected to at the moment is fine.
763 */
764
765 /* Restore will need to write to the target cluster */
766 fprintf(OPF, "SET default_transaction_read_only = off;\n\n");
767
768 /* Replicate encoding and standard_conforming_strings in output */
769 fprintf(OPF, "SET client_encoding = '%s';\n",
771 fprintf(OPF, "SET standard_conforming_strings = on;\n");
772 fprintf(OPF, "\n");
773 }
774
776 {
777 /*
778 * If asked to --clean, do that first. We can avoid detailed
779 * dependency analysis because databases never depend on each other,
780 * and tablespaces never depend on each other. Roles could have
781 * grants to each other, but DROP ROLE will clean those up silently.
782 *
783 * For non-text formats, pg_dumpall unconditionally process --clean
784 * option. In contrast, pg_restore only applies it if the user
785 * explicitly provides the flag. This discrepancy resolves corner
786 * cases where pg_restore requires cleanup instructions that may be
787 * missing from a standard pg_dumpall output.
788 */
790 {
792 dropDBs(conn);
793
794 if (!roles_only && !no_tablespaces)
796
797 if (!tablespaces_only)
799 }
800
801 /*
802 * Now create objects as requested. Be careful that option logic here
803 * is the same as for drops above.
804 */
805 if (!tablespaces_only)
806 {
807 /* Dump roles (users) */
809
810 /* Dump role memberships */
812
813 /* Dump role GUC privileges */
814 if (server_version >= 150000 && !skip_acls)
816 }
817
818 /* Dump tablespaces */
819 if (!roles_only && !no_tablespaces)
821 }
822
824 {
825 /*
826 * Exit restricted mode just before dumping the databases. pg_dump
827 * will handle entering restricted mode again as appropriate.
828 */
829 fprintf(OPF, "\\unrestrict %s\n\n", restrict_key);
830 }
831
834
836 {
837 PQfinish(conn);
838
839 if (verbose)
840 dumpTimestamp("Completed on");
841 fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
842
843 if (filename)
844 {
845 fclose(OPF);
846
847 /* sync the resulting file, errors are not fatal */
848 if (dosync)
849 (void) fsync_fname(filename, false);
850 }
851 }
852 else
853 {
854 RestoreOptions *ropt;
855
856 ropt = NewRestoreOptions();
857 SetArchiveOptions(fout, &dopt, ropt);
858
859 /* Mark which entries should be output */
862 }
863
864 exit_nicely(0);
865}
866
867
868static void
869help(void)
870{
871 printf(_("%s exports a PostgreSQL database cluster as an SQL script or to other formats.\n\n"), progname);
872 printf(_("Usage:\n"));
873 printf(_(" %s [OPTION]...\n"), progname);
874
875 printf(_("\nGeneral options:\n"));
876 printf(_(" -f, --file=FILENAME output file name\n"));
877 printf(_(" -F, --format=c|d|t|p output file format (custom, directory, tar,\n"
878 " plain text (default))\n"));
879 printf(_(" -v, --verbose verbose mode\n"));
880 printf(_(" -V, --version output version information, then exit\n"));
881 printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
882 printf(_(" -?, --help show this help, then exit\n"));
883 printf(_("\nOptions controlling the output content:\n"));
884 printf(_(" -a, --data-only dump only the data, not the schema or statistics\n"));
885 printf(_(" -c, --clean clean (drop) databases before recreating\n"));
886 printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
887 printf(_(" -g, --globals-only dump only global objects, no databases\n"));
888 printf(_(" -O, --no-owner skip restoration of object ownership\n"));
889 printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n"));
890 printf(_(" -s, --schema-only dump only the schema, no data or statistics\n"));
891 printf(_(" -S, --superuser=NAME superuser user name to use in the dump\n"));
892 printf(_(" -t, --tablespaces-only dump only tablespaces, no databases or roles\n"));
893 printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
894 printf(_(" --binary-upgrade for use by upgrade utilities only\n"));
895 printf(_(" --column-inserts dump data as INSERT commands with column names\n"));
896 printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
897 printf(_(" --disable-triggers disable triggers during data-only restore\n"));
898 printf(_(" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n"));
899 printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n"));
900 printf(_(" --filter=FILENAME exclude databases based on expressions in FILENAME\n"));
901 printf(_(" --if-exists use IF EXISTS when dropping objects\n"));
902 printf(_(" --inserts dump data as INSERT commands, rather than COPY\n"));
903 printf(_(" --load-via-partition-root load partitions via the root table\n"));
904 printf(_(" --no-comments do not dump comment commands\n"));
905 printf(_(" --no-data do not dump data\n"));
906 printf(_(" --no-policies do not dump row security policies\n"));
907 printf(_(" --no-publications do not dump publications\n"));
908 printf(_(" --no-role-passwords do not dump passwords for roles\n"));
909 printf(_(" --no-schema do not dump schema\n"));
910 printf(_(" --no-security-labels do not dump security label assignments\n"));
911 printf(_(" --no-statistics do not dump statistics\n"));
912 printf(_(" --no-subscriptions do not dump subscriptions\n"));
913 printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
914 printf(_(" --no-table-access-method do not dump table access methods\n"));
915 printf(_(" --no-tablespaces do not dump tablespace assignments\n"));
916 printf(_(" --no-toast-compression do not dump TOAST compression methods\n"));
917 printf(_(" --no-unlogged-table-data do not dump unlogged table data\n"));
918 printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n"));
919 printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n"));
920 printf(_(" --restrict-key=RESTRICT_KEY use provided string as psql \\restrict key\n"));
921 printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n"));
922 printf(_(" --sequence-data include sequence data in dump\n"));
923 printf(_(" --statistics dump the statistics\n"));
924 printf(_(" --statistics-only dump only the statistics, not schema or data\n"));
925 printf(_(" --use-set-session-authorization\n"
926 " use SET SESSION AUTHORIZATION commands instead of\n"
927 " ALTER OWNER commands to set ownership\n"));
928
929 printf(_("\nConnection options:\n"));
930 printf(_(" -d, --dbname=CONNSTR connect using connection string\n"));
931 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
932 printf(_(" -l, --database=DBNAME alternative default database\n"));
933 printf(_(" -p, --port=PORT database server port number\n"));
934 printf(_(" -U, --username=NAME connect as specified database user\n"));
935 printf(_(" -w, --no-password never prompt for password\n"));
936 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
937 printf(_(" --role=ROLENAME do SET ROLE before dump\n"));
938
939 printf(_("\nIf -f/--file is not used, then the SQL script will be written to the standard\n"
940 "output.\n\n"));
941 printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
942 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
943}
944
945
946/*
947 * Drop roles
948 */
949static void
951{
953 PGresult *res;
954 int i_rolname;
955 int i;
956
957 if (server_version >= 90600)
959 "SELECT rolname "
960 "FROM %s "
961 "WHERE rolname !~ '^pg_' "
962 "ORDER BY 1", role_catalog);
963 else
965 "SELECT rolname "
966 "FROM %s "
967 "ORDER BY 1", role_catalog);
968
969 res = executeQuery(conn, buf->data);
970
971 i_rolname = PQfnumber(res, "rolname");
972
973 if (PQntuples(res) > 0 && archDumpFormat == archNull)
974 fprintf(OPF, "--\n-- Drop roles\n--\n\n");
975
976 for (i = 0; i < PQntuples(res); i++)
977 {
978 const char *rolename;
980
981 rolename = PQgetvalue(res, i, i_rolname);
982
984 {
985 appendPQExpBuffer(delQry, "DROP ROLE %s%s;\n",
986 if_exists ? "IF EXISTS " : "",
987 fmtId(rolename));
988 fprintf(OPF, "%s", delQry->data);
989 }
990 else
991 {
992 appendPQExpBuffer(delQry, "DROP ROLE IF EXISTS %s;\n",
993 fmtId(rolename));
994
996 nilCatalogId, /* catalog ID */
997 createDumpId(), /* dump ID */
998 ARCHIVE_OPTS(.tag = psprintf("ROLE %s", fmtId(rolename)),
999 .description = "DROP_GLOBAL",
1000 .section = SECTION_PRE_DATA,
1001 .createStmt = delQry->data));
1002 }
1003
1005 }
1006
1007 PQclear(res);
1009
1010 if (archDumpFormat == archNull)
1011 fprintf(OPF, "\n\n");
1012}
1013
1014/*
1015 * Dump roles
1016 */
1017static void
1019{
1023 PGresult *res;
1024 int i_oid,
1025 i_rolname,
1026 i_rolsuper,
1038 int i;
1039
1040 /*
1041 * Notes: rolconfig is dumped later, and pg_authid must be used for
1042 * extracting rolcomment regardless of role_catalog.
1043 */
1044 if (server_version >= 90600)
1046 "SELECT oid, rolname, rolsuper, rolinherit, "
1047 "rolcreaterole, rolcreatedb, "
1048 "rolcanlogin, rolconnlimit, rolpassword, "
1049 "rolvaliduntil, rolreplication, rolbypassrls, "
1050 "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, "
1051 "rolname = current_user AS is_current_user "
1052 "FROM %s "
1053 "WHERE rolname !~ '^pg_' "
1054 "ORDER BY 2", role_catalog);
1055 else if (server_version >= 90500)
1057 "SELECT oid, rolname, rolsuper, rolinherit, "
1058 "rolcreaterole, rolcreatedb, "
1059 "rolcanlogin, rolconnlimit, rolpassword, "
1060 "rolvaliduntil, rolreplication, rolbypassrls, "
1061 "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, "
1062 "rolname = current_user AS is_current_user "
1063 "FROM %s "
1064 "ORDER BY 2", role_catalog);
1065 else
1067 "SELECT oid, rolname, rolsuper, rolinherit, "
1068 "rolcreaterole, rolcreatedb, "
1069 "rolcanlogin, rolconnlimit, rolpassword, "
1070 "rolvaliduntil, rolreplication, "
1071 "false as rolbypassrls, "
1072 "pg_catalog.shobj_description(oid, 'pg_authid') as rolcomment, "
1073 "rolname = current_user AS is_current_user "
1074 "FROM %s "
1075 "ORDER BY 2", role_catalog);
1076
1077 res = executeQuery(conn, buf->data);
1078
1079 i_oid = PQfnumber(res, "oid");
1080 i_rolname = PQfnumber(res, "rolname");
1081 i_rolsuper = PQfnumber(res, "rolsuper");
1082 i_rolinherit = PQfnumber(res, "rolinherit");
1083 i_rolcreaterole = PQfnumber(res, "rolcreaterole");
1084 i_rolcreatedb = PQfnumber(res, "rolcreatedb");
1085 i_rolcanlogin = PQfnumber(res, "rolcanlogin");
1086 i_rolconnlimit = PQfnumber(res, "rolconnlimit");
1087 i_rolpassword = PQfnumber(res, "rolpassword");
1088 i_rolvaliduntil = PQfnumber(res, "rolvaliduntil");
1089 i_rolreplication = PQfnumber(res, "rolreplication");
1090 i_rolbypassrls = PQfnumber(res, "rolbypassrls");
1091 i_rolcomment = PQfnumber(res, "rolcomment");
1092 i_is_current_user = PQfnumber(res, "is_current_user");
1093
1094 if (PQntuples(res) > 0 && archDumpFormat == archNull)
1095 fprintf(OPF, "--\n-- Roles\n--\n\n");
1096
1097 for (i = 0; i < PQntuples(res); i++)
1098 {
1099 const char *rolename;
1100 Oid auth_oid;
1101
1102 auth_oid = atooid(PQgetvalue(res, i, i_oid));
1103 rolename = PQgetvalue(res, i, i_rolname);
1104
1105 if (strncmp(rolename, "pg_", 3) == 0)
1106 {
1107 pg_log_warning("role name starting with \"pg_\" skipped (%s)",
1108 rolename);
1109 continue;
1110 }
1111
1115
1116 if (binary_upgrade)
1117 {
1118 appendPQExpBufferStr(buf, "\n-- For binary upgrade, must preserve pg_authid.oid\n");
1120 "SELECT pg_catalog.binary_upgrade_set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n",
1121 auth_oid);
1122 }
1123
1124 /*
1125 * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role
1126 * will acquire the right properties even if it already exists (ie, it
1127 * won't hurt for the CREATE to fail). This is particularly important
1128 * for the role we are connected as, since even with --clean we will
1129 * have failed to drop it. binary_upgrade cannot generate any errors,
1130 * so we assume the current role is already created.
1131 */
1132 if (!binary_upgrade ||
1133 strcmp(PQgetvalue(res, i, i_is_current_user), "f") == 0)
1134 appendPQExpBuffer(buf, "CREATE ROLE %s;\n", fmtId(rolename));
1135 appendPQExpBuffer(buf, "ALTER ROLE %s WITH", fmtId(rolename));
1136
1137 if (strcmp(PQgetvalue(res, i, i_rolsuper), "t") == 0)
1138 appendPQExpBufferStr(buf, " SUPERUSER");
1139 else
1140 appendPQExpBufferStr(buf, " NOSUPERUSER");
1141
1142 if (strcmp(PQgetvalue(res, i, i_rolinherit), "t") == 0)
1143 appendPQExpBufferStr(buf, " INHERIT");
1144 else
1145 appendPQExpBufferStr(buf, " NOINHERIT");
1146
1147 if (strcmp(PQgetvalue(res, i, i_rolcreaterole), "t") == 0)
1148 appendPQExpBufferStr(buf, " CREATEROLE");
1149 else
1150 appendPQExpBufferStr(buf, " NOCREATEROLE");
1151
1152 if (strcmp(PQgetvalue(res, i, i_rolcreatedb), "t") == 0)
1153 appendPQExpBufferStr(buf, " CREATEDB");
1154 else
1155 appendPQExpBufferStr(buf, " NOCREATEDB");
1156
1157 if (strcmp(PQgetvalue(res, i, i_rolcanlogin), "t") == 0)
1158 appendPQExpBufferStr(buf, " LOGIN");
1159 else
1160 appendPQExpBufferStr(buf, " NOLOGIN");
1161
1162 if (strcmp(PQgetvalue(res, i, i_rolreplication), "t") == 0)
1163 appendPQExpBufferStr(buf, " REPLICATION");
1164 else
1165 appendPQExpBufferStr(buf, " NOREPLICATION");
1166
1167 if (strcmp(PQgetvalue(res, i, i_rolbypassrls), "t") == 0)
1168 appendPQExpBufferStr(buf, " BYPASSRLS");
1169 else
1170 appendPQExpBufferStr(buf, " NOBYPASSRLS");
1171
1172 if (strcmp(PQgetvalue(res, i, i_rolconnlimit), "-1") != 0)
1173 appendPQExpBuffer(buf, " CONNECTION LIMIT %s",
1174 PQgetvalue(res, i, i_rolconnlimit));
1175
1176
1178 {
1179 appendPQExpBufferStr(buf, " PASSWORD ");
1181 }
1182
1183 if (!PQgetisnull(res, i, i_rolvaliduntil))
1184 appendPQExpBuffer(buf, " VALID UNTIL '%s'",
1186
1187 appendPQExpBufferStr(buf, ";\n");
1188
1189 if (!no_comments && !PQgetisnull(res, i, i_rolcomment))
1190 {
1191 appendPQExpBuffer(comment_buf, "COMMENT ON ROLE %s IS ", fmtId(rolename));
1194 }
1195
1196 if (!no_security_labels)
1197 buildShSecLabels(conn, "pg_authid", auth_oid,
1198 "ROLE", rolename,
1199 seclabel_buf);
1200
1201 if (archDumpFormat == archNull)
1202 {
1203 fprintf(OPF, "%s", buf->data);
1204 fprintf(OPF, "%s", comment_buf->data);
1205
1206 if (seclabel_buf->data[0] != '\0')
1207 fprintf(OPF, "%s", seclabel_buf->data);
1208 }
1209 else
1210 {
1211 char *tag = psprintf("ROLE %s", fmtId(rolename));
1212
1214 nilCatalogId, /* catalog ID */
1215 createDumpId(), /* dump ID */
1216 ARCHIVE_OPTS(.tag = tag,
1217 .description = "ROLE",
1218 .section = SECTION_PRE_DATA,
1219 .createStmt = buf->data));
1220 if (comment_buf->data[0] != '\0')
1222 nilCatalogId, /* catalog ID */
1223 createDumpId(), /* dump ID */
1224 ARCHIVE_OPTS(.tag = tag,
1225 .description = "COMMENT",
1226 .section = SECTION_PRE_DATA,
1227 .createStmt = comment_buf->data));
1228
1229 if (seclabel_buf->data[0] != '\0')
1231 nilCatalogId, /* catalog ID */
1232 createDumpId(), /* dump ID */
1233 ARCHIVE_OPTS(.tag = tag,
1234 .description = "SECURITY LABEL",
1235 .section = SECTION_PRE_DATA,
1236 .createStmt = seclabel_buf->data));
1237 }
1238 }
1239
1240 /*
1241 * Dump configuration settings for roles after all roles have been dumped.
1242 * We do it this way because config settings for roles could mention the
1243 * names of other roles.
1244 */
1245 if (PQntuples(res) > 0 && archDumpFormat == archNull)
1246 fprintf(OPF, "\n--\n-- User Configurations\n--\n");
1247
1248 for (i = 0; i < PQntuples(res); i++)
1250
1251 PQclear(res);
1252
1253 if (archDumpFormat == archNull)
1254 fprintf(OPF, "\n\n");
1255
1259}
1260
1261
1262/*
1263 * Dump role memberships.
1264 *
1265 * Note: we expect dumpRoles already created all the roles, but there is
1266 * no membership yet.
1267 */
1268static void
1270{
1274 PGresult *res;
1275 int start = 0,
1276 end,
1277 total;
1278 bool dump_grantors;
1279 bool dump_grant_options;
1280 int i_role;
1281 int i_member;
1282 int i_grantor;
1283 int i_roleid;
1284 int i_memberid;
1285 int i_grantorid;
1286 int i_admin_option;
1287 int i_inherit_option;
1288 int i_set_option;
1289
1290 /*
1291 * Previous versions of PostgreSQL didn't used to track the grantor very
1292 * carefully in the backend, and the grantor could be any user even if
1293 * they didn't have ADMIN OPTION on the role, or a user that no longer
1294 * existed. To avoid dump and restore failures, don't dump the grantor
1295 * when talking to an old server version.
1296 *
1297 * Also, in older versions the roleid and/or member could be role OIDs
1298 * that no longer exist. If we find such cases, print a warning and skip
1299 * the entry.
1300 */
1301 dump_grantors = (server_version >= 160000);
1302
1303 /*
1304 * Previous versions of PostgreSQL also did not have grant-level options.
1305 */
1306 dump_grant_options = (server_version >= 160000);
1307
1308 /* Generate and execute query. */
1309 printfPQExpBuffer(buf, "SELECT ur.rolname AS role, "
1310 "um.rolname AS member, "
1311 "ug.rolname AS grantor, "
1312 "a.roleid AS roleid, "
1313 "a.member AS memberid, "
1314 "a.grantor AS grantorid, "
1315 "a.admin_option");
1317 appendPQExpBufferStr(buf, ", a.inherit_option, a.set_option");
1318 appendPQExpBuffer(buf, " FROM pg_auth_members a "
1319 "LEFT JOIN %s ur on ur.oid = a.roleid "
1320 "LEFT JOIN %s um on um.oid = a.member "
1321 "LEFT JOIN %s ug on ug.oid = a.grantor "
1322 "WHERE NOT (ur.rolname ~ '^pg_' AND um.rolname ~ '^pg_')"
1323 "ORDER BY 1,2,3", role_catalog, role_catalog, role_catalog);
1324 res = executeQuery(conn, buf->data);
1325 i_role = PQfnumber(res, "role");
1326 i_member = PQfnumber(res, "member");
1327 i_grantor = PQfnumber(res, "grantor");
1328 i_roleid = PQfnumber(res, "roleid");
1329 i_memberid = PQfnumber(res, "memberid");
1330 i_grantorid = PQfnumber(res, "grantorid");
1331 i_admin_option = PQfnumber(res, "admin_option");
1332 i_inherit_option = PQfnumber(res, "inherit_option");
1333 i_set_option = PQfnumber(res, "set_option");
1334
1335 if (PQntuples(res) > 0 && archDumpFormat == archNull)
1336 fprintf(OPF, "--\n-- Role memberships\n--\n\n");
1337
1338 /*
1339 * We can't dump these GRANT commands in arbitrary order, because a role
1340 * that is named as a grantor must already have ADMIN OPTION on the role
1341 * for which it is granting permissions, except for the bootstrap
1342 * superuser, who can always be named as the grantor.
1343 *
1344 * We handle this by considering these grants role by role. For each role,
1345 * we initially consider the only allowable grantor to be the bootstrap
1346 * superuser. Every time we grant ADMIN OPTION on the role to some user,
1347 * that user also becomes an allowable grantor. We make repeated passes
1348 * over the grants for the role, each time dumping those whose grantors
1349 * are allowable and which we haven't done yet. Eventually this should let
1350 * us dump all the grants.
1351 */
1352 total = PQntuples(res);
1353 while (start < total)
1354 {
1355 char *role = PQgetvalue(res, start, i_role);
1356 int i;
1357 bool *done;
1358 int remaining;
1359 int prev_remaining = 0;
1361
1362 /* If we hit a null roleid, we're done (nulls sort to the end). */
1363 if (PQgetisnull(res, start, i_role))
1364 {
1365 /* translator: %s represents a numeric role OID */
1366 pg_log_warning("ignoring role grant for missing role with OID %s",
1367 PQgetvalue(res, start, i_roleid));
1368 break;
1369 }
1370
1371 /* All memberships for a single role should be adjacent. */
1372 for (end = start; end < total; ++end)
1373 {
1374 char *otherrole;
1375
1376 otherrole = PQgetvalue(res, end, i_role);
1377 if (strcmp(role, otherrole) != 0)
1378 break;
1379 }
1380
1381 remaining = end - start;
1382 done = pg_malloc0_array(bool, remaining);
1383
1384 /*
1385 * We use a hashtable to track the member names that have been granted
1386 * admin option. Usually a hashtable is overkill, but sometimes not.
1387 */
1389
1390 /*
1391 * Make repeated passes over the grants for this role until all have
1392 * been dumped.
1393 */
1394 while (remaining > 0)
1395 {
1396 /*
1397 * We should make progress on every iteration, because a notional
1398 * graph whose vertices are grants and whose edges point from
1399 * grantors to members should be connected and acyclic. If we fail
1400 * to make progress, either we or the server have messed up.
1401 */
1403 {
1404 pg_log_error("could not find a legal dump ordering for memberships in role \"%s\"",
1405 role);
1406 PQfinish(conn);
1407 exit_nicely(1);
1408 }
1410
1411 /* Make one pass over the grants for this role. */
1412 for (i = start; i < end; ++i)
1413 {
1414 char *member;
1415 char *grantorid;
1416 char *grantor = NULL;
1418 char *set_option = "true";
1419 char *admin_option;
1420 bool found;
1421
1422 /* If we already did this grant, don't do it again. */
1423 if (done[i - start])
1424 continue;
1425
1426 /* Complain about, then ignore, entries for unknown members. */
1427 if (PQgetisnull(res, i, i_member))
1428 {
1429 /* translator: %s represents a numeric role OID */
1430 pg_log_warning("ignoring role grant to missing role with OID %s",
1431 PQgetvalue(res, i, i_memberid));
1432 done[i - start] = true;
1433 --remaining;
1434 continue;
1435 }
1436 member = PQgetvalue(res, i, i_member);
1437
1438 /* If the grantor is unknown, complain and dump without it. */
1441 {
1442 if (PQgetisnull(res, i, i_grantor))
1443 {
1444 /* translator: %s represents a numeric role OID */
1445 pg_log_warning("grant of role \"%s\" to \"%s\" has invalid grantor OID %s",
1446 role, member, grantorid);
1447 pg_log_warning_detail("This grant will be dumped without GRANTED BY.");
1448 dump_this_grantor = false;
1449 }
1450 else
1451 grantor = PQgetvalue(res, i, i_grantor);
1452 }
1453
1457
1458 /*
1459 * If we're not dumping the grantor or if the grantor is the
1460 * bootstrap superuser, it's fine to dump this now. Otherwise,
1461 * it's got to be someone who has already been granted ADMIN
1462 * OPTION.
1463 */
1464 if (dump_this_grantor &&
1466 rolename_lookup(ht, grantor) == NULL)
1467 continue;
1468
1469 /* Remember that we did this so that we don't do it again. */
1470 done[i - start] = true;
1471 --remaining;
1472
1473 /*
1474 * If ADMIN OPTION is being granted, remember that grants
1475 * listing this member as the grantor can now be dumped.
1476 */
1477 if (*admin_option == 't')
1478 rolename_insert(ht, member, &found);
1479
1480 /* Generate the actual GRANT statement. */
1483 appendPQExpBuffer(querybuf, "GRANT %s", fmtId(role));
1484 appendPQExpBuffer(querybuf, " TO %s", fmtId(member));
1485 if (*admin_option == 't')
1486 appendPQExpBufferStr(optbuf, "ADMIN OPTION");
1488 {
1489 char *inherit_option;
1490
1491 if (optbuf->data[0] != '\0')
1494 appendPQExpBuffer(optbuf, "INHERIT %s",
1495 *inherit_option == 't' ?
1496 "TRUE" : "FALSE");
1497 }
1498 if (*set_option != 't')
1499 {
1500 if (optbuf->data[0] != '\0')
1502 appendPQExpBufferStr(optbuf, "SET FALSE");
1503 }
1504 if (optbuf->data[0] != '\0')
1505 appendPQExpBuffer(querybuf, " WITH %s", optbuf->data);
1507 appendPQExpBuffer(querybuf, " GRANTED BY %s", fmtId(grantor));
1509
1510 if (archDumpFormat == archNull)
1511 fprintf(OPF, "%s", querybuf->data);
1512 else
1514 nilCatalogId, /* catalog ID */
1515 createDumpId(), /* dump ID */
1516 ARCHIVE_OPTS(.tag = psprintf("ROLE %s", fmtId(role)),
1517 .description = "ROLE PROPERTIES",
1518 .section = SECTION_PRE_DATA,
1519 .createStmt = querybuf->data));
1520 }
1521 }
1522
1524 pg_free(done);
1525 start = end;
1526 }
1527
1528 PQclear(res);
1532
1533 if (archDumpFormat == archNull)
1534 fprintf(OPF, "\n\n");
1535}
1536
1537
1538/*
1539 * Dump role configuration parameter privileges. This code is used for 15.0
1540 * and later servers.
1541 *
1542 * Note: we expect dumpRoles already created all the roles, but there are
1543 * no per-role configuration parameter privileges yet.
1544 */
1545static void
1547{
1548 PGresult *res;
1549 int i;
1550
1551 /*
1552 * Get all parameters that have non-default acls defined.
1553 */
1554 res = executeQuery(conn, "SELECT parname, "
1555 "pg_catalog.pg_get_userbyid(" CppAsString2(BOOTSTRAP_SUPERUSERID) ") AS parowner, "
1556 "paracl, "
1557 "pg_catalog.acldefault('p', " CppAsString2(BOOTSTRAP_SUPERUSERID) ") AS acldefault "
1558 "FROM pg_catalog.pg_parameter_acl "
1559 "ORDER BY 1");
1560
1561 if (PQntuples(res) > 0 && archDumpFormat == archNull)
1562 fprintf(OPF, "--\n-- Role privileges on configuration parameters\n--\n\n");
1563
1564 for (i = 0; i < PQntuples(res); i++)
1565 {
1567 char *parname = PQgetvalue(res, i, 0);
1568 char *parowner = PQgetvalue(res, i, 1);
1569 char *paracl = PQgetvalue(res, i, 2);
1570 char *acldefault = PQgetvalue(res, i, 3);
1571 char *fparname;
1572
1573 /* needed for buildACLCommands() */
1575
1576 if (!buildACLCommands(fparname, NULL, NULL, "PARAMETER",
1579 {
1580 pg_log_error("could not parse ACL list (%s) for parameter \"%s\"",
1581 paracl, parname);
1582 PQfinish(conn);
1583 exit_nicely(1);
1584 }
1585
1586 if (archDumpFormat == archNull)
1587 fprintf(OPF, "%s", buf->data);
1588 else
1590 nilCatalogId, /* catalog ID */
1591 createDumpId(), /* dump ID */
1592 ARCHIVE_OPTS(.tag = psprintf("ROLE %s", fmtId(parowner)),
1593 .description = "ROLE PROPERTIES",
1594 .section = SECTION_PRE_DATA,
1595 .createStmt = buf->data));
1596
1597 free(fparname);
1599 }
1600
1601 PQclear(res);
1602
1603 if (archDumpFormat == archNull)
1604 fprintf(OPF, "\n\n");
1605}
1606
1607
1608/*
1609 * Drop tablespaces.
1610 */
1611static void
1613{
1614 PGresult *res;
1615 int i;
1616
1617 /*
1618 * Get all tablespaces except built-in ones (which we assume are named
1619 * pg_xxx)
1620 */
1621 res = executeQuery(conn, "SELECT spcname "
1622 "FROM pg_catalog.pg_tablespace "
1623 "WHERE spcname !~ '^pg_' "
1624 "ORDER BY 1");
1625
1626 if (PQntuples(res) > 0 && archDumpFormat == archNull)
1627 fprintf(OPF, "--\n-- Drop tablespaces\n--\n\n");
1628
1629 for (i = 0; i < PQntuples(res); i++)
1630 {
1631 char *spcname = PQgetvalue(res, i, 0);
1633
1634 if (archDumpFormat == archNull)
1635 {
1636 appendPQExpBuffer(delQry, "DROP TABLESPACE %s%s;\n",
1637 if_exists ? "IF EXISTS " : "",
1638 fmtId(spcname));
1639 fprintf(OPF, "%s", delQry->data);
1640 }
1641 else
1642 {
1643 appendPQExpBuffer(delQry, "DROP TABLESPACE IF EXISTS %s;\n",
1644 fmtId(spcname));
1646 nilCatalogId, /* catalog ID */
1647 createDumpId(), /* dump ID */
1648 ARCHIVE_OPTS(.tag = psprintf("TABLESPACE %s", fmtId(spcname)),
1649 .description = "DROP_GLOBAL",
1650 .section = SECTION_PRE_DATA,
1651 .createStmt = delQry->data));
1652 }
1653
1655 }
1656
1657 PQclear(res);
1658
1659 if (archDumpFormat == archNull)
1660 fprintf(OPF, "\n\n");
1661}
1662
1663/*
1664 * Dump tablespaces.
1665 */
1666static void
1668{
1669 PGresult *res;
1672 int i;
1673
1674 /*
1675 * Get all tablespaces except built-in ones (which we assume are named
1676 * pg_xxx)
1677 */
1678 res = executeQuery(conn, "SELECT oid, spcname, "
1679 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
1680 "pg_catalog.pg_tablespace_location(oid), "
1681 "spcacl, acldefault('t', spcowner) AS acldefault, "
1682 "array_to_string(spcoptions, ', '),"
1683 "pg_catalog.shobj_description(oid, 'pg_tablespace') "
1684 "FROM pg_catalog.pg_tablespace "
1685 "WHERE spcname !~ '^pg_' "
1686 "ORDER BY 1");
1687
1688 if (PQntuples(res) > 0 && archDumpFormat == archNull)
1689 fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
1690
1691 for (i = 0; i < PQntuples(res); i++)
1692 {
1694 Oid spcoid = atooid(PQgetvalue(res, i, 0));
1695 char *spcname = PQgetvalue(res, i, 1);
1696 char *spcowner = PQgetvalue(res, i, 2);
1697 char *spclocation = PQgetvalue(res, i, 3);
1698 char *spcacl = PQgetvalue(res, i, 4);
1699 char *acldefault = PQgetvalue(res, i, 5);
1700 char *spcoptions = PQgetvalue(res, i, 6);
1701 char *spccomment = PQgetvalue(res, i, 7);
1702 char *fspcname;
1703
1704 /* needed for buildACLCommands() */
1706
1709
1710 if (binary_upgrade)
1711 {
1712 appendPQExpBufferStr(buf, "\n-- For binary upgrade, must preserve pg_tablespace oid\n");
1713 appendPQExpBuffer(buf, "SELECT pg_catalog.binary_upgrade_set_next_pg_tablespace_oid('%u'::pg_catalog.oid);\n", spcoid);
1714 }
1715
1716 appendPQExpBuffer(buf, "CREATE TABLESPACE %s", fspcname);
1717 appendPQExpBuffer(buf, " OWNER %s", fmtId(spcowner));
1718
1719 appendPQExpBufferStr(buf, " LOCATION ");
1720
1721 /*
1722 * In-place tablespaces use a relative path, and need to be dumped
1723 * with an empty string as location.
1724 */
1727 else
1729
1730 appendPQExpBufferStr(buf, ";\n");
1731
1732 if (spcoptions && spcoptions[0] != '\0')
1733 appendPQExpBuffer(buf, "ALTER TABLESPACE %s SET (%s);\n",
1735
1736 /* tablespaces can't have initprivs */
1737
1738 if (!skip_acls &&
1739 !buildACLCommands(fspcname, NULL, NULL, "TABLESPACE",
1742 {
1743 pg_log_error("could not parse ACL list (%s) for tablespace \"%s\"",
1744 spcacl, spcname);
1745 PQfinish(conn);
1746 exit_nicely(1);
1747 }
1748
1749 if (!no_comments && spccomment && spccomment[0] != '\0')
1750 {
1751 appendPQExpBuffer(comment_buf, "COMMENT ON TABLESPACE %s IS ", fspcname);
1754 }
1755
1756 if (!no_security_labels)
1757 buildShSecLabels(conn, "pg_tablespace", spcoid,
1758 "TABLESPACE", spcname,
1759 seclabel_buf);
1760
1761 if (archDumpFormat == archNull)
1762 {
1763 fprintf(OPF, "%s", buf->data);
1764
1765 if (comment_buf->data[0] != '\0')
1766 fprintf(OPF, "%s", comment_buf->data);
1767
1768 if (seclabel_buf->data[0] != '\0')
1769 fprintf(OPF, "%s", seclabel_buf->data);
1770 }
1771 else
1772 {
1773 char *tag = psprintf("TABLESPACE %s", fmtId(fspcname));
1774
1776 nilCatalogId, /* catalog ID */
1777 createDumpId(), /* dump ID */
1778 ARCHIVE_OPTS(.tag = tag,
1779 .description = "TABLESPACE",
1780 .section = SECTION_PRE_DATA,
1781 .createStmt = buf->data));
1782
1783 if (comment_buf->data[0] != '\0')
1785 nilCatalogId, /* catalog ID */
1786 createDumpId(), /* dump ID */
1787 ARCHIVE_OPTS(.tag = tag,
1788 .description = "COMMENT",
1789 .section = SECTION_PRE_DATA,
1790 .createStmt = comment_buf->data));
1791
1792 if (seclabel_buf->data[0] != '\0')
1794 nilCatalogId, /* catalog ID */
1795 createDumpId(), /* dump ID */
1796 ARCHIVE_OPTS(.tag = tag,
1797 .description = "SECURITY LABEL",
1798 .section = SECTION_PRE_DATA,
1799 .createStmt = seclabel_buf->data));
1800 }
1801
1802 free(fspcname);
1804 }
1805
1806 PQclear(res);
1809
1810 if (archDumpFormat == archNull)
1811 fprintf(OPF, "\n\n");
1812}
1813
1814
1815/*
1816 * Dump commands to drop each database.
1817 */
1818static void
1820{
1821 PGresult *res;
1822 int i;
1823
1824 /*
1825 * Skip databases marked not datallowconn, since we'd be unable to connect
1826 * to them anyway. This must agree with dumpDatabases().
1827 */
1828 res = executeQuery(conn,
1829 "SELECT datname "
1830 "FROM pg_database d "
1831 "WHERE datallowconn AND datconnlimit != -2 "
1832 "ORDER BY datname");
1833
1834 if (PQntuples(res) > 0 && archDumpFormat == archNull)
1835 fprintf(OPF, "--\n-- Drop databases (except postgres and template1)\n--\n\n");
1836
1837 for (i = 0; i < PQntuples(res); i++)
1838 {
1839 char *dbname = PQgetvalue(res, i, 0);
1840
1841 /*
1842 * Skip "postgres" and "template1"; dumpDatabases() will deal with
1843 * them specially. Also, be sure to skip "template0", even if for
1844 * some reason it's not marked !datallowconn.
1845 */
1846 if (strcmp(dbname, "template1") != 0 &&
1847 strcmp(dbname, "template0") != 0 &&
1848 strcmp(dbname, "postgres") != 0)
1849 {
1850 if (archDumpFormat == archNull)
1851 {
1852 fprintf(OPF, "DROP DATABASE %s%s;\n",
1853 if_exists ? "IF EXISTS " : "",
1854 fmtId(dbname));
1855 }
1856 else
1857 {
1858 char *stmt = psprintf("DROP DATABASE IF EXISTS %s;\n",
1859 fmtId(dbname));
1860
1862 nilCatalogId, /* catalog ID */
1863 createDumpId(), /* dump ID */
1864 ARCHIVE_OPTS(.tag = psprintf("DATABASE %s", fmtId(dbname)),
1865 .description = "DROP_GLOBAL",
1866 .section = SECTION_PRE_DATA,
1867 .createStmt = stmt));
1868 pg_free(stmt);
1869 }
1870 }
1871 }
1872
1873 PQclear(res);
1874
1875 if (archDumpFormat == archNull)
1876 fprintf(OPF, "\n\n");
1877}
1878
1879
1880/*
1881 * Dump user-specific configuration
1882 */
1883static void
1885{
1887 PGresult *res;
1888
1889 printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
1890 "WHERE setdatabase = 0 AND setrole = "
1891 "(SELECT oid FROM %s WHERE rolname = ",
1892 role_catalog);
1895
1896 res = executeQuery(conn, buf->data);
1897
1898 if (PQntuples(res) > 0 && archDumpFormat == archNull)
1899 {
1900 char *sanitized;
1901
1903 fprintf(OPF, "\n--\n-- User Config \"%s\"\n--\n\n", sanitized);
1904 free(sanitized);
1905 }
1906
1907 for (int i = 0; i < PQntuples(res); i++)
1908 {
1911 "ROLE", username, NULL, NULL,
1912 buf);
1913
1914 if (archDumpFormat == archNull)
1915 fprintf(OPF, "%s", buf->data);
1916 else
1918 nilCatalogId, /* catalog ID */
1919 createDumpId(), /* dump ID */
1920 ARCHIVE_OPTS(.tag = psprintf("ROLE %s", fmtId(username)),
1921 .description = "ROLE PROPERTIES",
1922 .section = SECTION_PRE_DATA,
1923 .createStmt = buf->data));
1924 }
1925
1926 PQclear(res);
1927
1929}
1930
1931/*
1932 * Find a list of database names that match the given patterns.
1933 * See also expand_table_name_patterns() in pg_dump.c
1934 */
1935static void
1938 SimpleStringList *names)
1939{
1940 PQExpBuffer query;
1941 PGresult *res;
1942
1943 if (patterns->head == NULL)
1944 return; /* nothing to do */
1945
1946 query = createPQExpBuffer();
1947
1948 /*
1949 * The loop below runs multiple SELECTs, which might sometimes result in
1950 * duplicate entries in the name list, but we don't care, since all we're
1951 * going to do is test membership of the list.
1952 */
1953
1954 for (SimpleStringListCell *cell = patterns->head; cell; cell = cell->next)
1955 {
1956 int dotcnt;
1957
1959 "SELECT datname FROM pg_catalog.pg_database n\n");
1960 processSQLNamePattern(conn, query, cell->val, false,
1961 false, NULL, "datname", NULL, NULL, NULL,
1962 &dotcnt);
1963
1964 if (dotcnt > 0)
1965 {
1966 pg_log_error("improper qualified name (too many dotted names): %s",
1967 cell->val);
1968 PQfinish(conn);
1969 exit_nicely(1);
1970 }
1971
1972 res = executeQuery(conn, query->data);
1973 for (int i = 0; i < PQntuples(res); i++)
1974 {
1975 simple_string_list_append(names, PQgetvalue(res, i, 0));
1976 }
1977
1978 PQclear(res);
1979 resetPQExpBuffer(query);
1980 }
1981
1982 destroyPQExpBuffer(query);
1983}
1984
1985/*
1986 * Dump contents of databases.
1987 */
1988static void
1990{
1991 PGresult *res;
1992 int i;
1993 char db_subdir[MAXPGPATH];
1994 char dbfilepath[MAXPGPATH];
1995 FILE *map_file = NULL;
1996
1997 /*
1998 * Skip databases marked not datallowconn, since we'd be unable to connect
1999 * to them anyway. This must agree with dropDBs().
2000 *
2001 * We arrange for template1 to be processed first, then we process other
2002 * DBs in alphabetical order. If we just did them all alphabetically, we
2003 * might find ourselves trying to drop the "postgres" database while still
2004 * connected to it. This makes trying to run the restore script while
2005 * connected to "template1" a bad idea, but there's no fixed order that
2006 * doesn't have some failure mode with --clean.
2007 */
2008 res = executeQuery(conn,
2009 "SELECT datname, oid "
2010 "FROM pg_database d "
2011 "WHERE datallowconn AND datconnlimit != -2 "
2012 "ORDER BY (datname <> 'template1'), datname");
2013
2014 if (PQntuples(res) > 0 && archDumpFormat == archNull)
2015 fprintf(OPF, "--\n-- Databases\n--\n\n");
2016
2017 /*
2018 * If directory/tar/custom format is specified, create a subdirectory
2019 * under the main directory and each database dump file or subdirectory
2020 * will be created in that subdirectory by pg_dump.
2021 */
2022 if (archDumpFormat != archNull)
2023 {
2025
2026 snprintf(db_subdir, MAXPGPATH, "%s/databases", filename);
2027
2028 /* Create a subdirectory with 'databases' name under main directory. */
2030 pg_fatal("could not create directory \"%s\": %m", db_subdir);
2031
2032 snprintf(map_file_path, MAXPGPATH, "%s/map.dat", filename);
2033
2034 /* Create a map file (to store dboid and dbname) */
2036 if (!map_file)
2037 pg_fatal("could not open file \"%s\": %m", map_file_path);
2038
2040 "#################################################################\n"
2041 "# map.dat\n"
2042 "#\n"
2043 "# This file maps oids to database names\n"
2044 "#\n"
2045 "# pg_restore will restore all the databases listed here, unless\n"
2046 "# otherwise excluded. You can also inhibit restoration of a\n"
2047 "# database by removing the line or commenting out the line with\n"
2048 "# a # mark.\n"
2049 "#################################################################\n");
2050 }
2051
2052 for (i = 0; i < PQntuples(res); i++)
2053 {
2054 char *dbname = PQgetvalue(res, i, 0);
2055 char *sanitized;
2056 char *oid = PQgetvalue(res, i, 1);
2057 const char *create_opts = "";
2058 int ret;
2059
2060 /* Skip template0, even if it's not marked !datallowconn. */
2061 if (strcmp(dbname, "template0") == 0)
2062 continue;
2063
2064 /* Skip any explicitly excluded database */
2066 {
2067 pg_log_info("excluding database \"%s\"", dbname);
2068 continue;
2069 }
2070
2071 pg_log_info("dumping database \"%s\"", dbname);
2072
2074
2075 if (archDumpFormat == archNull)
2076 fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", sanitized);
2077
2078 free(sanitized);
2079
2080 /*
2081 * We assume that "template1" and "postgres" already exist in the
2082 * target installation. dropDBs() won't have removed them, for fear
2083 * of removing the DB the restore script is initially connected to. If
2084 * --clean was specified, tell pg_dump to drop and recreate them;
2085 * otherwise we'll merely restore their contents. Other databases
2086 * should simply be created.
2087 */
2088 if (strcmp(dbname, "template1") == 0 || strcmp(dbname, "postgres") == 0)
2089 {
2090 if (output_clean)
2091 create_opts = "--clean --create";
2092 /* Since pg_dump won't emit a \connect command, we must */
2093 else if (archDumpFormat == archNull)
2094 fprintf(OPF, "\\connect %s\n\n", dbname);
2095 else
2096 create_opts = "";
2097 }
2098 else
2099 create_opts = "--create";
2100
2102 fclose(OPF);
2103
2104 /*
2105 * If this is not a plain format dump, then append dboid and dbname to
2106 * the map.dat file.
2107 */
2108 if (archDumpFormat != archNull)
2109 {
2111 snprintf(dbfilepath, MAXPGPATH, "\"%s\"/\"%s\".dmp", db_subdir, oid);
2112 else if (archDumpFormat == archTar)
2113 snprintf(dbfilepath, MAXPGPATH, "\"%s\"/\"%s\".tar", db_subdir, oid);
2114 else
2115 snprintf(dbfilepath, MAXPGPATH, "\"%s\"/\"%s\"", db_subdir, oid);
2116
2117 /* Put one line entry for dboid and dbname in map file. */
2118 fprintf(map_file, "%s %s\n", oid, dbname);
2119 }
2120
2122 if (ret != 0)
2123 pg_fatal("pg_dump failed on database \"%s\", exiting", dbname);
2124
2126 {
2128 if (!OPF)
2129 pg_fatal("could not re-open the output file \"%s\": %m",
2130 filename);
2131 }
2132 }
2133
2134 /* Close map file */
2135 if (archDumpFormat != archNull)
2137
2138 PQclear(res);
2139}
2140
2141
2142
2143/*
2144 * Run pg_dump on dbname, with specified options.
2145 */
2146static int
2147runPgDump(const char *dbname, const char *create_opts, char *dbfile)
2148{
2150 PQExpBufferData cmd;
2151 int ret;
2152
2154 initPQExpBuffer(&cmd);
2155
2156 /*
2157 * If this is not a plain format dump, then append file name and dump
2158 * format to the pg_dump command to get archive dump.
2159 */
2160 if (archDumpFormat != archNull)
2161 {
2162 printfPQExpBuffer(&cmd, "\"%s\" %s -f %s %s", pg_dump_bin,
2164
2166 appendPQExpBufferStr(&cmd, " --format=directory ");
2167 else if (archDumpFormat == archCustom)
2168 appendPQExpBufferStr(&cmd, " --format=custom ");
2169 else if (archDumpFormat == archTar)
2170 appendPQExpBufferStr(&cmd, " --format=tar ");
2171 }
2172 else
2173 {
2174 printfPQExpBuffer(&cmd, "\"%s\" %s %s", pg_dump_bin,
2176
2177 /*
2178 * If we have a filename, use the undocumented plain-append pg_dump
2179 * format.
2180 */
2181 if (filename)
2182 appendPQExpBufferStr(&cmd, " -Fa ");
2183 else
2184 appendPQExpBufferStr(&cmd, " -Fp ");
2185 }
2186
2187 /*
2188 * Append the database name to the already-constructed stem of connection
2189 * string.
2190 */
2191 appendPQExpBuffer(&connstrbuf, "%s dbname=", connstr);
2193
2195
2196 pg_log_info("running \"%s\"", cmd.data);
2197
2198 fflush(NULL);
2199
2200 ret = system(cmd.data);
2201
2202 termPQExpBuffer(&cmd);
2204
2205 return ret;
2206}
2207
2208/*
2209 * buildShSecLabels
2210 *
2211 * Build SECURITY LABEL command(s) for a shared object
2212 *
2213 * The caller has to provide object type and identity in two separate formats:
2214 * catalog_name (e.g., "pg_database") and object OID, as well as
2215 * type name (e.g., "DATABASE") and object name (not pre-quoted).
2216 *
2217 * The command(s) are appended to "buffer".
2218 */
2219static void
2221 const char *objtype, const char *objname,
2222 PQExpBuffer buffer)
2223{
2225 PGresult *res;
2226
2227 buildShSecLabelQuery(catalog_name, objectId, sql);
2228 res = executeQuery(conn, sql->data);
2229 emitShSecLabels(conn, res, buffer, objtype, objname);
2230
2231 PQclear(res);
2232 destroyPQExpBuffer(sql);
2233}
2234
2235/*
2236 * As above for a SQL command (which returns nothing).
2237 */
2238static void
2239executeCommand(PGconn *conn, const char *query)
2240{
2241 PGresult *res;
2242
2243 pg_log_info("executing %s", query);
2244
2245 res = PQexec(conn, query);
2246 if (!res ||
2248 {
2249 pg_log_error("query failed: %s", PQerrorMessage(conn));
2250 pg_log_error_detail("Query was: %s", query);
2251 PQfinish(conn);
2252 exit_nicely(1);
2253 }
2254
2255 PQclear(res);
2256}
2257
2258
2259/*
2260 * check_for_invalid_global_names
2261 *
2262 * Check that no database, role, or tablespace name contains a newline or
2263 * carriage return character. Such characters in database names would break
2264 * the map.dat file format used for non-plain-text dumps. Role and tablespace
2265 * names are also checked because such characters were forbidden starting in
2266 * v19.
2267 *
2268 * Excluded databases are skipped since they won't appear in map.dat.
2269 */
2270static void
2273{
2274 PGresult *res;
2275 int i;
2276 PQExpBuffer names;
2277 int count = 0;
2278
2279 res = executeQuery(conn,
2280 "SELECT datname AS objname, 'database' AS objtype "
2281 "FROM pg_catalog.pg_database "
2282 "WHERE datallowconn AND datconnlimit != -2 "
2283 "UNION ALL "
2284 "SELECT rolname AS objname, 'role' AS objtype "
2285 "FROM pg_catalog.pg_roles "
2286 "UNION ALL "
2287 "SELECT spcname AS objname, 'tablespace' AS objtype "
2288 "FROM pg_catalog.pg_tablespace");
2289
2290 names = createPQExpBuffer();
2291
2292 for (i = 0; i < PQntuples(res); i++)
2293 {
2294 char *objname = PQgetvalue(res, i, 0);
2295 char *objtype = PQgetvalue(res, i, 1);
2296
2297 /* Skip excluded databases since they won't be in map.dat */
2298 if (strcmp(objtype, "database") == 0 &&
2300 continue;
2301
2302 if (strpbrk(objname, "\n\r"))
2303 {
2304 appendPQExpBuffer(names, " %s: \"", objtype);
2305 for (char *p = objname; *p; p++)
2306 {
2307 if (*p == '\n')
2308 appendPQExpBufferStr(names, "\\n");
2309 else if (*p == '\r')
2310 appendPQExpBufferStr(names, "\\r");
2311 else
2312 appendPQExpBufferChar(names, *p);
2313 }
2314 appendPQExpBufferStr(names, "\"\n");
2315 count++;
2316 }
2317 }
2318
2319 PQclear(res);
2320
2321 if (count > 0)
2322 pg_fatal("database, role, or tablespace names contain a newline or carriage return character, which is not supported in non-plain-text dumps:\n%s",
2323 names->data);
2324
2325 destroyPQExpBuffer(names);
2326}
2327
2328
2329/*
2330 * dumpTimestamp
2331 */
2332static void
2333dumpTimestamp(const char *msg)
2334{
2335 char buf[64];
2336 time_t now = time(NULL);
2337
2338 if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&now)) != 0)
2339 fprintf(OPF, "-- %s %s\n\n", msg, buf);
2340}
2341
2342/*
2343 * read_dumpall_filters - retrieve database identifier patterns from file
2344 *
2345 * Parse the specified filter file for include and exclude patterns, and add
2346 * them to the relevant lists. If the filename is "-" then filters will be
2347 * read from STDIN rather than a file.
2348 *
2349 * At the moment, the only allowed filter is for database exclusion.
2350 */
2351static void
2353{
2355 char *objname;
2357 FilterObjectType objtype;
2358
2360
2361 while (filter_read_item(&fstate, &objname, &comtype, &objtype))
2362 {
2364 {
2365 pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
2366 "include",
2367 filter_object_type_name(objtype));
2368 exit_nicely(1);
2369 }
2370
2371 switch (objtype)
2372 {
2374 break;
2385 pg_log_filter_error(&fstate, _("unsupported filter object"));
2386 exit_nicely(1);
2387 break;
2388
2390 simple_string_list_append(pattern, objname);
2391 break;
2392 }
2393
2394 if (objname)
2395 free(objname);
2396 }
2397
2399}
2400
2401/*
2402 * parseDumpFormat
2403 *
2404 * This will validate dump formats.
2405 */
2406static ArchiveFormat
2408{
2410
2411 if (pg_strcasecmp(format, "c") == 0)
2413 else if (pg_strcasecmp(format, "custom") == 0)
2415 else if (pg_strcasecmp(format, "d") == 0)
2417 else if (pg_strcasecmp(format, "directory") == 0)
2419 else if (pg_strcasecmp(format, "p") == 0)
2421 else if (pg_strcasecmp(format, "plain") == 0)
2423 else if (pg_strcasecmp(format, "t") == 0)
2425 else if (pg_strcasecmp(format, "tar") == 0)
2427 else
2428 pg_fatal("unrecognized output format \"%s\"; please specify \"c\", \"d\", \"p\", or \"t\"",
2429 format);
2430
2431 return archDumpFormat;
2432}
2433
2434/*
2435 * createDumpId
2436 *
2437 * Return the next dumpId.
2438 */
2439static int
2441{
2442 return ++dumpIdVal;
2443}
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition acl.c:827
void set_option(char *arg)
Definition args.c:261
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1600
void on_exit_close_archive(Archive *AHX)
Definition parallel.c:330
#define PG_BINARY_A
Definition c.h:1377
#define Assert(condition)
Definition c.h:945
#define PG_TEXTDOMAIN(domain)
Definition c.h:1305
#define CppAsString2(x)
Definition c.h:500
uint32_t uint32
Definition c.h:618
#define PG_BINARY_W
Definition c.h:1379
int find_my_exec(const char *argv0, char *retpath)
Definition exec.c:161
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition exec.c:430
int find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath)
Definition exec.c:311
int main(void)
PGresult * executeQuery(PGconn *conn, const char *query)
Definition connectdb.c:278
PGconn * ConnectDatabase(const char *dbname, const char *connection_string, const char *pghost, const char *pgport, const char *pguser, trivalue prompt_password, bool fail_on_error, const char *progname, const char **connstr, int *server_version, char *password, char *override_dbname)
Definition connectdb.c:40
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
char * generate_restrict_key(void)
Definition dumputils.c:976
bool buildACLCommands(const char *name, const char *subname, const char *nspname, const char *type, const char *acls, const char *baseacls, const char *owner, const char *prefix, int remoteVersion, PQExpBuffer sql)
Definition dumputils.c:104
bool valid_restrict_key(const char *restrict_key)
Definition dumputils.c:1000
void buildShSecLabelQuery(const char *catalog_name, Oid objectId, PQExpBuffer sql)
Definition dumputils.c:681
void makeAlterConfigCommand(PGconn *conn, const char *configitem, const char *type, const char *name, const char *type2, const char *name2, PQExpBuffer buf)
Definition dumputils.c:868
char * sanitize_line(const char *str, bool want_hyphen)
Definition dumputils.c:52
void create_or_open_dir(const char *dirname)
Definition dumputils.c:943
void emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, const char *objtype, const char *objname)
Definition dumputils.c:699
#define PGDUMP_STRFTIME_FMT
Definition dumputils.h:34
#define _(x)
Definition elog.c:95
void fsync_fname(const char *fname, bool isdir)
Definition fd.c:757
int PQclientEncoding(const PGconn *conn)
void PQfinish(PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
int PQsetClientEncoding(PGconn *conn, const char *encoding)
int PQfnumber(const PGresult *res, const char *field_name)
Definition fe-exec.c:3606
PGresult * PQexec(PGconn *conn, const char *query)
Definition fe-exec.c:2279
char * pg_strdup(const char *in)
Definition fe_memutils.c:85
void pg_free(void *ptr)
#define pg_malloc0_array(type, count)
Definition fe_memutils.h:57
int pg_dir_create_mode
Definition file_perm.c:18
@ DATA_DIR_SYNC_METHOD_FSYNC
Definition file_utils.h:29
void filter_init(FilterStateData *fstate, const char *filename, exit_function f_exit)
Definition filter.c:36
void filter_free(FilterStateData *fstate)
Definition filter.c:60
const char * filter_object_type_name(FilterObjectType fot)
Definition filter.c:82
bool filter_read_item(FilterStateData *fstate, char **objname, FilterCommandType *comtype, FilterObjectType *objtype)
Definition filter.c:392
void pg_log_filter_error(FilterStateData *fstate, const char *fmt,...)
Definition filter.c:154
FilterObjectType
Definition filter.h:48
@ FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN
Definition filter.h:51
@ FILTER_OBJECT_TYPE_SCHEMA
Definition filter.h:57
@ FILTER_OBJECT_TYPE_INDEX
Definition filter.h:56
@ FILTER_OBJECT_TYPE_TRIGGER
Definition filter.h:60
@ FILTER_OBJECT_TYPE_FOREIGN_DATA
Definition filter.h:54
@ FILTER_OBJECT_TYPE_DATABASE
Definition filter.h:52
@ FILTER_OBJECT_TYPE_FUNCTION
Definition filter.h:55
@ FILTER_OBJECT_TYPE_TABLE_DATA
Definition filter.h:50
@ FILTER_OBJECT_TYPE_NONE
Definition filter.h:49
@ FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN
Definition filter.h:59
@ FILTER_OBJECT_TYPE_EXTENSION
Definition filter.h:53
@ FILTER_OBJECT_TYPE_TABLE
Definition filter.h:58
FilterCommandType
Definition filter.h:38
@ FILTER_COMMAND_TYPE_INCLUDE
Definition filter.h:40
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition getopt_long.c:60
#define no_argument
Definition getopt_long.h:25
#define required_argument
Definition getopt_long.h:26
return str start
#define stmt
int remaining
Definition informix.c:692
static char * username
Definition initdb.c:153
static char * encoding
Definition initdb.c:139
int i
Definition isn.c:77
#define PQgetvalue
#define PQclear
#define PQresultStatus
#define PQgetisnull
#define PQntuples
@ PGRES_COMMAND_OK
Definition libpq-fe.h:131
void pg_logging_increase_verbosity(void)
Definition logging.c:185
void pg_logging_init(const char *argv0)
Definition logging.c:83
void pg_logging_set_level(enum pg_log_level new_level)
Definition logging.c:176
#define pg_log_error(...)
Definition logging.h:106
#define pg_log_error_hint(...)
Definition logging.h:112
#define pg_log_info(...)
Definition logging.h:124
@ PG_LOG_WARNING
Definition logging.h:38
#define pg_log_warning_detail(...)
Definition logging.h:118
#define pg_log_error_detail(...)
Definition logging.h:109
const char * progname
Definition main.c:44
#define check_mut_excl_opts(set, opt,...)
@ SECTION_PRE_DATA
Definition pg_backup.h:58
void ProcessArchiveRestoreOptions(Archive *AHX)
RestoreOptions * NewRestoreOptions(void)
#define appendStringLiteralAH(buf, str, AH)
Definition pg_backup.h:344
enum _archiveFormat ArchiveFormat
void CloseArchive(Archive *AHX)
Archive * CreateArchive(const char *FileSpec, const ArchiveFormat fmt, const pg_compress_specification compression_spec, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupDumpWorker, DataDirSyncMethod sync_method)
@ archModeWrite
Definition pg_backup.h:51
void SetArchiveOptions(Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
@ archTar
Definition pg_backup.h:43
@ archCustom
Definition pg_backup.h:42
@ archDirectory
Definition pg_backup.h:45
@ archNull
Definition pg_backup.h:44
void InitDumpOptions(DumpOptions *opts)
TocEntry * ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId, ArchiveOpts *opts)
#define ARCHIVE_OPTS(...)
void exit_nicely(int code)
#define pg_fatal(...)
static char format
#define MAXPGPATH
static void dumpTimestamp(const char *msg)
static const CatalogId nilCatalogId
Definition pg_dumpall.c:142
static int if_exists
Definition pg_dumpall.c:105
static int on_conflict_do_nothing
Definition pg_dumpall.c:124
static ArchiveFormat archDumpFormat
Definition pg_dumpall.c:141
static void dropTablespaces(PGconn *conn)
static void expand_dbname_patterns(PGconn *conn, SimpleStringList *patterns, SimpleStringList *names)
static int no_role_passwords
Definition pg_dumpall.c:120
static PQExpBuffer pgdumpopts
Definition pg_dumpall.c:94
static int statistics_only
Definition pg_dumpall.c:125
static int no_table_access_method
Definition pg_dumpall.c:107
static int no_unlogged_table_data
Definition pg_dumpall.c:119
static void check_for_invalid_global_names(PGconn *conn, SimpleStringList *database_exclude_names)
#define PG_AUTHID
Definition pg_dumpall.c:129
static int no_policies
Definition pg_dumpall.c:111
static int binary_upgrade
Definition pg_dumpall.c:101
static int disable_triggers
Definition pg_dumpall.c:104
static void dumpUserConfig(PGconn *conn, const char *username)
static bool dosync
Definition pg_dumpall.c:99
static const char * connstr
Definition pg_dumpall.c:95
static SimpleStringList database_exclude_patterns
Definition pg_dumpall.c:135
static void dumpTablespaces(PGconn *conn)
static void dumpRoleMembership(PGconn *conn)
static int createDumpId(void)
static char pg_dump_bin[MAXPGPATH]
Definition pg_dumpall.c:93
static int runPgDump(const char *dbname, const char *create_opts, char *dbfile)
static SimpleStringList database_exclude_names
Definition pg_dumpall.c:136
static FILE * OPF
Definition pg_dumpall.c:132
static int no_comments
Definition pg_dumpall.c:110
static int no_publications
Definition pg_dumpall.c:112
static int sequence_data
Definition pg_dumpall.c:126
static char * restrict_key
Definition pg_dumpall.c:138
static int no_security_labels
Definition pg_dumpall.c:113
static void dumpDatabases(PGconn *conn)
static Archive * fout
Definition pg_dumpall.c:139
static ArchiveFormat parseDumpFormat(const char *format)
static int disable_dollar_quoting
Definition pg_dumpall.c:103
static void buildShSecLabels(PGconn *conn, const char *catalog_name, Oid objectId, const char *objtype, const char *objname, PQExpBuffer buffer)
static int no_tablespaces
Definition pg_dumpall.c:108
static int no_toast_compression
Definition pg_dumpall.c:118
#define PG_ROLES
Definition pg_dumpall.c:130
static int inserts
Definition pg_dumpall.c:106
static void executeCommand(PGconn *conn, const char *query)
static int dumpIdVal
Definition pg_dumpall.c:140
static bool verbose
Definition pg_dumpall.c:98
static void dumpRoleGUCPrivs(PGconn *conn)
static int no_statistics
Definition pg_dumpall.c:116
static void dumpRoles(PGconn *conn)
static void help(void)
Definition pg_dumpall.c:869
static int use_setsessauth
Definition pg_dumpall.c:109
static int no_data
Definition pg_dumpall.c:114
static int load_via_partition_root
Definition pg_dumpall.c:123
static int column_inserts
Definition pg_dumpall.c:102
static void read_dumpall_filters(const char *filename, SimpleStringList *pattern)
static void dropRoles(PGconn *conn)
Definition pg_dumpall.c:950
static void dropDBs(PGconn *conn)
static int server_version
Definition pg_dumpall.c:122
static char role_catalog[10]
Definition pg_dumpall.c:128
static bool output_clean
Definition pg_dumpall.c:96
static int no_schema
Definition pg_dumpall.c:115
static int no_subscriptions
Definition pg_dumpall.c:117
static char * filename
Definition pg_dumpall.c:133
static int with_statistics
Definition pg_dumpall.c:121
#define PGDUMP_VERSIONSTR
Definition pg_dumpall.c:44
static bool skip_acls
Definition pg_dumpall.c:97
PGDLLIMPORT int optind
Definition getopt.c:51
PGDLLIMPORT char * optarg
Definition getopt.c:53
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define pg_encoding_to_char
Definition pg_wchar.h:630
static const char * pghost
Definition pgbench.c:295
static const char * pgport
Definition pgbench.c:296
#define pg_log_warning(...)
Definition pgfnames.c:24
#define is_absolute_path(filename)
Definition port.h:104
int pg_strcasecmp(const char *s1, const char *s2)
#define sprintf
Definition port.h:262
#define snprintf
Definition port.h:260
const char * get_progname(const char *argv0)
Definition path.c:652
#define printf(...)
Definition port.h:266
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
unsigned int Oid
#define atooid(x)
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition pqexpbuffer.c:72
void initPQExpBuffer(PQExpBuffer str)
Definition pqexpbuffer.c:90
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void termPQExpBuffer(PQExpBuffer str)
char * c
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
bool quote_all_identifiers
Definition ruleutils.c:344
bool simple_string_list_member(SimpleStringList *list, const char *val)
Definition simple_list.c:87
void simple_string_list_append(SimpleStringList *list, const char *val)
Definition simple_list.c:63
#define free(a)
char * dbname
Definition streamutil.c:49
PGconn * conn
Definition streamutil.c:52
const char * fmtId(const char *rawid)
void setFmtEncoding(int encoding)
void appendShellString(PQExpBuffer buf, const char *str)
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule, PQExpBuffer dbnamebuf, int *dotcnt)
void appendConnStrVal(PQExpBuffer buf, const char *str)
int minRemoteVersion
Definition pg_backup.h:237
int maxRemoteVersion
Definition pg_backup.h:238
int numWorkers
Definition pg_backup.h:240
int verbose
Definition pg_backup.h:232
uint32 hashval
Definition pg_dumpall.c:49
uint32 status
Definition pg_dumpall.c:48
char * rolename
Definition pg_dumpall.c:50
SimpleStringListCell * head
Definition simple_list.h:42
char * username
Definition pg_backup.h:90
ConnParams cparams
Definition pg_backup.h:173
trivalue
Definition vacuumlo.c:35
@ TRI_YES
Definition vacuumlo.c:38
@ TRI_DEFAULT
Definition vacuumlo.c:36
@ TRI_NO
Definition vacuumlo.c:37
const char * description
#define mkdir(a, b)
Definition win32_port.h:80