pg_upgrade.diff
text/x-diff
Filename: pg_upgrade.diff
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| contrib/pg_upgrade/check.c | 0 | 0 |
| contrib/pg_upgrade/dump.c | 0 | 0 |
| contrib/pg_upgrade/exec.c | 0 | 0 |
| contrib/pg_upgrade/pg_upgrade.c | 0 | 0 |
| contrib/pg_upgrade/pg_upgrade.h | 0 | 0 |
| contrib/pg_upgrade/relfilenode.c | 0 | 0 |
| contrib/pg_upgrade/util.c | 0 | 0 |
| src/bin/pg_dump/pg_dumpall.c | 0 | 0 |
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
new file mode 100644
index 285f10c..bccceb1
*** a/contrib/pg_upgrade/check.c
--- b/contrib/pg_upgrade/check.c
*************** output_check_banner(bool *live_check)
*** 72,78 ****
void
! check_old_cluster(bool live_check, char **sequence_script_file_name)
{
/* -- OLD -- */
--- 72,78 ----
void
! check_and_dump_old_cluster(bool live_check, char **sequence_script_file_name)
{
/* -- OLD -- */
*************** check_old_cluster(bool live_check, char
*** 131,140 ****
* the old server is running.
*/
if (!user_opts.check)
- {
generate_old_dump();
- split_old_dump();
- }
if (!live_check)
stop_postmaster(false);
--- 131,137 ----
diff --git a/contrib/pg_upgrade/dump.c b/contrib/pg_upgrade/dump.c
new file mode 100644
index 577ccac..d206e98
*** a/contrib/pg_upgrade/dump.c
--- b/contrib/pg_upgrade/dump.c
***************
*** 16,110 ****
void
generate_old_dump(void)
{
! /* run new pg_dumpall binary */
! prep_status("Creating catalog dump");
! /*
! * --binary-upgrade records the width of dropped columns in pg_class, and
! * restores the frozenid's for databases and relations.
! */
exec_prog(UTILITY_LOG_FILE, NULL, true,
! "\"%s/pg_dumpall\" %s --schema-only --binary-upgrade %s -f %s",
new_cluster.bindir, cluster_conn_opts(&old_cluster),
log_opts.verbose ? "--verbose" : "",
! ALL_DUMP_FILE);
! check_ok();
! }
!
!
! /*
! * split_old_dump
! *
! * This function splits pg_dumpall output into global values and
! * database creation, and per-db schemas. This allows us to create
! * the support functions between restoring these two parts of the
! * 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
! split_old_dump(void)
! {
! 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;
!
!
! /*
! * Open all files in binary mode to avoid line end translation on Windows,
! * both for input and output.
! */
!
! snprintf(filename, sizeof(filename), "%s", ALL_DUMP_FILE);
! if ((all_dump = fopen(filename, PG_BINARY_R)) == NULL)
! pg_log(PG_FATAL, "Could not open dump file \"%s\": %s\n", filename, getErrorText(errno));
! snprintf(filename, sizeof(filename), "%s", GLOBALS_DUMP_FILE);
! if ((globals_dump = fopen_priv(filename, PG_BINARY_W)) == NULL)
! pg_log(PG_FATAL, "Could not write to dump file \"%s\": %s\n", filename, getErrorText(errno));
! snprintf(filename, sizeof(filename), "%s", DB_DUMP_FILE);
! if ((db_dump = fopen_priv(filename, PG_BINARY_W)) == NULL)
! pg_log(PG_FATAL, "Could not write to dump file \"%s\": %s\n", filename, getErrorText(errno));
!
! current_output = globals_dump;
!
! /* patterns used to prevent our own username from being recreated */
! snprintf(create_role_str, sizeof(create_role_str),
! "CREATE ROLE %s;", os_info.user);
! snprintf(create_role_str_quote, sizeof(create_role_str_quote),
! "CREATE ROLE %s;", quote_identifier(os_info.user));
! 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);
}
--- 16,49 ----
void
generate_old_dump(void)
{
! int dbnum;
! prep_status("Creating catalog dump\n");
!
! pg_log(PG_REPORT, OVERWRITE_MESSAGE, "global objects");
!
! /* run new pg_dumpall binary for globals */
exec_prog(UTILITY_LOG_FILE, NULL, true,
! "\"%s/pg_dumpall\" %s --schema-only --globals-only --binary-upgrade %s -f %s",
new_cluster.bindir, cluster_conn_opts(&old_cluster),
log_opts.verbose ? "--verbose" : "",
! GLOBALS_DUMP_FILE);
! /* create per-db dump files */
! for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
{
! char file_name[MAXPGPATH];
! DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
! pg_log(PG_REPORT, OVERWRITE_MESSAGE, old_db->db_name);
! snprintf(file_name, sizeof(file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
! exec_prog(RESTORE_LOG_FILE, NULL, true,
! "\"%s/pg_dump\" %s --schema-only --binary-upgrade --format=custom %s --file=\"%s\" \"%s\"",
! new_cluster.bindir, cluster_conn_opts(&old_cluster),
! log_opts.verbose ? "--verbose" : "", file_name, old_db->db_name);
}
! end_progress_output();
! check_ok();
}
diff --git a/contrib/pg_upgrade/exec.c b/contrib/pg_upgrade/exec.c
new file mode 100644
index 76247fd..35de541
*** a/contrib/pg_upgrade/exec.c
--- b/contrib/pg_upgrade/exec.c
*************** exec_prog(const char *log_file, const ch
*** 104,111 ****
if (result != 0)
{
! report_status(PG_REPORT, "*failure*");
fflush(stdout);
pg_log(PG_VERBOSE, "There were problems executing \"%s\"\n", cmd);
if (opt_log_file)
pg_log(throw_error ? PG_FATAL : PG_REPORT,
--- 104,113 ----
if (result != 0)
{
! /* we might be in on a progress status line, so go to the next line */
! report_status(PG_REPORT, "\n*failure*");
fflush(stdout);
+
pg_log(PG_VERBOSE, "There were problems executing \"%s\"\n", cmd);
if (opt_log_file)
pg_log(throw_error ? PG_FATAL : PG_REPORT,
diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c
new file mode 100644
index 4d2e79c..bdc6d13
*** a/contrib/pg_upgrade/pg_upgrade.c
--- b/contrib/pg_upgrade/pg_upgrade.c
*************** main(int argc, char **argv)
*** 92,98 ****
check_cluster_compatibility(live_check);
! check_old_cluster(live_check, &sequence_script_file_name);
/* -- NEW -- */
--- 92,98 ----
check_cluster_compatibility(live_check);
! check_and_dump_old_cluster(live_check, &sequence_script_file_name);
/* -- NEW -- */
*************** create_new_objects(void)
*** 282,287 ****
--- 282,292 ----
prep_status("Adding support functions to new cluster");
+ /*
+ * Technically, we only need to install these support functions in new
+ * databases that also exist in the old cluster, but for completeness
+ * we process all new databases.
+ */
for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
{
DbInfo *new_db = &new_cluster.dbarr.dbs[dbnum];
*************** create_new_objects(void)
*** 292,302 ****
}
check_ok();
! prep_status("Restoring database schema to new cluster");
! exec_prog(RESTORE_LOG_FILE, NULL, true,
! "\"%s/psql\" " EXEC_PSQL_ARGS " %s -f \"%s\"",
! new_cluster.bindir, cluster_conn_opts(&new_cluster),
! DB_DUMP_FILE);
check_ok();
/* regenerate now that we have objects in the databases */
--- 297,323 ----
}
check_ok();
! prep_status("Restoring database schema to new cluster\n");
!
! for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
! {
! char file_name[MAXPGPATH];
! DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
!
! pg_log(PG_REPORT, OVERWRITE_MESSAGE, old_db->db_name);
! snprintf(file_name, sizeof(file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
!
! /*
! * Using pg_restore --single-transaction is faster than other
! * methods, like --jobs. pg_dump only produces its output at the
! * end, so there is little parallelism using the pipe.
! */
! exec_prog(RESTORE_LOG_FILE, NULL, true,
! "\"%s/pg_restore\" %s --exit-on-error --single-transaction --verbose --dbname \"%s\" \"%s\"",
! new_cluster.bindir, cluster_conn_opts(&new_cluster),
! old_db->db_name, file_name);
! }
! end_progress_output();
check_ok();
/* regenerate now that we have objects in the databases */
*************** cleanup(void)
*** 455,468 ****
/* Remove dump and log files? */
if (!log_opts.retain)
{
char **filename;
for (filename = output_files; *filename != NULL; filename++)
unlink(*filename);
! /* remove SQL files */
! unlink(ALL_DUMP_FILE);
unlink(GLOBALS_DUMP_FILE);
! unlink(DB_DUMP_FILE);
}
}
--- 476,498 ----
/* Remove dump and log files? */
if (!log_opts.retain)
{
+ int dbnum;
char **filename;
for (filename = output_files; *filename != NULL; filename++)
unlink(*filename);
! /* remove dump files */
unlink(GLOBALS_DUMP_FILE);
!
! if (old_cluster.dbarr.dbs)
! for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
! {
! char file_name[MAXPGPATH];
! DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
!
! snprintf(file_name, sizeof(file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
! unlink(file_name);
! }
}
}
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
new file mode 100644
index ace56e5..d981035
*** a/contrib/pg_upgrade/pg_upgrade.h
--- b/contrib/pg_upgrade/pg_upgrade.h
***************
*** 29,38 ****
#define OVERWRITE_MESSAGE " %-" MESSAGE_WIDTH "." MESSAGE_WIDTH "s\r"
#define GET_MAJOR_VERSION(v) ((v) / 100)
- #define ALL_DUMP_FILE "pg_upgrade_dump_all.sql"
/* contains both global db information and CREATE DATABASE commands */
#define GLOBALS_DUMP_FILE "pg_upgrade_dump_globals.sql"
! #define DB_DUMP_FILE "pg_upgrade_dump_db.sql"
#define SERVER_LOG_FILE "pg_upgrade_server.log"
#define RESTORE_LOG_FILE "pg_upgrade_restore.log"
--- 29,37 ----
#define OVERWRITE_MESSAGE " %-" MESSAGE_WIDTH "." MESSAGE_WIDTH "s\r"
#define GET_MAJOR_VERSION(v) ((v) / 100)
/* contains both global db information and CREATE DATABASE commands */
#define GLOBALS_DUMP_FILE "pg_upgrade_dump_globals.sql"
! #define DB_DUMP_FILE_MASK "pg_upgrade_dump_%u.custom"
#define SERVER_LOG_FILE "pg_upgrade_server.log"
#define RESTORE_LOG_FILE "pg_upgrade_restore.log"
*************** extern OSInfo os_info;
*** 296,307 ****
/* check.c */
void output_check_banner(bool *live_check);
! void check_old_cluster(bool live_check,
char **sequence_script_file_name);
void check_new_cluster(void);
void report_clusters_compatible(void);
void issue_warnings(char *sequence_script_file_name);
! void output_completion_banner(char *analyze_script_file_name,
char *deletion_script_file_name);
void check_cluster_versions(void);
void check_cluster_compatibility(bool live_check);
--- 295,306 ----
/* check.c */
void output_check_banner(bool *live_check);
! void check_and_dump_old_cluster(bool live_check,
char **sequence_script_file_name);
void check_new_cluster(void);
void report_clusters_compatible(void);
void issue_warnings(char *sequence_script_file_name);
! void output_completion_banner(char *analyze_script_file_name,
char *deletion_script_file_name);
void check_cluster_versions(void);
void check_cluster_compatibility(bool live_check);
*************** void disable_old_cluster(void);
*** 319,325 ****
/* dump.c */
void generate_old_dump(void);
- void split_old_dump(void);
/* exec.c */
--- 318,323 ----
*************** __attribute__((format(PG_PRINTF_ATTRIBUT
*** 433,438 ****
--- 431,437 ----
void
pg_log(eLogType type, char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+ void end_progress_output(void);
void
prep_status(const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c
new file mode 100644
index 7dbaac9..14e66df
*** a/contrib/pg_upgrade/relfilenode.c
--- b/contrib/pg_upgrade/relfilenode.c
*************** transfer_all_new_dbs(DbInfoArr *old_db_a
*** 82,90 ****
}
}
! prep_status(" "); /* in case nothing printed; pass a space so
! * gcc doesn't complain about empty format
! * string */
check_ok();
return msg;
--- 82,88 ----
}
}
! end_progress_output();
check_ok();
return msg;
diff --git a/contrib/pg_upgrade/util.c b/contrib/pg_upgrade/util.c
new file mode 100644
index 1d4bc89..0c1eccc
*** a/contrib/pg_upgrade/util.c
--- b/contrib/pg_upgrade/util.c
*************** report_status(eLogType type, const char
*** 35,40 ****
--- 35,52 ----
}
+ /* force blank output for progress display */
+ void
+ end_progress_output(void)
+ {
+ /*
+ * In case nothing printed; pass a space so gcc doesn't complain about
+ * empty format string.
+ */
+ prep_status(" ");
+ }
+
+
/*
* prep_status
*
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
new file mode 100644
index ca95bad..83eae81
*** a/src/bin/pg_dump/pg_dumpall.c
--- b/src/bin/pg_dump/pg_dumpall.c
*************** main(int argc, char *argv[])
*** 502,508 ****
}
/* Dump CREATE DATABASE commands */
! if (!globals_only && !roles_only && !tablespaces_only)
dumpCreateDB(conn);
/* Dump role/database settings */
--- 502,508 ----
}
/* Dump CREATE DATABASE commands */
! if (binary_upgrade || (!globals_only && !roles_only && !tablespaces_only))
dumpCreateDB(conn);
/* Dump role/database settings */
*************** dumpRoles(PGconn *conn)
*** 745,753 ****
* will acquire the right properties even if it already exists (ie, it
* won't hurt for the CREATE to fail). This is particularly important
* for the role we are connected as, since even with --clean we will
! * have failed to drop it.
*/
! appendPQExpBuffer(buf, "CREATE ROLE %s;\n", fmtId(rolename));
appendPQExpBuffer(buf, "ALTER ROLE %s WITH", fmtId(rolename));
if (strcmp(PQgetvalue(res, i, i_rolsuper), "t") == 0)
--- 745,755 ----
* will acquire the right properties even if it already exists (ie, it
* won't hurt for the CREATE to fail). This is particularly important
* for the role we are connected as, since even with --clean we will
! * have failed to drop it. binary_upgrade cannot generate any errors,
! * so we assume the role is already created.
*/
! if (!binary_upgrade)
! appendPQExpBuffer(buf, "CREATE ROLE %s;\n", fmtId(rolename));
appendPQExpBuffer(buf, "ALTER ROLE %s WITH", fmtId(rolename));
if (strcmp(PQgetvalue(res, i, i_rolsuper), "t") == 0)