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