v9-005-parallel_pg_restore.patch
application/octet-stream
Filename: v9-005-parallel_pg_restore.patch
Type: application/octet-stream
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
Series: patch v9
| File | + | − |
|---|---|---|
| src/bin/pg_upgrade/pg_upgrade.c | 95 | 40 |
commit 02513d121ce0b96be5619edfd0317b46b70a44da
Author: Sachin Kumar <ssetiya@amazon.com>
Date: Tue Jan 2 16:57:42 2024 +0000
Pass pg_upgrade --jobs parameter to pg_restore
This patch changes pg_upgrade --jobs behaviour for data, post_data
part of restore. Instead for restoring N databases in parallel,
they are restored in sequential order but with pg_restore
--jobs = {original pg_upgrade --jobs value}
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 5cfd2282e1..73ffdafd19 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -54,6 +54,7 @@
static void set_locale_and_encoding(void);
static void prepare_new_cluster(void);
static void prepare_new_globals(void);
+static void parallel_pg_restore_dbs(bool);
static void create_new_objects(void);
static void copy_xact_xlog_xid(void);
static void set_frozenxids(bool minmxid_only);
@@ -508,6 +509,96 @@ prepare_new_globals(void)
check_ok();
}
+/*
+ * This function will use parallel pg_restore to restore
+ * {data}, {post_data} section of the dump.
+ * Since {pre_data} section cant be parallelized , instead we will
+ * restore {pg_upgrade --jobs} dbs in parallel.
+ */
+static void
+parallel_pg_restore_dbs(bool pre_data)
+{
+ int dbnum;
+ int jobs = user_opts.jobs ? user_opts.jobs : 1;
+ /*
+ * Restore @section of the dump with parallel pg_restore
+ */
+ for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
+ {
+ char sql_file_name[MAXPGPATH],
+ log_file_name[MAXPGPATH];
+ DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
+ const char *create_opts;
+
+ /* Skip template1 in this pass */
+ if (strcmp(old_db->db_name, "template1") == 0)
+ continue;
+
+ pg_log(PG_STATUS, "%s", old_db->db_name);
+ snprintf(sql_file_name, sizeof(sql_file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
+ snprintf(log_file_name, sizeof(log_file_name), DB_DUMP_LOG_FILE_MASK, old_db->db_oid);
+
+ /*
+ * postgres database will already exist in the target installation, so
+ * tell pg_restore to drop and recreate it; otherwise we would fail to
+ * propagate its database-level properties.
+ */
+ if (pre_data)
+ {
+ if (strcmp(old_db->db_name, "postgres") == 0)
+ create_opts = "--clean --create";
+ else if (pre_data)
+ create_opts = "--create";
+ }
+ else
+ create_opts = "";
+
+ /*
+ * Restore pre-data section of the dump in parallel with single pg_restore job
+ * This section of dump cant be parallelized with parallel pg_restore
+ */
+ if (pre_data)
+ {
+ parallel_exec_prog(log_file_name,
+ NULL,
+ "\"%s/pg_restore\" %s %s --exit-on-error --verbose "
+ " --section=pre-data "
+ "--dbname template1 \"%s/%s\"",
+ new_cluster.bindir,
+ cluster_conn_opts(&new_cluster),
+ create_opts,
+ log_opts.dumpdir,
+ sql_file_name);
+
+ }
+ else
+ {
+ exec_prog(log_file_name,
+ NULL,
+ true,
+ true,
+ "\"%s/pg_restore\" %s %s --exit-on-error --verbose "
+ "--transaction-size=1000 --jobs %d --section=data --section=post-data "
+ "--dbname template1 \"%s/%s\"",
+ new_cluster.bindir,
+ cluster_conn_opts(&new_cluster),
+ create_opts,
+ jobs,
+ log_opts.dumpdir,
+ sql_file_name);
+ }
+ }
+ /*
+ * Wait for child process for pre-data section
+ */
+ if (pre_data)
+ {
+ /* reap all children */
+ while (reap_child(true) == true)
+ ;
+ }
+
+}
static void
create_new_objects(void)
@@ -559,46 +650,10 @@ create_new_objects(void)
break; /* done once we've processed template1 */
}
- for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
- {
- char sql_file_name[MAXPGPATH],
- log_file_name[MAXPGPATH];
- DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
- const char *create_opts;
-
- /* Skip template1 in this pass */
- if (strcmp(old_db->db_name, "template1") == 0)
- continue;
-
- pg_log(PG_STATUS, "%s", old_db->db_name);
- snprintf(sql_file_name, sizeof(sql_file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
- snprintf(log_file_name, sizeof(log_file_name), DB_DUMP_LOG_FILE_MASK, old_db->db_oid);
-
- /*
- * postgres database will already exist in the target installation, so
- * tell pg_restore to drop and recreate it; otherwise we would fail to
- * propagate its database-level properties.
- */
- if (strcmp(old_db->db_name, "postgres") == 0)
- create_opts = "--clean --create";
- else
- create_opts = "--create";
-
- parallel_exec_prog(log_file_name,
- NULL,
- "\"%s/pg_restore\" %s %s --exit-on-error --verbose "
- "--transaction-size=1000 "
- "--dbname template1 \"%s/%s\"",
- new_cluster.bindir,
- cluster_conn_opts(&new_cluster),
- create_opts,
- log_opts.dumpdir,
- sql_file_name);
- }
-
- /* reap all children */
- while (reap_child(true) == true)
- ;
+ /* Restore pre_data */
+ parallel_pg_restore_dbs(true);
+ /* Restore data, post_data */
+ parallel_pg_restore_dbs(false);
end_progress_output();
check_ok();