v6-0011-Enlarge-OID-generation-to-8-bytes.patch
text/x-diff
Filename: v6-0011-Enlarge-OID-generation-to-8-bytes.patch
Type: text/x-diff
Part: 10
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: format-patch
Series: patch v6-0011
Subject: Enlarge OID generation to 8 bytes
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/pg_resetwal.sgml | 3 | 3 |
| src/backend/access/rmgrdesc/xlogdesc.c | 4 | 4 |
| src/backend/access/transam/varsup.c | 44 | 18 |
| src/backend/access/transam/xlog.c | 4 | 4 |
| src/backend/access/transam/xlogrecovery.c | 1 | 1 |
| src/bin/pg_controldata/pg_controldata.c | 1 | 1 |
| src/bin/pg_resetwal/pg_resetwal.c | 5 | 5 |
| src/include/access/transam.h | 2 | 1 |
| src/include/access/xlog.h | 1 | 1 |
| src/include/catalog/pg_control.h | 1 | 1 |
From 704484b94e6e3ae44ce89799e8b64bb2cf8f2a07 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 14 Aug 2025 12:15:15 +0900
Subject: [PATCH v6 11/15] Enlarge OID generation to 8 bytes
This adds a new routine called GetNewObjectId8() in varsup.c, which is
able to retrieve a 64b OID. GetNewObjectId() is kept compatible with
its origin, where we still check that the lower 32 bits of the counter
do not wraparound, handling the FirstNormalObjectId case.
pg_resetwal -o/--next-oid is updated to be able to handle 8-byte OIDs.
---
src/include/access/transam.h | 3 +-
src/include/access/xlog.h | 2 +-
src/include/catalog/pg_control.h | 2 +-
src/backend/access/rmgrdesc/xlogdesc.c | 8 +--
src/backend/access/transam/varsup.c | 62 ++++++++++++++++-------
src/backend/access/transam/xlog.c | 8 +--
src/backend/access/transam/xlogrecovery.c | 2 +-
src/bin/pg_controldata/pg_controldata.c | 2 +-
src/bin/pg_resetwal/pg_resetwal.c | 10 ++--
doc/src/sgml/ref/pg_resetwal.sgml | 6 +--
10 files changed, 66 insertions(+), 39 deletions(-)
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index 7d82cd2eb562..2ef3000bdb1f 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -211,7 +211,7 @@ typedef struct TransamVariablesData
/*
* These fields are protected by OidGenLock.
*/
- Oid nextOid; /* next OID to assign */
+ Oid8 nextOid; /* next OID (8 bytes) to assign */
uint32 oidCount; /* OIDs available before must do XLOG work */
/*
@@ -293,6 +293,7 @@ extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
extern void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid);
extern bool ForceTransactionIdLimitUpdate(void);
extern Oid GetNewObjectId(void);
+extern Oid8 GetNewObjectId8(void);
extern void StopGeneratingPinnedObjectIds(void);
#ifdef USE_ASSERT_CHECKING
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index d12798be3d80..21d915ae5802 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -243,7 +243,7 @@ extern void ShutdownXLOG(int code, Datum arg);
extern bool CreateCheckPoint(int flags);
extern bool CreateRestartPoint(int flags);
extern WALAvailability GetWALAvailability(XLogRecPtr targetLSN);
-extern void XLogPutNextOid(Oid nextOid);
+extern void XLogPutNextOid(Oid8 nextOid);
extern XLogRecPtr XLogRestorePoint(const char *rpName);
extern void UpdateFullPageWrites(void);
extern void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p);
diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h
index 63e834a6ce47..c85c84bbfdbb 100644
--- a/src/include/catalog/pg_control.h
+++ b/src/include/catalog/pg_control.h
@@ -42,7 +42,7 @@ typedef struct CheckPoint
bool fullPageWrites; /* current full_page_writes */
int wal_level; /* current wal_level */
FullTransactionId nextXid; /* next free transaction ID */
- Oid nextOid; /* next free OID */
+ Oid8 nextOid; /* next free OID */
MultiXactId nextMulti; /* next free MultiXactId */
MultiXactOffset nextMultiOffset; /* next free MultiXact offset */
TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */
diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index cd6c2a2f650a..23920d32092a 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -66,7 +66,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
CheckPoint *checkpoint = (CheckPoint *) rec;
appendStringInfo(buf, "redo %X/%08X; "
- "tli %u; prev tli %u; fpw %s; wal_level %s; xid %u:%u; oid %u; multi %u; offset %u; "
+ "tli %u; prev tli %u; fpw %s; wal_level %s; xid %u:%u; oid " OID8_FORMAT "; multi %u; offset %u; "
"oldest xid %u in DB %u; oldest multi %u in DB %u; "
"oldest/newest commit timestamp xid: %u/%u; "
"oldest running xid %u; %s",
@@ -91,10 +91,10 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
}
else if (info == XLOG_NEXTOID)
{
- Oid nextOid;
+ Oid8 nextOid;
- memcpy(&nextOid, rec, sizeof(Oid));
- appendStringInfo(buf, "%u", nextOid);
+ memcpy(&nextOid, rec, sizeof(Oid8));
+ appendStringInfo(buf, OID8_FORMAT, nextOid);
}
else if (info == XLOG_RESTORE_POINT)
{
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index f8c4dada7c93..662d1dcaed16 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -542,31 +542,51 @@ ForceTransactionIdLimitUpdate(void)
/*
- * GetNewObjectId -- allocate a new OID
+ * GetNewObjectId -- allocate a new OID (4 bytes)
*
- * OIDs are generated by a cluster-wide counter. Since they are only 32 bits
- * wide, counter wraparound will occur eventually, and therefore it is unwise
- * to assume they are unique unless precautions are taken to make them so.
- * Hence, this routine should generally not be used directly. The only direct
- * callers should be GetNewOidWithIndex() and GetNewRelFileNumber() in
- * catalog/catalog.c.
+ * OIDs are generated by a cluster-wide counter. The callers of this routine
+ * expect a 32 bit-wide counter, and counter wraparound will occur eventually,
+ * and therefore it is unwise to assume they are unique unless precautions are
+ * taken to make them so. This routine should generally not be used directly.
+ * The only direct callers should be GetNewOidWithIndex() and
+ * GetNewRelFileNumber() in catalog/catalog.c.
*/
Oid
GetNewObjectId(void)
{
- Oid result;
+ return (Oid) GetNewObjectId8();
+}
+
+/*
+ * GetNewObjectId8 -- allocate a new OID (8 bytes)
+ *
+ * This routine can be called directly if the consumer of the OID allocated
+ * stores the counter in an 8-byte space, where wraparound does not matter.
+ * We still need to care about the wraparound case in the low 32 bits of the
+ * space allocated, GetNewObjectId() expecting OIDs to never be allocated
+ * up to FirstNormalObjectId.
+ */
+Oid8
+GetNewObjectId8(void)
+{
+ Oid8 result;
+ Oid nextoid_lo;
+ uint32 nextoid_hi;
/* safety check, we should never get this far in a HS standby */
if (RecoveryInProgress())
elog(ERROR, "cannot assign OIDs during recovery");
LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
+ nextoid_lo = (Oid) TransamVariables->nextOid;
+ nextoid_hi = (uint32) (TransamVariables->nextOid >> 32);
/*
- * Check for wraparound of the OID counter. We *must* not return 0
- * (InvalidOid), and in normal operation we mustn't return anything below
- * FirstNormalObjectId since that range is reserved for initdb (see
- * IsCatalogRelationOid()). Note we are relying on unsigned comparison.
+ * Check for wraparound of the OID counter in its lower 4 bytes. We
+ * *must* not return 0 (InvalidOid), and in normal operation we
+ * mustn't return anything below FirstNormalObjectId since that range
+ * is reserved for initdb (see IsCatalogRelationOid()). Note we are
+ * relying on unsigned comparison.
*
* During initdb, we start the OID generator at FirstGenbkiObjectId, so we
* only wrap if before that point when in bootstrap or standalone mode.
@@ -576,26 +596,32 @@ GetNewObjectId(void)
* available for automatic assignment during initdb, while ensuring they
* will never conflict with user-assigned OIDs.
*/
- if (TransamVariables->nextOid < ((Oid) FirstNormalObjectId))
+ if (nextoid_lo < ((Oid) FirstNormalObjectId))
{
if (IsPostmasterEnvironment)
{
/* wraparound, or first post-initdb assignment, in normal mode */
- TransamVariables->nextOid = FirstNormalObjectId;
+ nextoid_lo = FirstNormalObjectId;
TransamVariables->oidCount = 0;
}
else
{
/* we may be bootstrapping, so don't enforce the full range */
- if (TransamVariables->nextOid < ((Oid) FirstGenbkiObjectId))
+ if (nextoid_lo < ((Oid) FirstGenbkiObjectId))
{
/* wraparound in standalone mode (unlikely but possible) */
- TransamVariables->nextOid = FirstNormalObjectId;
+ nextoid_lo = FirstNormalObjectId;
TransamVariables->oidCount = 0;
}
}
}
+ /*
+ * Set next OID in its 8-byte space, skipping the first post-init
+ * assignment.
+ */
+ TransamVariables->nextOid = ((Oid8) nextoid_hi) << 32 | nextoid_lo;
+
/* If we run out of logged for use oids then we must log more */
if (TransamVariables->oidCount == 0)
{
@@ -620,7 +646,7 @@ GetNewObjectId(void)
* to the specified value.
*/
static void
-SetNextObjectId(Oid nextOid)
+SetNextObjectId(Oid8 nextOid)
{
/* Safety check, this is only allowable during initdb */
if (IsPostmasterEnvironment)
@@ -630,7 +656,7 @@ SetNextObjectId(Oid nextOid)
LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
if (TransamVariables->nextOid > nextOid)
- elog(ERROR, "too late to advance OID counter to %u, it is now %u",
+ elog(ERROR, "too late to advance OID counter to " OID8_FORMAT ", it is now " OID8_FORMAT,
nextOid, TransamVariables->nextOid);
TransamVariables->nextOid = nextOid;
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 0baf0ac6160a..adfaea15b103 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8052,10 +8052,10 @@ KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
* Write a NEXTOID log record
*/
void
-XLogPutNextOid(Oid nextOid)
+XLogPutNextOid(Oid8 nextOid)
{
XLogBeginInsert();
- XLogRegisterData(&nextOid, sizeof(Oid));
+ XLogRegisterData(&nextOid, sizeof(Oid8));
(void) XLogInsert(RM_XLOG_ID, XLOG_NEXTOID);
/*
@@ -8278,7 +8278,7 @@ xlog_redo(XLogReaderState *record)
if (info == XLOG_NEXTOID)
{
- Oid nextOid;
+ Oid8 nextOid;
/*
* We used to try to take the maximum of TransamVariables->nextOid and
@@ -8287,7 +8287,7 @@ xlog_redo(XLogReaderState *record)
* anyway, better to just believe the record exactly. We still take
* OidGenLock while setting the variable, just in case.
*/
- memcpy(&nextOid, XLogRecGetData(record), sizeof(Oid));
+ memcpy(&nextOid, XLogRecGetData(record), sizeof(Oid8));
LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
TransamVariables->nextOid = nextOid;
TransamVariables->oidCount = 0;
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 346319338a0e..f19f6511c778 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -880,7 +880,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
LSN_FORMAT_ARGS(checkPoint.redo),
wasShutdown ? "true" : "false"));
ereport(DEBUG1,
- (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: %u",
+ (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: " OID8_FORMAT,
U64FromFullTransactionId(checkPoint.nextXid),
checkPoint.nextOid)));
ereport(DEBUG1,
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 10de058ce91f..992111d3a1d2 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -260,7 +260,7 @@ main(int argc, char *argv[])
printf(_("Latest checkpoint's NextXID: %u:%u\n"),
EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid),
XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid));
- printf(_("Latest checkpoint's NextOID: %u\n"),
+ printf(_("Latest checkpoint's NextOID: " OID8_FORMAT "\n"),
ControlFile->checkPointCopy.nextOid);
printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
ControlFile->checkPointCopy.nextMulti);
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index 7a4e4eb95706..c1039a8a4d16 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -68,7 +68,7 @@ static TransactionId set_oldest_xid = 0;
static TransactionId set_xid = 0;
static TransactionId set_oldest_commit_ts_xid = 0;
static TransactionId set_newest_commit_ts_xid = 0;
-static Oid set_oid = 0;
+static Oid8 set_oid = 0;
static MultiXactId set_mxid = 0;
static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
static TimeLineID minXlogTli = 0;
@@ -225,7 +225,7 @@ main(int argc, char *argv[])
case 'o':
errno = 0;
- set_oid = strtoul(optarg, &endptr, 0);
+ set_oid = strtou64(optarg, &endptr, 0);
if (endptr == optarg || *endptr != '\0' || errno != 0)
{
pg_log_error("invalid argument for option %s", "-o");
@@ -755,7 +755,7 @@ PrintControlValues(bool guessed)
printf(_("Latest checkpoint's NextXID: %u:%u\n"),
EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid),
XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid));
- printf(_("Latest checkpoint's NextOID: %u\n"),
+ printf(_("Latest checkpoint's NextOID: " OID8_FORMAT "\n"),
ControlFile.checkPointCopy.nextOid);
printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
ControlFile.checkPointCopy.nextMulti);
@@ -839,7 +839,7 @@ PrintNewControlValues(void)
if (set_oid != 0)
{
- printf(_("NextOID: %u\n"),
+ printf(_("NextOID: " OID8_FORMAT "\n"),
ControlFile.checkPointCopy.nextOid);
}
@@ -1208,7 +1208,7 @@ usage(void)
printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
- printf(_(" -o, --next-oid=OID set next OID\n"));
+ printf(_(" -o, --next-oid=OID8 set next OID (8 bytes)\n"));
printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n"));
printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml
index 2c019c2aac6e..b03251cedbbe 100644
--- a/doc/src/sgml/ref/pg_resetwal.sgml
+++ b/doc/src/sgml/ref/pg_resetwal.sgml
@@ -279,11 +279,11 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
- <term><option>-o <replaceable class="parameter">oid</replaceable></option></term>
- <term><option>--next-oid=<replaceable class="parameter">oid</replaceable></option></term>
+ <term><option>-o <replaceable class="parameter">oid8</replaceable></option></term>
+ <term><option>--next-oid=<replaceable class="parameter">oid8</replaceable></option></term>
<listitem>
<para>
- Manually set the next OID.
+ Manually set the next OID (8 bytes).
</para>
<para>
--
2.51.0