0001-rough-draft-of-skipping-bogus-offsets.patch.txt
text/plain
Filename: 0001-rough-draft-of-skipping-bogus-offsets.patch.txt
Type: text/plain
Part: 0
Message:
Re: POC: make mxidoff 64 bits
From c2ccb107bef898420e6417c37d56c6b30578d28f Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Thu, 4 Dec 2025 17:02:35 +0300
Subject: [PATCH] rough draft of skipping bogus offsets
---
src/bin/pg_upgrade/multixact_old.c | 38 ++++++++++++++++++++++++------
src/bin/pg_upgrade/multixact_old.h | 2 +-
src/bin/pg_upgrade/pg_upgrade.c | 15 ++++++------
3 files changed, 40 insertions(+), 15 deletions(-)
diff --git a/src/bin/pg_upgrade/multixact_old.c b/src/bin/pg_upgrade/multixact_old.c
index 529eeeb93b6..685bfaeff82 100644
--- a/src/bin/pg_upgrade/multixact_old.c
+++ b/src/bin/pg_upgrade/multixact_old.c
@@ -136,7 +136,7 @@ AllocOldMultiXactRead(char *pgdata, MultiXactId nextMulti,
* - Because there's no concurrent activity, We don't need to worry about
* locking and some corner cases.
*/
-void
+bool
GetOldMultiXactIdSingleMember(OldMultiXactReader *state, MultiXactId multi,
TransactionId *result, MultiXactStatus *status)
{
@@ -189,7 +189,18 @@ GetOldMultiXactIdSingleMember(OldMultiXactReader *state, MultiXactId multi,
offptr += entryno;
offset = *offptr;
- Assert(offset != 0);
+ if (offset == 0)
+ {
+ pg_log(PG_WARNING, "multixact %u, offset is empty", multi);
+ return false;
+ }
+#if 0
+ if ( <more checks> )
+ {
+ pg_log(PG_WARNING, "multixact %u, offset is bogus", multi);
+ return false;
+ }
+#endif
/*
* Use the same increment rule as GetNewMultiXactId(), that is, don't
@@ -224,9 +235,13 @@ GetOldMultiXactIdSingleMember(OldMultiXactReader *state, MultiXactId multi,
/*
* Corner case 2: next multixact is still being filled in, this cannot
- * happen during upgrade.
+ * happen during upgrade, but if it does, complain.
*/
- Assert(nextMXOffset != 0);
+ if (nextMXOffset == 0)
+ {
+ pg_log(PG_WARNING, "multixact next to %u is empty", multi);
+ return false;
+ }
length = nextMXOffset - offset;
}
@@ -272,8 +287,11 @@ GetOldMultiXactIdSingleMember(OldMultiXactReader *state, MultiXactId multi,
{
/* sanity check */
if (result_isupdate)
- pg_fatal("multixact %u has more than one updating member",
- multi);
+ {
+ pg_log(PG_WARNING,
+ "multixact %u has more than one updating member", multi);
+ return false;
+ }
result_xid = *xactptr;
result_isupdate = true;
}
@@ -282,11 +300,17 @@ GetOldMultiXactIdSingleMember(OldMultiXactReader *state, MultiXactId multi,
}
/* A multixid with zero members should not happen */
- Assert(TransactionIdIsValid(result_xid));
+ if (!TransactionIdIsValid(result_xid))
+ {
+ pg_log(PG_WARNING, "multixact %u have zero members", multi);
+ return false;
+ }
*result = result_xid;
*status = result_isupdate ? MultiXactStatusUpdate :
MultiXactStatusForKeyShare;
+
+ return true;
}
/*
diff --git a/src/bin/pg_upgrade/multixact_old.h b/src/bin/pg_upgrade/multixact_old.h
index 4f9e086a1fb..b7352159d83 100644
--- a/src/bin/pg_upgrade/multixact_old.h
+++ b/src/bin/pg_upgrade/multixact_old.h
@@ -29,7 +29,7 @@ typedef struct OldMultiXactReader
extern OldMultiXactReader *AllocOldMultiXactRead(char *pgdata,
MultiXactId nextMulti,
OldMultiXactOffset nextOffset);
-extern void GetOldMultiXactIdSingleMember(OldMultiXactReader *state,
+extern bool GetOldMultiXactIdSingleMember(OldMultiXactReader *state,
MultiXactId multi,
TransactionId *result,
MultiXactStatus *status);
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index ff937b9e104..c5da56fe785 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -832,14 +832,15 @@ convert_multixacts(MultiXactId from_multi, MultiXactId to_multi)
* one updating one, or if there was no update, arbitrarily the
* first locking xid.
*/
- GetOldMultiXactIdSingleMember(old_reader, multi, &xid, &status);
+ if (GetOldMultiXactIdSingleMember(old_reader, multi, &xid, &status))
+ {
+ /* Write it out in new format */
+ member.xid = xid;
+ member.status = status;
+ RecordNewMultiXact(new_writer, next_offset, multi, 1, &member);
+ next_offset += 1;
+ }
- /* Write it out in new format */
- member.xid = xid;
- member.status = status;
- RecordNewMultiXact(new_writer, next_offset, multi, 1, &member);
-
- next_offset += 1;
multi++;
/* handle wraparound */
if (multi < FirstMultiXactId)
--
2.43.0