📄 pg_dumpall.c
字号:
/*------------------------------------------------------------------------- * * pg_dumpall * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.28.2.1 2004/01/22 19:09:48 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres_fe.h"#include <unistd.h>#ifdef ENABLE_NLS#include <locale.h>#endif#ifndef HAVE_STRDUP#include "strdup.h"#endif#include <errno.h>#include "getopt_long.h"#ifndef HAVE_OPTRESETint optreset;#endif#include "dumputils.h"#include "libpq-fe.h"#include "pg_backup.h"#include "pqexpbuffer.h"#define _(x) gettext((x))static char *progname;static void help(void);static void dumpUsers(PGconn *conn);static void dumpGroups(PGconn *conn);static void dumpCreateDB(PGconn *conn);static void dumpDatabaseConfig(PGconn *conn, const char *dbname);static void dumpUserConfig(PGconn *conn, const char *username);static void makeAlterConfigCommand(const char *arrayitem, const char *type, const char *name);static void dumpDatabases(PGconn *conn);static int runPgDump(const char *dbname);static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport, const char *pguser, bool require_password);static PGresult *executeQuery(PGconn *conn, const char *query);static char *findPgDump(const char *argv0);char *pgdumploc;PQExpBuffer pgdumpopts;bool output_clean = false;bool skip_acls = false;bool verbose = false;int server_version;intmain(int argc, char *argv[]){ char *pghost = NULL; char *pgport = NULL; char *pguser = NULL; bool force_password = false; bool data_only = false; bool globals_only = false; bool schema_only = false; PGconn *conn; int c; static struct option long_options[] = { {"data-only", no_argument, NULL, 'a'}, {"clean", no_argument, NULL, 'c'}, {"inserts", no_argument, NULL, 'd'}, {"attribute-inserts", no_argument, NULL, 'D'}, {"column-inserts", no_argument, NULL, 'D'}, {"globals-only", no_argument, NULL, 'g'}, {"host", required_argument, NULL, 'h'}, {"ignore-version", no_argument, NULL, 'i'}, {"oids", no_argument, NULL, 'o'}, {"port", required_argument, NULL, 'p'}, {"password", no_argument, NULL, 'W'}, {"schema-only", no_argument, NULL, 's'}, {"username", required_argument, NULL, 'U'}, {"verbose", no_argument, NULL, 'v'}, {"no-privileges", no_argument, NULL, 'x'}, {"no-acl", no_argument, NULL, 'x'}, {NULL, 0, NULL, 0} }; int optindex;#ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain("pg_dump", LOCALEDIR); textdomain("pg_dump");#endif progname = get_progname(argv[0]); if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(); exit(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("pg_dumpall (PostgreSQL) " PG_VERSION); exit(0); } } pgdumploc = findPgDump(argv[0]); pgdumpopts = createPQExpBuffer(); while ((c = getopt_long(argc, argv, "acdDgh:iop:sU:vWx", long_options, &optindex)) != -1) { switch (c) { case 'a': data_only = true; appendPQExpBuffer(pgdumpopts, " -a"); break; case 'c': output_clean = true; break; case 'd': case 'D': appendPQExpBuffer(pgdumpopts, " -%c", c); break; case 'g': globals_only = true; break; case 'h': pghost = optarg; appendPQExpBuffer(pgdumpopts, " -h '%s'", pghost); break; case 'i': case 'o': appendPQExpBuffer(pgdumpopts, " -%c", c); break; case 'p': pgport = optarg; appendPQExpBuffer(pgdumpopts, " -p '%s'", pgport); break; case 's': schema_only = true; appendPQExpBuffer(pgdumpopts, " -s"); break; case 'U': pguser = optarg; appendPQExpBuffer(pgdumpopts, " -U '%s'", pguser); break; case 'v': verbose = true; appendPQExpBuffer(pgdumpopts, " -v"); break; case 'W': force_password = true; appendPQExpBuffer(pgdumpopts, " -W"); break; case 'x': skip_acls = true; appendPQExpBuffer(pgdumpopts, " -x"); break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } } if (optind < argc) { fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } conn = connectDatabase("template1", pghost, pgport, pguser, force_password); printf("--\n"); printf("-- PostgreSQL database cluster dump\n"); printf("--\n\n"); printf("\\connect \"template1\"\n\n"); if (!data_only) { dumpUsers(conn); dumpGroups(conn); } if (!globals_only) { if (!data_only) dumpCreateDB(conn); dumpDatabases(conn); } PQfinish(conn); exit(0);}static voidhelp(void){ printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname); printf(_("Usage:\n")); printf(_(" %s [OPTION]...\n"), progname); printf(_("\nOptions:\n")); printf(_(" -a, --data-only dump only the data, not the schema\n")); printf(_(" -c, --clean clean (drop) databases prior to create\n")); printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n")); printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n")); printf(_(" -g, --globals-only dump only global objects, no databases\n")); printf(_(" -i, --ignore-version proceed even when server version mismatches\n" " pg_dumpall version\n")); printf(_(" -s, --schema-only dump only the schema, no data\n")); printf(_(" -o, --oids include OIDs in dump\n")); printf(_(" -v, --verbose verbose mode\n")); printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n")); printf(_(" --help show this help, then exit\n")); printf(_(" --version output version information, then exit\n")); printf(_("\nConnection options:\n")); printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); printf(_(" -p, --port=PORT database server port number\n")); printf(_(" -U, --username=NAME connect as specified database user\n")); printf(_(" -W, --password force password prompt (should happen automatically)\n")); printf(_("\nThe SQL script will be written to the standard output.\n\n")); printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));}/* * Dump users (but not the user created by initdb). */static voiddumpUsers(PGconn *conn){ PGresult *res; int i; printf("--\n-- Users\n--\n\n"); printf("DELETE FROM pg_shadow WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');\n\n"); if (server_version >= 70100) res = executeQuery(conn, "SELECT usename, usesysid, passwd, usecreatedb, " "usesuper, valuntil " "FROM pg_shadow " "WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0')"); else res = executeQuery(conn, "SELECT usename, usesysid, passwd, usecreatedb, " "usesuper, valuntil " "FROM pg_shadow " "WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template1')"); for (i = 0; i < PQntuples(res); i++) { PQExpBuffer buf = createPQExpBuffer(); const char *username; username = PQgetvalue(res, i, 0); appendPQExpBuffer(buf, "CREATE USER %s WITH SYSID %s", fmtId(username), PQgetvalue(res, i, 1)); if (!PQgetisnull(res, i, 2)) { appendPQExpBuffer(buf, " PASSWORD "); appendStringLiteral(buf, PQgetvalue(res, i, 2), true); } if (strcmp(PQgetvalue(res, i, 3), "t") == 0) appendPQExpBuffer(buf, " CREATEDB"); else appendPQExpBuffer(buf, " NOCREATEDB"); if (strcmp(PQgetvalue(res, i, 4), "t") == 0) appendPQExpBuffer(buf, " CREATEUSER"); else appendPQExpBuffer(buf, " NOCREATEUSER"); if (!PQgetisnull(res, i, 5)) appendPQExpBuffer(buf, " VALID UNTIL '%s'", PQgetvalue(res, i, 5)); appendPQExpBuffer(buf, ";\n"); printf("%s", buf->data); destroyPQExpBuffer(buf); if (server_version >= 70300) dumpUserConfig(conn, username); } PQclear(res); printf("\n\n");}/* * Dump groups. */static voiddumpGroups(PGconn *conn){ PGresult *res; int i; printf("--\n-- Groups\n--\n\n"); printf("DELETE FROM pg_group;\n\n"); res = executeQuery(conn, "SELECT groname, grosysid, grolist FROM pg_group"); for (i = 0; i < PQntuples(res); i++) { PQExpBuffer buf = createPQExpBuffer(); char *val; char *tok; appendPQExpBuffer(buf, "CREATE GROUP %s WITH SYSID %s;\n", fmtId(PQgetvalue(res, i, 0)), PQgetvalue(res, i, 1)); val = strdup(PQgetvalue(res, i, 2)); tok = strtok(val, ",{}"); while (tok) { PGresult *res2; PQExpBuffer buf2 = createPQExpBuffer(); int j; appendPQExpBuffer(buf2, "SELECT usename FROM pg_shadow WHERE usesysid = %s;", tok); res2 = executeQuery(conn, buf2->data); destroyPQExpBuffer(buf2); for (j = 0; j < PQntuples(res2); j++) { appendPQExpBuffer(buf, "ALTER GROUP %s ", fmtId(PQgetvalue(res, i, 0))); appendPQExpBuffer(buf, "ADD USER %s;\n", fmtId(PQgetvalue(res2, j, 0))); } PQclear(res2); tok = strtok(NULL, "{},"); } free(val); printf("%s", buf->data); destroyPQExpBuffer(buf); } PQclear(res); printf("\n\n");}/* * Dump commands to create each database. * * To minimize the number of reconnections (and possibly ensuing * password prompts) required by the output script, we emit all CREATE * DATABASE commands during the initial phase of the script, and then * run pg_dump for each database to dump the contents of that * database. We skip databases marked not datallowconn, since we'd be * unable to connect to them anyway (and besides, we don't want to * dump template0). */static voiddumpCreateDB(PGconn *conn){ PGresult *res; int i; printf("--\n-- Database creation\n--\n\n"); if (server_version >= 70300) res = executeQuery(conn, "SELECT datname, " "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), " "pg_encoding_to_char(d.encoding), " "datistemplate, datpath, datacl " "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) " "WHERE datallowconn ORDER BY 1"); else if (server_version >= 70100) res = executeQuery(conn, "SELECT datname, "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -