2010-05-12 10:19:11 +08:00
|
|
|
/*
|
|
|
|
* dump.c
|
|
|
|
*
|
|
|
|
* dump functions
|
2010-07-03 22:23:14 +08:00
|
|
|
*
|
2012-01-02 07:01:58 +08:00
|
|
|
* Copyright (c) 2010-2012, PostgreSQL Global Development Group
|
2010-09-21 04:08:53 +08:00
|
|
|
* contrib/pg_upgrade/dump.c
|
2010-05-12 10:19:11 +08:00
|
|
|
*/
|
|
|
|
|
2011-08-27 09:16:24 +08:00
|
|
|
#include "postgres.h"
|
|
|
|
|
2010-05-12 10:19:11 +08:00
|
|
|
#include "pg_upgrade.h"
|
|
|
|
|
2012-03-13 07:47:54 +08:00
|
|
|
#include <sys/types.h>
|
2010-05-12 10:19:11 +08:00
|
|
|
|
|
|
|
void
|
2010-10-20 05:38:16 +08:00
|
|
|
generate_old_dump(void)
|
2010-05-12 10:19:11 +08:00
|
|
|
{
|
|
|
|
/* run new pg_dumpall binary */
|
2010-10-20 05:38:16 +08:00
|
|
|
prep_status("Creating catalog dump");
|
2010-05-12 10:19:11 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* --binary-upgrade records the width of dropped columns in pg_class, and
|
|
|
|
* restores the frozenid's for databases and relations.
|
|
|
|
*/
|
2012-08-28 02:21:09 +08:00
|
|
|
exec_prog(UTILITY_LOG_FILE, NULL, true,
|
2012-09-04 01:52:34 +08:00
|
|
|
"\"%s/pg_dumpall\" %s --schema-only --binary-upgrade %s -f %s",
|
|
|
|
new_cluster.bindir, cluster_conn_opts(&old_cluster),
|
2012-03-13 07:47:54 +08:00
|
|
|
log_opts.verbose ? "--verbose" : "",
|
2012-08-28 02:21:09 +08:00
|
|
|
ALL_DUMP_FILE);
|
2010-10-20 05:38:16 +08:00
|
|
|
check_ok();
|
2010-05-12 10:19:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* split_old_dump
|
|
|
|
*
|
|
|
|
* This function splits pg_dumpall output into global values and
|
|
|
|
* database creation, and per-db schemas. This allows us to create
|
2011-01-08 10:59:29 +08:00
|
|
|
* the support functions between restoring these two parts of the
|
2010-05-12 10:19:11 +08:00
|
|
|
* dump. We split on the first "\connect " after a CREATE ROLE
|
|
|
|
* username match; this is where the per-db restore starts.
|
|
|
|
*
|
|
|
|
* We suppress recreation of our own username so we don't generate
|
|
|
|
* an error during restore
|
|
|
|
*/
|
|
|
|
void
|
2010-10-20 05:38:16 +08:00
|
|
|
split_old_dump(void)
|
2010-05-12 10:19:11 +08:00
|
|
|
{
|
|
|
|
FILE *all_dump,
|
|
|
|
*globals_dump,
|
|
|
|
*db_dump;
|
|
|
|
FILE *current_output;
|
|
|
|
char line[LINE_ALLOC];
|
|
|
|
bool start_of_line = true;
|
|
|
|
char create_role_str[MAX_STRING];
|
|
|
|
char create_role_str_quote[MAX_STRING];
|
|
|
|
char filename[MAXPGPATH];
|
|
|
|
bool suppressed_username = false;
|
|
|
|
|
2012-03-13 07:47:54 +08:00
|
|
|
snprintf(filename, sizeof(filename), "%s", ALL_DUMP_FILE);
|
2010-05-12 10:19:11 +08:00
|
|
|
if ((all_dump = fopen(filename, "r")) == NULL)
|
2011-07-12 12:13:51 +08:00
|
|
|
pg_log(PG_FATAL, "Could not open dump file \"%s\": %s\n", filename, getErrorText(errno));
|
2012-03-13 07:47:54 +08:00
|
|
|
snprintf(filename, sizeof(filename), "%s", GLOBALS_DUMP_FILE);
|
|
|
|
if ((globals_dump = fopen_priv(filename, "w")) == NULL)
|
2011-07-12 12:13:51 +08:00
|
|
|
pg_log(PG_FATAL, "Could not write to dump file \"%s\": %s\n", filename, getErrorText(errno));
|
2012-03-13 07:47:54 +08:00
|
|
|
snprintf(filename, sizeof(filename), "%s", DB_DUMP_FILE);
|
|
|
|
if ((db_dump = fopen_priv(filename, "w")) == NULL)
|
2011-07-12 12:13:51 +08:00
|
|
|
pg_log(PG_FATAL, "Could not write to dump file \"%s\": %s\n", filename, getErrorText(errno));
|
2012-03-13 07:47:54 +08:00
|
|
|
|
2010-05-12 10:19:11 +08:00
|
|
|
current_output = globals_dump;
|
|
|
|
|
|
|
|
/* patterns used to prevent our own username from being recreated */
|
|
|
|
snprintf(create_role_str, sizeof(create_role_str),
|
2010-10-20 05:38:16 +08:00
|
|
|
"CREATE ROLE %s;", os_info.user);
|
2010-05-12 10:19:11 +08:00
|
|
|
snprintf(create_role_str_quote, sizeof(create_role_str_quote),
|
2010-10-20 05:38:16 +08:00
|
|
|
"CREATE ROLE %s;", quote_identifier(os_info.user));
|
2010-05-12 10:19:11 +08:00
|
|
|
|
|
|
|
while (fgets(line, sizeof(line), all_dump) != NULL)
|
|
|
|
{
|
|
|
|
/* switch to db_dump file output? */
|
|
|
|
if (current_output == globals_dump && start_of_line &&
|
|
|
|
suppressed_username &&
|
|
|
|
strncmp(line, "\\connect ", strlen("\\connect ")) == 0)
|
|
|
|
current_output = db_dump;
|
|
|
|
|
|
|
|
/* output unless we are recreating our own username */
|
|
|
|
if (current_output != globals_dump || !start_of_line ||
|
|
|
|
(strncmp(line, create_role_str, strlen(create_role_str)) != 0 &&
|
|
|
|
strncmp(line, create_role_str_quote, strlen(create_role_str_quote)) != 0))
|
|
|
|
fputs(line, current_output);
|
|
|
|
else
|
|
|
|
suppressed_username = true;
|
|
|
|
|
|
|
|
if (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
|
|
|
|
start_of_line = true;
|
|
|
|
else
|
|
|
|
start_of_line = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(all_dump);
|
|
|
|
fclose(globals_dump);
|
|
|
|
fclose(db_dump);
|
|
|
|
}
|