0002-Check-is-first-and-last-multis-exists.patch.txt

text/plain

Filename: 0002-Check-is-first-and-last-multis-exists.patch.txt
Type: text/plain
Part: 1
Message: Re: POC: make mxidoff 64 bits
From 0ac8eb292c21a06da31215aa41adb53ec1f90872 Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Thu, 4 Dec 2025 18:31:37 +0300
Subject: [PATCH 2/2] Check is first and last multis exists

---
 src/bin/pg_upgrade/multixact_old.c | 10 ++++++++++
 src/bin/pg_upgrade/multixact_old.h |  2 ++
 src/bin/pg_upgrade/pg_upgrade.c    | 23 +++++++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/src/bin/pg_upgrade/multixact_old.c b/src/bin/pg_upgrade/multixact_old.c
index 685bfaeff82..ffd06ad908f 100644
--- a/src/bin/pg_upgrade/multixact_old.c
+++ b/src/bin/pg_upgrade/multixact_old.c
@@ -324,3 +324,13 @@ FreeOldMultiXactReader(OldMultiXactReader *state)
 
 	pfree(state);
 }
+
+void
+CheckOldMultiXactIdExist(OldMultiXactReader *state, MultiXactId multi)
+{
+	int64 pageno = MultiXactIdToOffsetPage(multi);
+	char *buf = SlruReadSwitchPage(state->offset, pageno);
+
+	if (!buf)
+		pg_fatal("could not read multixact %u", multi);
+}
diff --git a/src/bin/pg_upgrade/multixact_old.h b/src/bin/pg_upgrade/multixact_old.h
index b7352159d83..86141ac392f 100644
--- a/src/bin/pg_upgrade/multixact_old.h
+++ b/src/bin/pg_upgrade/multixact_old.h
@@ -34,5 +34,7 @@ extern bool GetOldMultiXactIdSingleMember(OldMultiXactReader *state,
 										  TransactionId *result,
 										  MultiXactStatus *status);
 extern void FreeOldMultiXactReader(OldMultiXactReader *reader);
+extern void CheckOldMultiXactIdExist(OldMultiXactReader *state,
+									 MultiXactId multi);
 
 #endif							/* MULTIXACT_OLD_H */
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index c5da56fe785..647e05f350a 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -772,6 +772,21 @@ copy_subdir_files(const char *old_subdir, const char *new_subdir)
 	check_ok();
 }
 
+static void
+check_multixacts(MultiXactId from_multi, MultiXactId to_multi)
+{
+	OldMultiXactReader *reader;
+
+	reader = AllocOldMultiXactRead(old_cluster.pgdata,
+								   old_cluster.controldata.chkpnt_nxtmulti,
+								   old_cluster.controldata.chkpnt_nxtmxoff);
+
+	CheckOldMultiXactIdExist(reader, from_multi);
+	CheckOldMultiXactIdExist(reader, to_multi);
+
+	FreeOldMultiXactReader(reader);
+}
+
 /*
  * Convert pg_multixact/offset and /members from the old format with 32-bit
  * offsets.
@@ -958,6 +973,14 @@ copy_xact_xlog_xid(void)
 		remove_new_subdir("pg_multixact/members", false);
 		remove_new_subdir("pg_multixact/offsets", false);
 
+		/*
+		 * Before the actual conversion do sanity check.
+		 * XXX: place it properly, it should be better place for this
+		 */
+		prep_status("Sanity check pg_multixact files");
+		check_multixacts(oldstMulti, nxtmulti);
+		check_ok();
+
 		/*
 		 * Create new pg_multixact files, converting old ones if needed.
 		 */
-- 
2.43.0