[PATCH v6 2/4] pg_upgrade: bump minimum supported version to v10
Nathan Bossart <nathan@postgresql.org>
From: Nathan Bossart <nathan@postgresql.org>
To:
Date: 2026-04-17T18:20:18Z
Lists: pgsql-hackers
---
doc/src/sgml/ref/pgupgrade.sgml | 2 +-
src/bin/pg_upgrade/check.c | 157 +-------------------
src/bin/pg_upgrade/controldata.c | 98 +-----------
src/bin/pg_upgrade/exec.c | 23 ---
src/bin/pg_upgrade/file.c | 164 ---------------------
src/bin/pg_upgrade/multixact_rewrite.c | 11 +-
src/bin/pg_upgrade/pg_upgrade.c | 56 +------
src/bin/pg_upgrade/pg_upgrade.h | 29 ----
src/bin/pg_upgrade/relfilenumber.c | 37 +----
src/bin/pg_upgrade/server.c | 3 +-
src/bin/pg_upgrade/t/006_transfer_modes.pl | 20 ---
src/bin/pg_upgrade/version.c | 127 ----------------
12 files changed, 26 insertions(+), 701 deletions(-)
diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml
index cc44983a9a8..e4e8c02e6d6 100644
--- a/doc/src/sgml/ref/pgupgrade.sgml
+++ b/doc/src/sgml/ref/pgupgrade.sgml
@@ -67,7 +67,7 @@ PostgreSQL documentation
</para>
<para>
- <application>pg_upgrade</application> supports upgrades from 9.2.X and later to the current
+ <application>pg_upgrade</application> supports upgrades from 10.X and later to the current
major release of <productname>PostgreSQL</productname>, including snapshot and beta releases.
</para>
diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c
index f8f31382835..786c1474829 100644
--- a/src/bin/pg_upgrade/check.c
+++ b/src/bin/pg_upgrade/check.c
@@ -28,7 +28,6 @@ static void check_for_incompatible_polymorphics(ClusterInfo *cluster);
static void check_for_tables_with_oids(ClusterInfo *cluster);
static void check_for_not_null_inheritance(ClusterInfo *cluster);
static void check_for_gist_inet_ops(ClusterInfo *cluster);
-static void check_for_pg_role_prefix(ClusterInfo *cluster);
static void check_for_new_tablespace_dir(void);
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster);
static void check_for_unicode_update(ClusterInfo *cluster);
@@ -128,26 +127,6 @@ static DataTypesUsageChecks data_types_usage_checks[] =
.threshold_version = ALL_VERSIONS
},
- /*
- * 9.3 -> 9.4 Fully implement the 'line' data type in 9.4, which
- * previously returned "not enabled" by default and was only functionally
- * enabled with a compile-time switch; as of 9.4 "line" has a different
- * on-disk representation format.
- */
- {
- .status = gettext_noop("Checking for incompatible \"line\" data type"),
- .report_filename = "tables_using_line.txt",
- .base_query =
- "SELECT 'pg_catalog.line'::pg_catalog.regtype AS oid",
- .report_text =
- gettext_noop("Your installation contains the \"line\" data type in user tables.\n"
- "This data type changed its internal and input/output format\n"
- "between your old and new versions so this\n"
- "cluster cannot currently be upgraded. You can\n"
- "drop the problem columns and restart the upgrade.\n"),
- .threshold_version = 903
- },
-
/*
* pg_upgrade only preserves these system values: pg_class.oid pg_type.oid
* pg_enum.oid
@@ -209,30 +188,6 @@ static DataTypesUsageChecks data_types_usage_checks[] =
.threshold_version = 1500
},
- /*
- * It's no longer allowed to create tables or views with "unknown"-type
- * columns. We do not complain about views with such columns, because
- * they should get silently converted to "text" columns during the DDL
- * dump and reload; it seems unlikely to be worth making users do that by
- * hand. However, if there's a table with such a column, the DDL reload
- * will fail, so we should pre-detect that rather than failing
- * mid-upgrade. Worse, if there's a matview with such a column, the DDL
- * reload will silently change it to "text" which won't match the on-disk
- * storage (which is like "cstring"). So we *must* reject that.
- */
- {
- .status = gettext_noop("Checking for invalid \"unknown\" user columns"),
- .report_filename = "tables_using_unknown.txt",
- .base_query =
- "SELECT 'pg_catalog.unknown'::pg_catalog.regtype AS oid",
- .report_text =
- gettext_noop("Your installation contains the \"unknown\" data type in user tables.\n"
- "This data type is no longer allowed in tables, so this cluster\n"
- "cannot currently be upgraded. You can drop the problem columns\n"
- "and restart the upgrade.\n"),
- .threshold_version = 906
- },
-
/*
* PG 12 changed the 'sql_identifier' type storage to be based on name,
* not varchar, which breaks on-disk format for existing data. So we need
@@ -255,23 +210,6 @@ static DataTypesUsageChecks data_types_usage_checks[] =
.threshold_version = 1100
},
- /*
- * JSONB changed its storage format during 9.4 beta, so check for it.
- */
- {
- .status = gettext_noop("Checking for incompatible \"jsonb\" data type in user tables"),
- .report_filename = "tables_using_jsonb.txt",
- .base_query =
- "SELECT 'pg_catalog.jsonb'::pg_catalog.regtype AS oid",
- .report_text =
- gettext_noop("Your installation contains the \"jsonb\" data type in user tables.\n"
- "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
- "cluster cannot currently be upgraded. You can drop the problem \n"
- "columns and restart the upgrade.\n"),
- .threshold_version = MANUAL_CHECK,
- .version_hook = jsonb_9_4_check_applicable
- },
-
/*
* PG 12 removed types abstime, reltime, tinterval.
*/
@@ -712,20 +650,6 @@ check_and_dump_old_cluster(void)
if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1800)
check_for_gist_inet_ops(&old_cluster);
- /*
- * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
- * hash indexes
- */
- if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906)
- {
- if (user_opts.check)
- old_9_6_invalidate_hash_indexes(&old_cluster, true);
- }
-
- /* 9.5 and below should not have roles starting with pg_ */
- if (GET_MAJOR_VERSION(old_cluster.major_version) <= 905)
- check_for_pg_role_prefix(&old_cluster);
-
/*
* While not a check option, we do this now because this is the only time
* the old server is running.
@@ -772,20 +696,6 @@ check_new_cluster(void)
* system boundaries.
*/
check_hard_link(TRANSFER_MODE_SWAP);
-
- /*
- * There are a few known issues with using --swap to upgrade from
- * versions older than 10. For example, the sequence tuple format
- * changed in v10, and the visibility map format changed in 9.6.
- * While such problems are not insurmountable (and we may have to
- * deal with similar problems in the future, anyway), it doesn't
- * seem worth the effort to support swap mode for upgrades from
- * long-unsupported versions.
- */
- if (GET_MAJOR_VERSION(old_cluster.major_version) < 1000)
- pg_fatal("Swap mode can only upgrade clusters from PostgreSQL version %s and later.",
- "10");
-
break;
}
@@ -831,10 +741,6 @@ issue_warnings_and_set_wal_level(void)
*/
start_postmaster(&new_cluster, true);
- /* Reindex hash indexes for old < 10.0 */
- if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906)
- old_9_6_invalidate_hash_indexes(&new_cluster, false);
-
report_extension_updates(&new_cluster);
stop_postmaster(false);
@@ -892,9 +798,9 @@ check_cluster_versions(void)
* upgrades
*/
- if (GET_MAJOR_VERSION(old_cluster.major_version) < 902)
+ if (GET_MAJOR_VERSION(old_cluster.major_version) < 1000)
pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
- "9.2");
+ "10");
/* Only current PG version is supported as a target */
if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM))
@@ -1569,12 +1475,10 @@ check_for_incompatible_polymorphics(ClusterInfo *cluster)
", 'array_cat(anyarray,anyarray)'"
", 'array_prepend(anyelement,anyarray)'");
- if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
appendPQExpBufferStr(&old_polymorphics,
", 'array_remove(anyarray,anyelement)'"
", 'array_replace(anyarray,anyelement,anyelement)'");
- if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
appendPQExpBufferStr(&old_polymorphics,
", 'array_position(anyarray,anyelement)'"
", 'array_position(anyarray,anyelement,integer)'"
@@ -1870,63 +1774,6 @@ check_for_gist_inet_ops(ClusterInfo *cluster)
check_ok();
}
-/*
- * check_for_pg_role_prefix()
- *
- * Versions older than 9.6 should not have any pg_* roles
- */
-static void
-check_for_pg_role_prefix(ClusterInfo *cluster)
-{
- PGresult *res;
- PGconn *conn = connectToServer(cluster, "template1");
- int ntups;
- int i_roloid;
- int i_rolname;
- FILE *script = NULL;
- char output_path[MAXPGPATH];
-
- prep_status("Checking for roles starting with \"pg_\"");
-
- snprintf(output_path, sizeof(output_path), "%s/%s",
- log_opts.basedir,
- "pg_role_prefix.txt");
-
- res = executeQueryOrDie(conn,
- "SELECT oid AS roloid, rolname "
- "FROM pg_catalog.pg_roles "
- "WHERE rolname ~ '^pg_'");
-
- ntups = PQntuples(res);
- i_roloid = PQfnumber(res, "roloid");
- i_rolname = PQfnumber(res, "rolname");
- for (int rowno = 0; rowno < ntups; rowno++)
- {
- if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
- pg_fatal("could not open file \"%s\": %m", output_path);
- fprintf(script, "%s (oid=%s)\n",
- PQgetvalue(res, rowno, i_rolname),
- PQgetvalue(res, rowno, i_roloid));
- }
-
- PQclear(res);
-
- PQfinish(conn);
-
- if (script)
- {
- fclose(script);
- pg_log(PG_REPORT, "fatal");
- pg_fatal("Your installation contains roles starting with \"pg_\".\n"
- "\"pg_\" is a reserved prefix for system roles. The cluster\n"
- "cannot be upgraded until these roles are renamed.\n"
- "A list of roles starting with \"pg_\" is in the file:\n"
- " %s", output_path);
- }
- else
- check_ok();
-}
-
/*
* Callback function for processing results of query for
* check_for_user_defined_encoding_conversions()'s UpgradeTask. If the query
diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c
index cffcd4b0eba..8f81c9e9582 100644
--- a/src/bin/pg_upgrade/controldata.c
+++ b/src/bin/pg_upgrade/controldata.c
@@ -42,9 +42,6 @@ get_control_data(ClusterInfo *cluster)
char bufin[MAX_STRING];
FILE *output;
char *p;
- bool got_tli = false;
- bool got_log_id = false;
- bool got_log_seg = false;
bool got_xid = false;
bool got_oid = false;
bool got_multi = false;
@@ -75,10 +72,6 @@ get_control_data(ClusterInfo *cluster)
char *language = NULL;
char *lc_all = NULL;
char *lc_messages = NULL;
- uint32 tli = 0;
- uint32 logid = 0;
- uint32 segno = 0;
- char *resetwal_bin;
int rc;
bool live_check = (cluster == &old_cluster && user_opts.live_check);
@@ -189,27 +182,15 @@ get_control_data(ClusterInfo *cluster)
}
}
- /* pg_resetxlog has been renamed to pg_resetwal in version 10 */
- if (GET_MAJOR_VERSION(cluster->bin_version) <= 906)
- resetwal_bin = "pg_resetxlog\" -n";
- else
- resetwal_bin = "pg_resetwal\" -n";
snprintf(cmd, sizeof(cmd), "\"%s/%s \"%s\"",
cluster->bindir,
- live_check ? "pg_controldata\"" : resetwal_bin,
+ live_check ? "pg_controldata\"" : "pg_resetwal\" -n",
cluster->pgdata);
fflush(NULL);
if ((output = popen(cmd, "r")) == NULL)
pg_fatal("could not get control data using %s: %m", cmd);
- /* Only in <= 9.2 */
- if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
- {
- cluster->controldata.data_checksum_version = PG_DATA_CHECKSUM_OFF;
- got_data_checksum_version = true;
- }
-
/* we have the result of cmd in "output". so parse it line by line now */
while (fgets(bufin, sizeof(bufin), output))
{
@@ -237,39 +218,6 @@ get_control_data(ClusterInfo *cluster)
p++; /* remove ':' char */
cluster->controldata.cat_ver = str2uint(p);
}
- else if ((p = strstr(bufin, "Latest checkpoint's TimeLineID:")) != NULL)
- {
- p = strchr(p, ':');
-
- if (p == NULL || strlen(p) <= 1)
- pg_fatal("%d: controldata retrieval problem", __LINE__);
-
- p++; /* remove ':' char */
- tli = str2uint(p);
- got_tli = true;
- }
- else if ((p = strstr(bufin, "First log file ID after reset:")) != NULL)
- {
- p = strchr(p, ':');
-
- if (p == NULL || strlen(p) <= 1)
- pg_fatal("%d: controldata retrieval problem", __LINE__);
-
- p++; /* remove ':' char */
- logid = str2uint(p);
- got_log_id = true;
- }
- else if ((p = strstr(bufin, "First log file segment after reset:")) != NULL)
- {
- p = strchr(p, ':');
-
- if (p == NULL || strlen(p) <= 1)
- pg_fatal("%d: controldata retrieval problem", __LINE__);
-
- p++; /* remove ':' char */
- segno = str2uint(p);
- got_log_seg = true;
- }
else if ((p = strstr(bufin, "Latest checkpoint's NextXID:")) != NULL)
{
p = strchr(p, ':');
@@ -280,23 +228,12 @@ get_control_data(ClusterInfo *cluster)
p++; /* remove ':' char */
cluster->controldata.chkpnt_nxtepoch = str2uint(p);
- /*
- * Delimiter changed from '/' to ':' in 9.6. We don't test for
- * the catalog version of the change because the catalog version
- * is pulled from pg_controldata too, and it isn't worth adding an
- * order dependency for this --- we just check the string.
- */
- if (strchr(p, '/') != NULL)
- p = strchr(p, '/');
- else if (GET_MAJOR_VERSION(cluster->major_version) >= 906)
p = strchr(p, ':');
- else
- p = NULL;
if (p == NULL || strlen(p) <= 1)
pg_fatal("%d: controldata retrieval problem", __LINE__);
- p++; /* remove '/' or ':' char */
+ p++; /* remove ':' char */
cluster->controldata.chkpnt_nxtxid = str2uint(p);
got_xid = true;
}
@@ -568,22 +505,6 @@ get_control_data(ClusterInfo *cluster)
pg_free(lc_all);
pg_free(lc_messages);
- /*
- * Before 9.3, pg_resetwal reported the xlogid and segno of the first log
- * file after reset as separate lines. Starting with 9.3, it reports the
- * WAL file name. If the old cluster is older than 9.3, we construct the
- * WAL file name from the xlogid and segno.
- */
- if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
- {
- if (got_tli && got_log_id && got_log_seg)
- {
- snprintf(cluster->controldata.nextxlogfile, 25, "%08X%08X%08X",
- tli, logid, segno);
- got_nextxlogfile = true;
- }
- }
-
/*
* Pre-v18 database clusters don't have the default char signedness
* information. We use the char signedness of the platform where
@@ -602,14 +523,12 @@ get_control_data(ClusterInfo *cluster)
/* verify that we got all the mandatory pg_control data */
if (!got_xid || !got_oid ||
!got_multi || !got_oldestxid ||
- (!got_oldestmulti &&
- cluster->controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER) ||
+ !got_oldestmulti ||
!got_mxoff || (!live_check && !got_nextxlogfile) ||
!got_float8_pass_by_value || !got_align || !got_blocksz ||
!got_largesz || !got_walsz || !got_walseg || !got_ident ||
!got_index || !got_toast ||
- (!got_large_object &&
- cluster->controldata.ctrl_ver >= LARGE_OBJECT_SIZE_PG_CONTROL_VER) ||
+ !got_large_object ||
!got_date_is_int || !got_data_checksum_version ||
(!got_default_char_signedness &&
cluster->controldata.cat_ver >= DEFAULT_CHAR_SIGNEDNESS_CAT_VER))
@@ -630,8 +549,7 @@ get_control_data(ClusterInfo *cluster)
if (!got_multi)
pg_log(PG_REPORT, " latest checkpoint next MultiXactId");
- if (!got_oldestmulti &&
- cluster->controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER)
+ if (!got_oldestmulti)
pg_log(PG_REPORT, " latest checkpoint oldest MultiXactId");
if (!got_oldestxid)
@@ -670,8 +588,7 @@ get_control_data(ClusterInfo *cluster)
if (!got_toast)
pg_log(PG_REPORT, " maximum TOAST chunk size");
- if (!got_large_object &&
- cluster->controldata.ctrl_ver >= LARGE_OBJECT_SIZE_PG_CONTROL_VER)
+ if (!got_large_object)
pg_log(PG_REPORT, " large-object chunk size");
if (!got_date_is_int)
@@ -724,8 +641,7 @@ check_control_data(ControlData *oldctrl,
if (oldctrl->toast == 0 || oldctrl->toast != newctrl->toast)
pg_fatal("old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match");
- /* large_object added in 9.5, so it might not exist in the old cluster */
- if (oldctrl->large_object != 0 &&
+ if (oldctrl->large_object == 0 ||
oldctrl->large_object != newctrl->large_object)
pg_fatal("old and new pg_controldata large-object chunk sizes are invalid or do not match");
diff --git a/src/bin/pg_upgrade/exec.c b/src/bin/pg_upgrade/exec.c
index 563b4a6b5fa..44355feea30 100644
--- a/src/bin/pg_upgrade/exec.c
+++ b/src/bin/pg_upgrade/exec.c
@@ -55,16 +55,7 @@ get_bin_version(ClusterInfo *cluster)
if (sscanf(cmd_output, "%*s %*s %d.%d", &v1, &v2) < 1)
pg_fatal("could not get pg_ctl version output from %s", cmd);
- if (v1 < 10)
- {
- /* old style, e.g. 9.6.1 */
- cluster->bin_version = v1 * 10000 + v2 * 100;
- }
- else
- {
- /* new style, e.g. 10.1 */
cluster->bin_version = v1 * 10000;
- }
}
@@ -353,17 +344,7 @@ check_data_dir(ClusterInfo *cluster)
check_single_dir(pg_data, "pg_subtrans");
check_single_dir(pg_data, PG_TBLSPC_DIR);
check_single_dir(pg_data, "pg_twophase");
-
- /* pg_xlog has been renamed to pg_wal in v10 */
- if (GET_MAJOR_VERSION(cluster->major_version) <= 906)
- check_single_dir(pg_data, "pg_xlog");
- else
check_single_dir(pg_data, "pg_wal");
-
- /* pg_clog has been renamed to pg_xact in v10 */
- if (GET_MAJOR_VERSION(cluster->major_version) <= 906)
- check_single_dir(pg_data, "pg_clog");
- else
check_single_dir(pg_data, "pg_xact");
}
@@ -404,10 +385,6 @@ check_bin_dir(ClusterInfo *cluster, bool check_versions)
*/
get_bin_version(cluster);
- /* pg_resetxlog has been renamed to pg_resetwal in version 10 */
- if (GET_MAJOR_VERSION(cluster->bin_version) <= 906)
- check_exec(cluster->bindir, "pg_resetxlog", check_versions);
- else
check_exec(cluster->bindir, "pg_resetwal", check_versions);
if (cluster == &new_cluster)
diff --git a/src/bin/pg_upgrade/file.c b/src/bin/pg_upgrade/file.c
index 5b276008614..af82c0de490 100644
--- a/src/bin/pg_upgrade/file.c
+++ b/src/bin/pg_upgrade/file.c
@@ -20,12 +20,8 @@
#include <linux/fs.h>
#endif
-#include "access/visibilitymapdefs.h"
#include "common/file_perm.h"
#include "pg_upgrade.h"
-#include "storage/bufpage.h"
-#include "storage/checksum.h"
-#include "storage/checksum_impl.h"
/*
@@ -196,166 +192,6 @@ linkFile(const char *src, const char *dst,
}
-/*
- * rewriteVisibilityMap()
- *
- * Transform a visibility map file, copying from src to dst.
- * schemaName/relName are relation's SQL name (used for error messages only).
- *
- * In versions of PostgreSQL prior to catversion 201603011, PostgreSQL's
- * visibility map included one bit per heap page; it now includes two.
- * When upgrading a cluster from before that time to a current PostgreSQL
- * version, we could refuse to copy visibility maps from the old cluster
- * to the new cluster; the next VACUUM would recreate them, but at the
- * price of scanning the entire table. So, instead, we rewrite the old
- * visibility maps in the new format. That way, the all-visible bits
- * remain set for the pages for which they were set previously. The
- * all-frozen bits are never set by this conversion; we leave that to VACUUM.
- */
-void
-rewriteVisibilityMap(const char *fromfile, const char *tofile,
- const char *schemaName, const char *relName)
-{
- int src_fd;
- int dst_fd;
- PGIOAlignedBlock buffer;
- PGIOAlignedBlock new_vmbuf;
- ssize_t totalBytesRead = 0;
- ssize_t src_filesize;
- int rewriteVmBytesPerPage;
- BlockNumber new_blkno = 0;
- struct stat statbuf;
-
- /* Compute number of old-format bytes per new page */
- rewriteVmBytesPerPage = (BLCKSZ - SizeOfPageHeaderData) / 2;
-
- if ((src_fd = open(fromfile, O_RDONLY | PG_BINARY, 0)) < 0)
- pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %m",
- schemaName, relName, fromfile);
-
- if (fstat(src_fd, &statbuf) != 0)
- pg_fatal("error while copying relation \"%s.%s\": could not stat file \"%s\": %m",
- schemaName, relName, fromfile);
-
- if ((dst_fd = open(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
- pg_file_create_mode)) < 0)
- pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %m",
- schemaName, relName, tofile);
-
- /* Save old file size */
- src_filesize = statbuf.st_size;
-
- /*
- * Turn each visibility map page into 2 pages one by one. Each new page
- * has the same page header as the old one. If the last section of the
- * last page is empty, we skip it, mostly to avoid turning one-page
- * visibility maps for small relations into two pages needlessly.
- */
- while (totalBytesRead < src_filesize)
- {
- ssize_t bytesRead;
- char *old_cur;
- char *old_break;
- char *old_blkend;
- PageHeaderData pageheader;
- bool old_lastblk;
-
- if ((bytesRead = read(src_fd, buffer.data, BLCKSZ)) != BLCKSZ)
- {
- if (bytesRead < 0)
- pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %m",
- schemaName, relName, fromfile);
- else
- pg_fatal("error while copying relation \"%s.%s\": partial page found in file \"%s\"",
- schemaName, relName, fromfile);
- }
-
- totalBytesRead += BLCKSZ;
- old_lastblk = (totalBytesRead == src_filesize);
-
- /* Save the page header data */
- memcpy(&pageheader, buffer.data, SizeOfPageHeaderData);
-
- /*
- * These old_* variables point to old visibility map page. old_cur
- * points to current position on old page. old_blkend points to end of
- * old block. old_break is the end+1 position on the old page for the
- * data that will be transferred to the current new page.
- */
- old_cur = buffer.data + SizeOfPageHeaderData;
- old_blkend = buffer.data + bytesRead;
- old_break = old_cur + rewriteVmBytesPerPage;
-
- while (old_break <= old_blkend)
- {
- char *new_cur;
- bool empty = true;
- bool old_lastpart;
-
- /* First, copy old page header to new page */
- memcpy(new_vmbuf.data, &pageheader, SizeOfPageHeaderData);
-
- /* Rewriting the last part of the last old page? */
- old_lastpart = old_lastblk && (old_break == old_blkend);
-
- new_cur = new_vmbuf.data + SizeOfPageHeaderData;
-
- /* Process old page bytes one by one, and turn it into new page. */
- while (old_cur < old_break)
- {
- uint8 byte = *(uint8 *) old_cur;
- uint16 new_vmbits = 0;
- int i;
-
- /* Generate new format bits while keeping old information */
- for (i = 0; i < BITS_PER_BYTE; i++)
- {
- if (byte & (1 << i))
- {
- empty = false;
- new_vmbits |=
- VISIBILITYMAP_ALL_VISIBLE << (BITS_PER_HEAPBLOCK * i);
- }
- }
-
- /* Copy new visibility map bytes to new-format page */
- new_cur[0] = (char) (new_vmbits & 0xFF);
- new_cur[1] = (char) (new_vmbits >> 8);
-
- old_cur++;
- new_cur += BITS_PER_HEAPBLOCK;
- }
-
- /* If the last part of the last page is empty, skip writing it */
- if (old_lastpart && empty)
- break;
-
- /* Set new checksum for visibility map page, if enabled */
- if (new_cluster.controldata.data_checksum_version != PG_DATA_CHECKSUM_OFF)
- ((PageHeader) new_vmbuf.data)->pd_checksum =
- pg_checksum_page(new_vmbuf.data, new_blkno);
-
- errno = 0;
- if (write(dst_fd, new_vmbuf.data, BLCKSZ) != BLCKSZ)
- {
- /* if write didn't set errno, assume problem is no disk space */
- if (errno == 0)
- errno = ENOSPC;
- pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %m",
- schemaName, relName, tofile);
- }
-
- /* Advance for next new page */
- old_break += rewriteVmBytesPerPage;
- new_blkno++;
- }
- }
-
- /* Clean up */
- close(dst_fd);
- close(src_fd);
-}
-
void
check_file_clone(void)
{
diff --git a/src/bin/pg_upgrade/multixact_rewrite.c b/src/bin/pg_upgrade/multixact_rewrite.c
index 823984ec8f3..c45b3183684 100644
--- a/src/bin/pg_upgrade/multixact_rewrite.c
+++ b/src/bin/pg_upgrade/multixact_rewrite.c
@@ -25,10 +25,7 @@ static void RecordMultiXactMembers(SlruSegState *members_writer,
* 32-bit offsets to the current format.
*
* Multixids in the range [from_multi, to_multi) are read from the old
- * cluster, and written in the new format. An important edge case is that if
- * from_multi == to_multi, this initializes the new pg_multixact files in the
- * new format without trying to open any old files. (We rely on that when
- * upgrading from PostgreSQL version 9.2 or below.)
+ * cluster, and written in the new format.
*
* Returns the new nextOffset value; the caller should set it in the new
* control file. The new members always start from offset 1, regardless of
@@ -42,6 +39,7 @@ rewrite_multixacts(MultiXactId from_multi, MultiXactId to_multi)
SlruSegState *members_writer;
char dir[MAXPGPATH] = {0};
bool prev_multixid_valid = false;
+ OldMultiXactReader *old_reader;
/*
* The range of valid multi XIDs is unchanged by the conversion (they are
@@ -63,10 +61,6 @@ rewrite_multixacts(MultiXactId from_multi, MultiXactId to_multi)
* Convert old multixids, if needed, by reading them one-by-one from the
* old cluster.
*/
- if (to_multi != from_multi)
- {
- OldMultiXactReader *old_reader;
-
old_reader = AllocOldMultiXactRead(old_cluster.pgdata,
old_cluster.controldata.chkpnt_nxtmulti,
old_cluster.controldata.chkpnt_nxtmxoff);
@@ -113,7 +107,6 @@ rewrite_multixacts(MultiXactId from_multi, MultiXactId to_multi)
}
FreeOldMultiXactReader(old_reader);
- }
/* Write the final 'next' offset to the last SLRU page */
RecordMultiXactOffset(offsets_writer, to_multi,
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 2127d297bfe..c6af9035665 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -64,7 +64,7 @@ static void prepare_new_cluster(void);
static void prepare_new_globals(void);
static void create_new_objects(void);
static void copy_xact_xlog_xid(void);
-static void set_frozenxids(bool minmxid_only);
+static void set_frozenxids(void);
static void make_outputdirs(char *pgdata);
static void setup(char *argv0);
static void create_logical_replication_slots(void);
@@ -576,7 +576,7 @@ prepare_new_globals(void)
/*
* Before we restore anything, set frozenxids of initdb-created tables.
*/
- set_frozenxids(false);
+ set_frozenxids();
/*
* Now restore global objects (roles and tablespaces).
@@ -714,13 +714,6 @@ create_new_objects(void)
end_progress_output();
check_ok();
- /*
- * We don't have minmxids for databases or relations in pre-9.3 clusters,
- * so set those after we have restored the schema.
- */
- if (GET_MAJOR_VERSION(old_cluster.major_version) <= 902)
- set_frozenxids(true);
-
/* update new_cluster info now that we have objects in the databases */
get_db_rel_and_slot_infos(&new_cluster);
}
@@ -777,10 +770,7 @@ copy_xact_xlog_xid(void)
* Copy old commit logs to new data dir. pg_clog has been renamed to
* pg_xact in post-10 clusters.
*/
- copy_subdir_files(GET_MAJOR_VERSION(old_cluster.major_version) <= 906 ?
- "pg_clog" : "pg_xact",
- GET_MAJOR_VERSION(new_cluster.major_version) <= 906 ?
- "pg_clog" : "pg_xact");
+ copy_subdir_files("pg_xact", "pg_xact");
prep_status("Setting oldest XID for new cluster");
exec_prog(UTILITY_LOG_FILE, NULL, true, true,
@@ -809,7 +799,6 @@ copy_xact_xlog_xid(void)
check_ok();
/* Copy or convert pg_multixact files */
- Assert(new_cluster.controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER);
Assert(new_cluster.controldata.cat_ver >= MULTIXACTOFFSET_FORMATCHANGE_CAT_VER);
if (old_cluster.controldata.cat_ver >= MULTIXACTOFFSET_FORMATCHANGE_CAT_VER)
{
@@ -844,25 +833,7 @@ copy_xact_xlog_xid(void)
* Determine the range of multixacts to convert.
*/
nxtmulti = old_cluster.controldata.chkpnt_nxtmulti;
- if (old_cluster.controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER)
- {
- /* Versions 9.3 - 18: convert all multixids */
oldstMulti = old_cluster.controldata.chkpnt_oldstMulti;
- }
- else
- {
- /*
- * In PostgreSQL 9.2 and below, multitransactions were only used
- * for row locking, and as such don't need to be preserved during
- * upgrade. In that case, we utilize rewrite_multixacts() just to
- * initialize new, empty files in the new format.
- *
- * It's important that the oldest multi is set to the latest value
- * used by the old system, so that multixact.c returns the empty
- * set for multis that might be present on disk.
- */
- oldstMulti = nxtmulti;
- }
/* handle wraparound */
if (nxtmulti < FirstMultiXactId)
nxtmulti = FirstMultiXactId;
@@ -906,26 +877,18 @@ copy_xact_xlog_xid(void)
/*
* set_frozenxids()
*
- * This is called on the new cluster before we restore anything, with
- * minmxid_only = false. Its purpose is to ensure that all initdb-created
+ * This is called on the new cluster before we restore anything.
+ * Its purpose is to ensure that all initdb-created
* vacuumable tables have relfrozenxid/relminmxid matching the old cluster's
* xid/mxid counters. We also initialize the datfrozenxid/datminmxid of the
* built-in databases to match.
*
* As we create user tables later, their relfrozenxid/relminmxid fields will
* be restored properly by the binary-upgrade restore script. Likewise for
- * user-database datfrozenxid/datminmxid. However, if we're upgrading from a
- * pre-9.3 database, which does not store per-table or per-DB minmxid, then
- * the relminmxid/datminmxid values filled in by the restore script will just
- * be zeroes.
- *
- * Hence, with a pre-9.3 source database, a second call occurs after
- * everything is restored, with minmxid_only = true. This pass will
- * initialize all tables and databases, both those made by initdb and user
- * objects, with the desired minmxid value. frozenxid values are left alone.
+ * user-database datfrozenxid/datminmxid.
*/
static void
-set_frozenxids(bool minmxid_only)
+set_frozenxids(void)
{
int dbnum;
PGconn *conn,
@@ -935,14 +898,10 @@ set_frozenxids(bool minmxid_only)
int i_datname;
int i_datallowconn;
- if (!minmxid_only)
prep_status("Setting frozenxid and minmxid counters in new cluster");
- else
- prep_status("Setting minmxid counter in new cluster");
conn_template1 = connectToServer(&new_cluster, "template1");
- if (!minmxid_only)
/* set pg_database.datfrozenxid */
PQclear(executeQueryOrDie(conn_template1,
"UPDATE pg_catalog.pg_database "
@@ -983,7 +942,6 @@ set_frozenxids(bool minmxid_only)
conn = connectToServer(&new_cluster, datname);
- if (!minmxid_only)
/* set pg_class.relfrozenxid */
PQclear(executeQueryOrDie(conn,
"UPDATE pg_catalog.pg_class "
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index ccd1ac0d013..d6e5bca5792 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -101,19 +101,6 @@ extern char *output_files[];
#endif
-/*
- * The format of visibility map was changed with this 9.6 commit.
- */
-#define VISIBILITY_MAP_FROZEN_BIT_CAT_VER 201603011
-
-/*
- * pg_multixact format changed in 9.3 commit 0ac5ad5134f2769ccbaefec73844f85,
- * ("Improve concurrency of foreign key locking") which also updated catalog
- * version to this value. pg_upgrade behavior depends on whether old and new
- * server versions are both newer than this, or only the new one is.
- */
-#define MULTIXACT_FORMATCHANGE_CAT_VER 201301231
-
/*
* MultiXactOffset was changed from 32-bit to 64-bit in version 19, at this
* catalog version. pg_multixact files need to be converted when upgrading
@@ -121,17 +108,6 @@ extern char *output_files[];
*/
#define MULTIXACTOFFSET_FORMATCHANGE_CAT_VER 202512091
-/*
- * large object chunk size added to pg_controldata,
- * commit 5f93c37805e7485488480916b4585e098d3cc883
- */
-#define LARGE_OBJECT_SIZE_PG_CONTROL_VER 942
-
-/*
- * change in JSONB format during 9.4 beta
- */
-#define JSONB_FORMAT_CHANGE_CAT_VER 201409291
-
/*
* The control file was changed to have the default char signedness,
* commit 44fe30fdab6746a287163e7cc093fd36cda8eb92
@@ -429,8 +405,6 @@ void copyFileByRange(const char *src, const char *dst,
const char *schemaName, const char *relName);
void linkFile(const char *src, const char *dst,
const char *schemaName, const char *relName);
-void rewriteVisibilityMap(const char *fromfile, const char *tofile,
- const char *schemaName, const char *relName);
void check_file_clone(void);
void check_copy_file_range(void);
void check_hard_link(transferMode transfer_mode);
@@ -500,10 +474,7 @@ unsigned int str2uint(const char *str);
/* version.c */
-bool jsonb_9_4_check_applicable(ClusterInfo *cluster);
bool protocol_negotiation_supported(const ClusterInfo *cluster);
-void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster,
- bool check_mode);
void report_extension_updates(ClusterInfo *cluster);
diff --git a/src/bin/pg_upgrade/relfilenumber.c b/src/bin/pg_upgrade/relfilenumber.c
index d5088447e0d..ec2ff7acb21 100644
--- a/src/bin/pg_upgrade/relfilenumber.c
+++ b/src/bin/pg_upgrade/relfilenumber.c
@@ -18,7 +18,7 @@
#include "pg_upgrade.h"
static void transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace, char *new_tablespace);
-static void transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_frozenbit);
+static void transfer_relfile(FileNameMap *map, const char *type_suffix);
/*
* The following set of sync_queue_* functions are used for --swap to reduce
@@ -496,25 +496,10 @@ transfer_single_new_db(FileNameMap *maps, int size,
char *old_tablespace, char *new_tablespace)
{
int mapnum;
- bool vm_must_add_frozenbit = false;
-
- /*
- * Do we need to rewrite visibilitymap?
- */
- if (old_cluster.controldata.cat_ver < VISIBILITY_MAP_FROZEN_BIT_CAT_VER &&
- new_cluster.controldata.cat_ver >= VISIBILITY_MAP_FROZEN_BIT_CAT_VER)
- vm_must_add_frozenbit = true;
/* --swap has its own subroutine */
if (user_opts.transfer_mode == TRANSFER_MODE_SWAP)
{
- /*
- * We don't support --swap to upgrade from versions that require
- * rewriting the visibility map. We should've failed already if
- * someone tries to do that.
- */
- Assert(!vm_must_add_frozenbit);
-
do_swap(maps, size, old_tablespace, new_tablespace);
return;
}
@@ -525,13 +510,13 @@ transfer_single_new_db(FileNameMap *maps, int size,
strcmp(maps[mapnum].old_tablespace, old_tablespace) == 0)
{
/* transfer primary file */
- transfer_relfile(&maps[mapnum], "", vm_must_add_frozenbit);
+ transfer_relfile(&maps[mapnum], "");
/*
* Copy/link any fsm and vm files, if they exist
*/
- transfer_relfile(&maps[mapnum], "_fsm", vm_must_add_frozenbit);
- transfer_relfile(&maps[mapnum], "_vm", vm_must_add_frozenbit);
+ transfer_relfile(&maps[mapnum], "_fsm");
+ transfer_relfile(&maps[mapnum], "_vm");
}
}
}
@@ -540,12 +525,10 @@ transfer_single_new_db(FileNameMap *maps, int size,
/*
* transfer_relfile()
*
- * Copy or link file from old cluster to new one. If vm_must_add_frozenbit
- * is true, visibility map forks are converted and rewritten, even in link
- * mode.
+ * Copy or link file from old cluster to new one.
*/
static void
-transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_frozenbit)
+transfer_relfile(FileNameMap *map, const char *type_suffix)
{
char old_file[MAXPGPATH];
char new_file[MAXPGPATH];
@@ -604,14 +587,6 @@ transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_fro
/* Copying files might take some time, so give feedback. */
pg_log(PG_STATUS, "%s", old_file);
- if (vm_must_add_frozenbit && strcmp(type_suffix, "_vm") == 0)
- {
- /* Need to rewrite visibility map format */
- pg_log(PG_VERBOSE, "rewriting \"%s\" to \"%s\"",
- old_file, new_file);
- rewriteVisibilityMap(old_file, new_file, map->nspname, map->relname);
- }
- else
switch (user_opts.transfer_mode)
{
case TRANSFER_MODE_CLONE:
diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c
index 5d81e4e95b8..7da9dffe585 100644
--- a/src/bin/pg_upgrade/server.c
+++ b/src/bin/pg_upgrade/server.c
@@ -186,8 +186,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error)
snprintf(socket_string + strlen(socket_string),
sizeof(socket_string) - strlen(socket_string),
" -c %s='%s'",
- (GET_MAJOR_VERSION(cluster->major_version) <= 902) ?
- "unix_socket_directory" : "unix_socket_directories",
+ "unix_socket_directories",
cluster->sockdir);
#endif
diff --git a/src/bin/pg_upgrade/t/006_transfer_modes.pl b/src/bin/pg_upgrade/t/006_transfer_modes.pl
index 6b7ab9f29a2..9efa5dc863c 100644
--- a/src/bin/pg_upgrade/t/006_transfer_modes.pl
+++ b/src/bin/pg_upgrade/t/006_transfer_modes.pl
@@ -17,15 +17,6 @@ sub test_mode
PostgreSQL::Test::Cluster->new('old', install_path => $ENV{oldinstall});
my $new = PostgreSQL::Test::Cluster->new('new');
- # --swap can't be used to upgrade from versions older than 10, so just skip
- # the test if the old cluster version is too old.
- if ($old->pg_version < 10 && $mode eq "--swap")
- {
- $old->clean_node();
- $new->clean_node();
- return;
- }
-
if (defined($ENV{oldinstall}))
{
# Checksums are now enabled by default, but weren't before 18, so pass
@@ -38,14 +29,10 @@ sub test_mode
}
$new->init();
- # allow_in_place_tablespaces is available as far back as v10.
- if ($old->pg_version >= 10)
- {
$new->append_conf('postgresql.conf',
"allow_in_place_tablespaces = true");
$old->append_conf('postgresql.conf',
"allow_in_place_tablespaces = true");
- }
# We can only test security labels if both the old and new installations
# have dummy_seclabel.
@@ -89,9 +76,6 @@ sub test_mode
"CREATE TABLE test4 AS SELECT generate_series(400, 502)");
}
- # If the old cluster is >= v10, we can test in-place tablespaces.
- if ($old->pg_version >= 10)
- {
$old->safe_psql('postgres',
"CREATE TABLESPACE inplc_tblspc LOCATION ''");
$old->safe_psql('postgres',
@@ -101,7 +85,6 @@ sub test_mode
);
$old->safe_psql('testdb3',
"CREATE TABLE test6 AS SELECT generate_series(607, 711)");
- }
# While we are here, test handling of large objects.
$old->safe_psql(
@@ -169,15 +152,12 @@ sub test_mode
}
# Tests for in-place tablespaces.
- if ($old->pg_version >= 10)
- {
$result =
$new->safe_psql('postgres', "SELECT COUNT(*) FROM test5");
is($result, '104', "test5 data after pg_upgrade $mode");
$result =
$new->safe_psql('testdb3', "SELECT COUNT(*) FROM test6");
is($result, '105', "test6 data after pg_upgrade $mode");
- }
# Tests for large objects
$result = $new->safe_psql('postgres', "SELECT lo_get(4532)");
diff --git a/src/bin/pg_upgrade/version.c b/src/bin/pg_upgrade/version.c
index 047670d4acb..9e83d4659be 100644
--- a/src/bin/pg_upgrade/version.c
+++ b/src/bin/pg_upgrade/version.c
@@ -12,22 +12,6 @@
#include "fe_utils/string_utils.h"
#include "pg_upgrade.h"
-/*
- * version_hook functions for check_for_data_types_usage in order to determine
- * whether a data type check should be executed for the cluster in question or
- * not.
- */
-bool
-jsonb_9_4_check_applicable(ClusterInfo *cluster)
-{
- /* JSONB changed its storage format during 9.4 beta */
- if (GET_MAJOR_VERSION(cluster->major_version) == 904 &&
- cluster->controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER)
- return true;
-
- return false;
-}
-
/*
* Older servers can't support newer protocol versions, so their connection
* strings will need to lock max_protocol_version to 3.0.
@@ -46,117 +30,6 @@ protocol_negotiation_supported(const ClusterInfo *cluster)
return (GET_MAJOR_VERSION(cluster->major_version) >= 1100);
}
-/*
- * old_9_6_invalidate_hash_indexes()
- * 9.6 -> 10
- * Hash index binary format has changed from 9.6->10.0
- */
-void
-old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
-{
- int dbnum;
- FILE *script = NULL;
- bool found = false;
- char *output_path = "reindex_hash.sql";
-
- prep_status("Checking for hash indexes");
-
- for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
- {
- PGresult *res;
- bool db_used = false;
- int ntups;
- int rowno;
- int i_nspname,
- i_relname;
- DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
- PGconn *conn = connectToServer(cluster, active_db->db_name);
-
- /* find hash indexes */
- res = executeQueryOrDie(conn,
- "SELECT n.nspname, c.relname "
- "FROM pg_catalog.pg_class c, "
- " pg_catalog.pg_index i, "
- " pg_catalog.pg_am a, "
- " pg_catalog.pg_namespace n "
- "WHERE i.indexrelid = c.oid AND "
- " c.relam = a.oid AND "
- " c.relnamespace = n.oid AND "
- " a.amname = 'hash'"
- );
-
- ntups = PQntuples(res);
- i_nspname = PQfnumber(res, "nspname");
- i_relname = PQfnumber(res, "relname");
- for (rowno = 0; rowno < ntups; rowno++)
- {
- found = true;
- if (!check_mode)
- {
- if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
- pg_fatal("could not open file \"%s\": %m", output_path);
- if (!db_used)
- {
- PQExpBufferData connectbuf;
-
- initPQExpBuffer(&connectbuf);
- appendPsqlMetaConnect(&connectbuf, active_db->db_name);
- fputs(connectbuf.data, script);
- termPQExpBuffer(&connectbuf);
- db_used = true;
- }
- fprintf(script, "REINDEX INDEX %s.%s;\n",
- quote_identifier(PQgetvalue(res, rowno, i_nspname)),
- quote_identifier(PQgetvalue(res, rowno, i_relname)));
- }
- }
-
- PQclear(res);
-
- if (!check_mode && db_used)
- {
- /* mark hash indexes as invalid */
- PQclear(executeQueryOrDie(conn,
- "UPDATE pg_catalog.pg_index i "
- "SET indisvalid = false "
- "FROM pg_catalog.pg_class c, "
- " pg_catalog.pg_am a, "
- " pg_catalog.pg_namespace n "
- "WHERE i.indexrelid = c.oid AND "
- " c.relam = a.oid AND "
- " c.relnamespace = n.oid AND "
- " a.amname = 'hash'"));
- }
-
- PQfinish(conn);
- }
-
- if (script)
- fclose(script);
-
- if (found)
- {
- report_status(PG_WARNING, "warning");
- if (check_mode)
- pg_log(PG_WARNING, "\n"
- "Your installation contains hash indexes. These indexes have different\n"
- "internal formats between your old and new clusters, so they must be\n"
- "reindexed with the REINDEX command. After upgrading, you will be given\n"
- "REINDEX instructions.");
- else
- pg_log(PG_WARNING, "\n"
- "Your installation contains hash indexes. These indexes have different\n"
- "internal formats between your old and new clusters, so they must be\n"
- "reindexed with the REINDEX command. The file\n"
- " %s\n"
- "when executed by psql by the database superuser will recreate all invalid\n"
- "indexes; until then, none of these indexes will be used.",
- output_path);
- }
- else
- check_ok();
-}
-
/*
* Callback function for processing results of query for
* report_extension_updates()'s UpgradeTask. If the query returned any rows,
--
2.50.1 (Apple Git-155)
--aHl3HfeiUuO3zeNC
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v6-0003-psql-bump-minimum-supported-version-to-v10.patch
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Add default_char_signedness field to ControlFileData.
- 44fe30fdab67 18.0 cited
-
Add defenses against running with a wrong selection of LOBLKSIZE.
- 5f93c37805e7 9.4.0 cited