v4-0001-Add-precalculated-proc-counts-to-reduce-repetitio.patch
text/x-patch
Filename: v4-0001-Add-precalculated-proc-counts-to-reduce-repetitio.patch
Type: text/x-patch
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: format-patch
Series: patch v4-0001
Subject: Add precalculated proc counts to reduce repetition.
| File | + | − |
|---|---|---|
| src/backend/access/transam/multixact.c | 1 | 1 |
| src/backend/access/transam/xlogwait.c | 3 | 4 |
| src/backend/postmaster/launch_backend.c | 4 | 0 |
| src/backend/storage/aio/aio_init.c | 2 | 2 |
| src/backend/storage/aio/method_io_uring.c | 1 | 1 |
| src/backend/storage/buffer/bufmgr.c | 1 | 1 |
| src/backend/storage/ipc/procarray.c | 1 | 1 |
| src/backend/storage/ipc/procsignal.c | 1 | 1 |
| src/backend/storage/ipc/sinvaladt.c | 1 | 1 |
| src/backend/storage/lmgr/lock.c | 4 | 5 |
| src/backend/storage/lmgr/predicate.c | 5 | 8 |
| src/backend/storage/lmgr/proc.c | 4 | 9 |
| src/backend/utils/activity/backend_status.c | 1 | 1 |
| src/backend/utils/init/globals.c | 5 | 2 |
| src/backend/utils/init/postinit.c | 7 | 2 |
| src/include/miscadmin.h | 3 | 0 |
From a9db95d6f97300d49c5c3f8ac1ecb87c9d7cf429 Mon Sep 17 00:00:00 2001
From: Yura Sokolov <y.sokolov@postgrespro.ru>
Date: Thu, 26 Feb 2026 17:41:40 +0300
Subject: [PATCH v4 1/2] Add precalculated proc counts to reduce repetition.
Lets name common sums:
MaxBackends + NUM_AUXILIARY_PROCS => MaxChildren
MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts => TotalProcs
MaxBackends + max_prepared_xacts => TotalXactProcs
It also may simplify api for extension.
---
src/backend/access/transam/multixact.c | 2 +-
src/backend/access/transam/xlogwait.c | 7 +++----
src/backend/postmaster/launch_backend.c | 4 ++++
src/backend/storage/aio/aio_init.c | 4 ++--
src/backend/storage/aio/method_io_uring.c | 2 +-
src/backend/storage/buffer/bufmgr.c | 2 +-
src/backend/storage/ipc/procarray.c | 2 +-
src/backend/storage/ipc/procsignal.c | 2 +-
src/backend/storage/ipc/sinvaladt.c | 2 +-
src/backend/storage/lmgr/lock.c | 9 ++++-----
src/backend/storage/lmgr/predicate.c | 13 +++++--------
src/backend/storage/lmgr/proc.c | 13 ++++---------
src/backend/utils/activity/backend_status.c | 2 +-
src/backend/utils/init/globals.c | 7 +++++--
src/backend/utils/init/postinit.c | 9 +++++++--
src/include/miscadmin.h | 3 +++
16 files changed, 44 insertions(+), 39 deletions(-)
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 90ec87d9dd6..a35671ea346 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -210,7 +210,7 @@ typedef struct MultiXactStateData
/*
* Size of OldestMemberMXactId and OldestVisibleMXactId arrays.
*/
-#define MaxOldestSlot (MaxBackends + max_prepared_xacts)
+#define MaxOldestSlot TotalXactProcs
/* Pointers to the state data in shared memory */
static MultiXactStateData *MultiXactState;
diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c
index d286ff63123..4c2f3085e34 100644
--- a/src/backend/access/transam/xlogwait.c
+++ b/src/backend/access/transam/xlogwait.c
@@ -115,7 +115,7 @@ WaitLSNShmemSize(void)
Size size;
size = offsetof(WaitLSNState, procInfos);
- size = add_size(size, mul_size(MaxBackends + NUM_AUXILIARY_PROCS, sizeof(WaitLSNProcInfo)));
+ size = add_size(size, mul_size(MaxChildren, sizeof(WaitLSNProcInfo)));
return size;
}
@@ -140,8 +140,7 @@ WaitLSNShmemInit(void)
}
/* Initialize process info array */
- memset(&waitLSNState->procInfos, 0,
- (MaxBackends + NUM_AUXILIARY_PROCS) * sizeof(WaitLSNProcInfo));
+ memset(&waitLSNState->procInfos, 0, MaxChildren * sizeof(WaitLSNProcInfo));
}
}
@@ -382,7 +381,7 @@ WaitForLSN(WaitLSNType lsnType, XLogRecPtr targetLSN, int64 timeout)
Assert(waitLSNState);
/* Should have a valid proc number */
- Assert(MyProcNumber >= 0 && MyProcNumber < MaxBackends + NUM_AUXILIARY_PROCS);
+ Assert(MyProcNumber >= 0 && MyProcNumber < MaxChildren);
if (timeout > 0)
{
diff --git a/src/backend/postmaster/launch_backend.c b/src/backend/postmaster/launch_backend.c
index e9134b9751b..1b5c5b7f550 100644
--- a/src/backend/postmaster/launch_backend.c
+++ b/src/backend/postmaster/launch_backend.c
@@ -62,6 +62,7 @@
#ifdef EXEC_BACKEND
+#include "access/twophase.h"
#include "common/file_utils.h"
#include "storage/fd.h"
#include "storage/lwlock.h"
@@ -1010,6 +1011,9 @@ restore_backend_variables(BackendParameters *param)
max_safe_fds = param->max_safe_fds;
MaxBackends = param->MaxBackends;
+ MaxChildren = MaxBackends + NUM_AUXILIARY_PROCS;
+ TotalProcs = MaxChildren + max_prepared_xacts;
+ TotalXactProcs = MaxBackends + max_prepared_xacts;
num_pmchild_slots = param->num_pmchild_slots;
#ifdef WIN32
diff --git a/src/backend/storage/aio/aio_init.c b/src/backend/storage/aio/aio_init.c
index d3c68d8b04c..df1e750e802 100644
--- a/src/backend/storage/aio/aio_init.c
+++ b/src/backend/storage/aio/aio_init.c
@@ -42,7 +42,7 @@ AioProcs(void)
* guarantee that nothing gets assigned to an IO worker's ProcNumber if we
* just subtracted MAX_IO_WORKERS.
*/
- return MaxBackends + NUM_AUXILIARY_PROCS;
+ return MaxChildren;
}
static Size
@@ -100,7 +100,7 @@ AioChooseMaxConcurrency(void)
int max_proportional_pins;
/* Similar logic to LimitAdditionalPins() */
- max_backends = MaxBackends + NUM_AUXILIARY_PROCS;
+ max_backends = MaxChildren;
max_proportional_pins = NBuffers / max_backends;
max_proportional_pins = Max(max_proportional_pins, 1);
diff --git a/src/backend/storage/aio/method_io_uring.c b/src/backend/storage/aio/method_io_uring.c
index ed6e71bcd46..904deeb724f 100644
--- a/src/backend/storage/aio/method_io_uring.c
+++ b/src/backend/storage/aio/method_io_uring.c
@@ -131,7 +131,7 @@ pgaio_uring_procs(void)
* We can subtract MAX_IO_WORKERS here as io workers are never used at the
* same time as io_method=io_uring.
*/
- return MaxBackends + NUM_AUXILIARY_PROCS - MAX_IO_WORKERS;
+ return MaxChildren - MAX_IO_WORKERS;
}
/*
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index d1babaff023..c1d6306a073 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -4129,7 +4129,7 @@ InitBufferManagerAccess(void)
* allow plenty of pins. LimitAdditionalPins() and
* GetAdditionalPinLimit() can be used to check the remaining balance.
*/
- MaxProportionalPins = NBuffers / (MaxBackends + NUM_AUXILIARY_PROCS);
+ MaxProportionalPins = NBuffers / MaxChildren;
memset(&PrivateRefCountArray, 0, sizeof(PrivateRefCountArray));
memset(&PrivateRefCountArrayKeys, 0, sizeof(PrivateRefCountArrayKeys));
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 40312df2cac..807c292f481 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -381,7 +381,7 @@ ProcArrayShmemSize(void)
Size size;
/* Size of the ProcArray structure itself */
-#define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts)
+#define PROCARRAY_MAXPROCS TotalXactProcs
size = offsetof(ProcArrayStruct, pgprocnos);
size = add_size(size, mul_size(sizeof(int), PROCARRAY_MAXPROCS));
diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c
index 7505c9d3a37..4694f645805 100644
--- a/src/backend/storage/ipc/procsignal.c
+++ b/src/backend/storage/ipc/procsignal.c
@@ -93,7 +93,7 @@ struct ProcSignalHeader
* more than one of any auxiliary process type at a time, except for
* IO workers.)
*/
-#define NumProcSignalSlots (MaxBackends + NUM_AUXILIARY_PROCS)
+#define NumProcSignalSlots MaxChildren
/* Check whether the relevant type bit is set in the flags. */
#define BARRIER_SHOULD_CHECK(flags, type) \
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index a7a7cc4f0a9..ec030b9466b 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -201,7 +201,7 @@ typedef struct SISeg
* more than one of any auxiliary process type at a time, except for
* IO workers.)
*/
-#define NumProcStateSlots (MaxBackends + NUM_AUXILIARY_PROCS)
+#define NumProcStateSlots MaxChildren
static SISeg *shmInvalBuffer; /* pointer to the shared inval buffer */
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index d930c66cdbd..d3294200c2c 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -53,8 +53,7 @@
int max_locks_per_xact; /* used to set the lock table size */
bool log_lock_failures = false;
-#define NLOCKENTS() \
- mul_size(max_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
+#define NLOCKENTS() mul_size(max_locks_per_xact, TotalXactProcs)
/*
@@ -3097,10 +3096,10 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
vxids = (VirtualTransactionId *)
MemoryContextAlloc(TopMemoryContext,
sizeof(VirtualTransactionId) *
- (MaxBackends + max_prepared_xacts + 1));
+ (TotalXactProcs + 1));
}
else
- vxids = palloc0_array(VirtualTransactionId, (MaxBackends + max_prepared_xacts + 1));
+ vxids = palloc0_array(VirtualTransactionId, (TotalXactProcs + 1));
/* Compute hash code and partition lock, and look up conflicting modes. */
hashcode = LockTagHashCode(locktag);
@@ -3259,7 +3258,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
LWLockRelease(partitionLock);
- if (count > MaxBackends + max_prepared_xacts) /* should never happen */
+ if (count > TotalXactProcs) /* should never happen */
elog(PANIC, "too many conflicting locks found");
vxids[count].procNumber = INVALID_PROC_NUMBER;
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index fe75ead3501..5a14422ad4c 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -261,8 +261,7 @@
#define PredicateLockHashPartitionLockByIndex(i) \
(&MainLWLockArray[PREDICATELOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
-#define NPREDICATELOCKTARGETENTS() \
- mul_size(max_predicate_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
+#define NPREDICATELOCKTARGETENTS() mul_size(max_predicate_locks_per_xact, TotalXactProcs)
#define SxactIsOnFinishedList(sxact) (!dlist_node_is_detached(&(sxact)->finishedLink))
@@ -1214,7 +1213,7 @@ PredicateLockShmemInit(void)
* Compute size for serializable transaction hashtable. Note these
* calculations must agree with PredicateLockShmemSize!
*/
- max_table_size = (MaxBackends + max_prepared_xacts);
+ max_table_size = TotalXactProcs;
/*
* Allocate a list to hold information on transactions participating in
@@ -1376,7 +1375,7 @@ PredicateLockShmemSize(void)
size = add_size(size, size / 10);
/* transaction list */
- max_table_size = MaxBackends + max_prepared_xacts;
+ max_table_size = TotalXactProcs;
max_table_size *= 10;
size = add_size(size, PredXactListDataSize);
size = add_size(size, mul_size((Size) max_table_size,
@@ -1902,8 +1901,7 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
else
{
++(PredXact->WritableSxactCount);
- Assert(PredXact->WritableSxactCount <=
- (MaxBackends + max_prepared_xacts));
+ Assert(PredXact->WritableSxactCount <= TotalXactProcs);
}
/* Maintain serializable global xmin info. */
@@ -4965,8 +4963,7 @@ predicatelock_twophase_recover(FullTransactionId fxid, uint16 info,
if (!SxactIsReadOnly(sxact))
{
++(PredXact->WritableSxactCount);
- Assert(PredXact->WritableSxactCount <=
- (MaxBackends + max_prepared_xacts));
+ Assert(PredXact->WritableSxactCount <= TotalXactProcs);
}
/*
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 771b006b522..52cc3c7c702 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -87,8 +87,6 @@ static Size
PGProcShmemSize(void)
{
Size size = 0;
- Size TotalProcs =
- add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
@@ -105,8 +103,6 @@ static Size
FastPathLockShmemSize(void)
{
Size size = 0;
- Size TotalProcs =
- add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
Size fpLockBitsSize,
fpRelIdSize;
@@ -151,7 +147,7 @@ ProcGlobalSemas(void)
* We need a sema per backend (including autovacuum), plus one for each
* auxiliary process.
*/
- return MaxBackends + NUM_AUXILIARY_PROCS;
+ return MaxChildren;
}
/*
@@ -186,7 +182,6 @@ InitProcGlobal(void)
int i,
j;
bool found;
- uint32 TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
/* Used for setup of per-backend fast-path slots. */
char *fpPtr,
@@ -238,7 +233,7 @@ InitProcGlobal(void)
ProcGlobal->allProcs = procs;
/* XXX allProcCount isn't really all of them; it excludes prepared xacts */
- ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS;
+ ProcGlobal->allProcCount = MaxChildren;
/*
* Allocate arrays mirroring PGPROC fields in a dense manner. See
@@ -304,7 +299,7 @@ InitProcGlobal(void)
* dummy PGPROCs don't need these though - they're never associated
* with a real process
*/
- if (i < MaxBackends + NUM_AUXILIARY_PROCS)
+ if (i < MaxChildren)
{
proc->sem = PGSemaphoreCreate();
InitSharedLatch(&(proc->procLatch));
@@ -369,7 +364,7 @@ InitProcGlobal(void)
* processes and prepared transactions.
*/
AuxiliaryProcs = &procs[MaxBackends];
- PreparedXactProcs = &procs[MaxBackends + NUM_AUXILIARY_PROCS];
+ PreparedXactProcs = &procs[MaxChildren];
}
/*
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index cd087129469..ed797da6bee 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -32,7 +32,7 @@
* real processes.)
* ----------
*/
-#define NumBackendStatSlots (MaxBackends + NUM_AUXILIARY_PROCS)
+#define NumBackendStatSlots MaxChildren
/* ----------
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 36ad708b360..1fbef826a8b 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -136,14 +136,17 @@ int max_parallel_maintenance_workers = 2;
/*
* Primary determinants of sizes of shared-memory structures.
*
- * MaxBackends is computed by PostmasterMain after modules have had a chance to
- * register background workers.
+ * MaxBackends, MaxChildren and TotalProcs are computed by PostmasterMain after
+ * modules have had a chance to register background workers.
*/
int NBuffers = 16384;
int MaxConnections = 100;
int max_worker_processes = 8;
int max_parallel_workers = 8;
int MaxBackends = 0;
+int MaxChildren = 0;
+int TotalProcs = 0;
+int TotalXactProcs = 0;
/* GUC parameters for vacuum */
int VacuumBufferUsageLimit = 2048;
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index b59e08605cc..cc295878868 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -24,6 +24,7 @@
#include "access/htup_details.h"
#include "access/session.h"
#include "access/tableam.h"
+#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
@@ -563,14 +564,18 @@ InitializeMaxBackends(void)
MaxBackends = MaxConnections + autovacuum_worker_slots +
max_worker_processes + max_wal_senders + NUM_SPECIAL_WORKER_PROCS;
- if (MaxBackends > MAX_BACKENDS)
+ MaxChildren = MaxBackends + NUM_AUXILIARY_PROCS;
+ if (MaxChildren > MAX_BACKENDS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("too many server processes configured"),
errdetail("\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d.",
MaxConnections, autovacuum_worker_slots,
max_worker_processes, max_wal_senders,
- MAX_BACKENDS - (NUM_SPECIAL_WORKER_PROCS - 1))));
+ MAX_BACKENDS - NUM_AUXILIARY_PROCS - (NUM_SPECIAL_WORKER_PROCS - 1))));
+
+ TotalProcs = MaxChildren + max_prepared_xacts;
+ TotalXactProcs = MaxBackends + max_prepared_xacts;
}
/*
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index f16f35659b9..b2498455ea4 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -175,6 +175,9 @@ extern PGDLLIMPORT int data_directory_mode;
extern PGDLLIMPORT int NBuffers;
extern PGDLLIMPORT int MaxBackends;
+extern PGDLLIMPORT int MaxChildren;
+extern PGDLLIMPORT int TotalProcs;
+extern PGDLLIMPORT int TotalXactProcs;
extern PGDLLIMPORT int MaxConnections;
extern PGDLLIMPORT int max_worker_processes;
extern PGDLLIMPORT int max_parallel_workers;
--
2.51.0