mirror of
https://github.com/postgres/postgres.git
synced 2025-04-20 00:42:27 +03:00
Improve accounting for PredXactList, RWConflictPool and PGPROC
Various places allocated shared memory by first allocating a small chunk using ShmemInitStruct(), followed by ShmemAlloc() calls to allocate more memory. Unfortunately, ShmemAlloc() does not update ShmemIndex, so this affected pg_shmem_allocations - it only shown the initial chunk. This commit modifies the following allocations, to allocate everything as a single chunk, and then split it internally. - PredXactList - RWConflictPool - PGPROC structures - Fast-Path Lock Array The fast-path lock array is allocated separately, not as a part of the PGPROC structures allocation. Author: Rahila Syed <rahilasyed90@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com> Reviewed-by: Tomas Vondra <tomas@vondra.me> Discussion: https://postgr.es/m/CAH2L28vHzRankszhqz7deXURxKncxfirnuW68zD7+hVAqaS5GQ@mail.gmail.com
This commit is contained in:
parent
f5930f9a98
commit
46df9487d9
@ -1226,14 +1226,21 @@ PredicateLockShmemInit(void)
|
|||||||
*/
|
*/
|
||||||
max_table_size *= 10;
|
max_table_size *= 10;
|
||||||
|
|
||||||
|
requestSize = add_size(PredXactListDataSize,
|
||||||
|
(mul_size((Size) max_table_size,
|
||||||
|
sizeof(SERIALIZABLEXACT))));
|
||||||
|
|
||||||
PredXact = ShmemInitStruct("PredXactList",
|
PredXact = ShmemInitStruct("PredXactList",
|
||||||
PredXactListDataSize,
|
requestSize,
|
||||||
&found);
|
&found);
|
||||||
Assert(found == IsUnderPostmaster);
|
Assert(found == IsUnderPostmaster);
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* clean everything, both the header and the element */
|
||||||
|
memset(PredXact, 0, requestSize);
|
||||||
|
|
||||||
dlist_init(&PredXact->availableList);
|
dlist_init(&PredXact->availableList);
|
||||||
dlist_init(&PredXact->activeList);
|
dlist_init(&PredXact->activeList);
|
||||||
PredXact->SxactGlobalXmin = InvalidTransactionId;
|
PredXact->SxactGlobalXmin = InvalidTransactionId;
|
||||||
@ -1242,11 +1249,9 @@ PredicateLockShmemInit(void)
|
|||||||
PredXact->LastSxactCommitSeqNo = FirstNormalSerCommitSeqNo - 1;
|
PredXact->LastSxactCommitSeqNo = FirstNormalSerCommitSeqNo - 1;
|
||||||
PredXact->CanPartialClearThrough = 0;
|
PredXact->CanPartialClearThrough = 0;
|
||||||
PredXact->HavePartialClearedThrough = 0;
|
PredXact->HavePartialClearedThrough = 0;
|
||||||
requestSize = mul_size((Size) max_table_size,
|
PredXact->element
|
||||||
sizeof(SERIALIZABLEXACT));
|
= (SERIALIZABLEXACT *) ((char *) PredXact + PredXactListDataSize);
|
||||||
PredXact->element = ShmemAlloc(requestSize);
|
|
||||||
/* Add all elements to available list, clean. */
|
/* Add all elements to available list, clean. */
|
||||||
memset(PredXact->element, 0, requestSize);
|
|
||||||
for (i = 0; i < max_table_size; i++)
|
for (i = 0; i < max_table_size; i++)
|
||||||
{
|
{
|
||||||
LWLockInitialize(&PredXact->element[i].perXactPredicateListLock,
|
LWLockInitialize(&PredXact->element[i].perXactPredicateListLock,
|
||||||
@ -1300,20 +1305,25 @@ PredicateLockShmemInit(void)
|
|||||||
*/
|
*/
|
||||||
max_table_size *= 5;
|
max_table_size *= 5;
|
||||||
|
|
||||||
|
requestSize = RWConflictPoolHeaderDataSize +
|
||||||
|
mul_size((Size) max_table_size,
|
||||||
|
RWConflictDataSize);
|
||||||
|
|
||||||
RWConflictPool = ShmemInitStruct("RWConflictPool",
|
RWConflictPool = ShmemInitStruct("RWConflictPool",
|
||||||
RWConflictPoolHeaderDataSize,
|
requestSize,
|
||||||
&found);
|
&found);
|
||||||
Assert(found == IsUnderPostmaster);
|
Assert(found == IsUnderPostmaster);
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* clean everything, including the elements */
|
||||||
|
memset(RWConflictPool, 0, requestSize);
|
||||||
|
|
||||||
dlist_init(&RWConflictPool->availableList);
|
dlist_init(&RWConflictPool->availableList);
|
||||||
requestSize = mul_size((Size) max_table_size,
|
RWConflictPool->element = (RWConflict) ((char *) RWConflictPool +
|
||||||
RWConflictDataSize);
|
RWConflictPoolHeaderDataSize);
|
||||||
RWConflictPool->element = ShmemAlloc(requestSize);
|
|
||||||
/* Add all elements to available list, clean. */
|
/* Add all elements to available list, clean. */
|
||||||
memset(RWConflictPool->element, 0, requestSize);
|
|
||||||
for (i = 0; i < max_table_size; i++)
|
for (i = 0; i < max_table_size; i++)
|
||||||
{
|
{
|
||||||
dlist_push_tail(&RWConflictPool->availableList,
|
dlist_push_tail(&RWConflictPool->availableList,
|
||||||
|
@ -91,10 +91,28 @@ static void CheckDeadLock(void);
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Report shared-memory space needed by InitProcGlobal.
|
* Report shared-memory space needed by PGPROC.
|
||||||
*/
|
*/
|
||||||
Size
|
static Size
|
||||||
ProcGlobalShmemSize(void)
|
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)));
|
||||||
|
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
|
||||||
|
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Report shared-memory space needed by Fast-Path locks.
|
||||||
|
*/
|
||||||
|
static Size
|
||||||
|
FastPathLockShmemSize(void)
|
||||||
{
|
{
|
||||||
Size size = 0;
|
Size size = 0;
|
||||||
Size TotalProcs =
|
Size TotalProcs =
|
||||||
@ -102,15 +120,6 @@ ProcGlobalShmemSize(void)
|
|||||||
Size fpLockBitsSize,
|
Size fpLockBitsSize,
|
||||||
fpRelIdSize;
|
fpRelIdSize;
|
||||||
|
|
||||||
/* ProcGlobal */
|
|
||||||
size = add_size(size, sizeof(PROC_HDR));
|
|
||||||
size = add_size(size, mul_size(TotalProcs, sizeof(PGPROC)));
|
|
||||||
size = add_size(size, sizeof(slock_t));
|
|
||||||
|
|
||||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
|
|
||||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
|
|
||||||
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Memory needed for PGPROC fast-path lock arrays. Make sure the sizes are
|
* Memory needed for PGPROC fast-path lock arrays. Make sure the sizes are
|
||||||
* nicely aligned in each backend.
|
* nicely aligned in each backend.
|
||||||
@ -123,6 +132,24 @@ ProcGlobalShmemSize(void)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Report shared-memory space needed by InitProcGlobal.
|
||||||
|
*/
|
||||||
|
Size
|
||||||
|
ProcGlobalShmemSize(void)
|
||||||
|
{
|
||||||
|
Size size = 0;
|
||||||
|
|
||||||
|
/* ProcGlobal */
|
||||||
|
size = add_size(size, sizeof(PROC_HDR));
|
||||||
|
size = add_size(size, sizeof(slock_t));
|
||||||
|
|
||||||
|
size = add_size(size, PGProcShmemSize());
|
||||||
|
size = add_size(size, FastPathLockShmemSize());
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Report number of semaphores needed by InitProcGlobal.
|
* Report number of semaphores needed by InitProcGlobal.
|
||||||
*/
|
*/
|
||||||
@ -175,6 +202,8 @@ InitProcGlobal(void)
|
|||||||
*fpEndPtr PG_USED_FOR_ASSERTS_ONLY;
|
*fpEndPtr PG_USED_FOR_ASSERTS_ONLY;
|
||||||
Size fpLockBitsSize,
|
Size fpLockBitsSize,
|
||||||
fpRelIdSize;
|
fpRelIdSize;
|
||||||
|
Size requestSize;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
/* Create the ProcGlobal shared structure */
|
/* Create the ProcGlobal shared structure */
|
||||||
ProcGlobal = (PROC_HDR *)
|
ProcGlobal = (PROC_HDR *)
|
||||||
@ -204,8 +233,17 @@ InitProcGlobal(void)
|
|||||||
* with a single freelist.) Each PGPROC structure is dedicated to exactly
|
* with a single freelist.) Each PGPROC structure is dedicated to exactly
|
||||||
* one of these purposes, and they do not move between groups.
|
* one of these purposes, and they do not move between groups.
|
||||||
*/
|
*/
|
||||||
procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
|
requestSize = PGProcShmemSize();
|
||||||
MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
|
|
||||||
|
ptr = ShmemInitStruct("PGPROC structures",
|
||||||
|
requestSize,
|
||||||
|
&found);
|
||||||
|
|
||||||
|
MemSet(ptr, 0, requestSize);
|
||||||
|
|
||||||
|
procs = (PGPROC *) ptr;
|
||||||
|
ptr = (char *) ptr + TotalProcs * sizeof(PGPROC);
|
||||||
|
|
||||||
ProcGlobal->allProcs = procs;
|
ProcGlobal->allProcs = procs;
|
||||||
/* XXX allProcCount isn't really all of them; it excludes prepared xacts */
|
/* XXX allProcCount isn't really all of them; it excludes prepared xacts */
|
||||||
ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS;
|
ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS;
|
||||||
@ -217,13 +255,17 @@ InitProcGlobal(void)
|
|||||||
* XXX: It might make sense to increase padding for these arrays, given
|
* XXX: It might make sense to increase padding for these arrays, given
|
||||||
* how hotly they are accessed.
|
* how hotly they are accessed.
|
||||||
*/
|
*/
|
||||||
ProcGlobal->xids =
|
ProcGlobal->xids = (TransactionId *) ptr;
|
||||||
(TransactionId *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->xids));
|
ptr = (char *) ptr + (TotalProcs * sizeof(*ProcGlobal->xids));
|
||||||
MemSet(ProcGlobal->xids, 0, TotalProcs * sizeof(*ProcGlobal->xids));
|
|
||||||
ProcGlobal->subxidStates = (XidCacheStatus *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->subxidStates));
|
ProcGlobal->subxidStates = (XidCacheStatus *) ptr;
|
||||||
MemSet(ProcGlobal->subxidStates, 0, TotalProcs * sizeof(*ProcGlobal->subxidStates));
|
ptr = (char *) ptr + (TotalProcs * sizeof(*ProcGlobal->subxidStates));
|
||||||
ProcGlobal->statusFlags = (uint8 *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->statusFlags));
|
|
||||||
MemSet(ProcGlobal->statusFlags, 0, TotalProcs * sizeof(*ProcGlobal->statusFlags));
|
ProcGlobal->statusFlags = (uint8 *) ptr;
|
||||||
|
ptr = (char *) ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags));
|
||||||
|
|
||||||
|
/* make sure wer didn't overflow */
|
||||||
|
Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate arrays for fast-path locks. Those are variable-length, so
|
* Allocate arrays for fast-path locks. Those are variable-length, so
|
||||||
@ -233,11 +275,16 @@ InitProcGlobal(void)
|
|||||||
fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
|
fpLockBitsSize = MAXALIGN(FastPathLockGroupsPerBackend * sizeof(uint64));
|
||||||
fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
|
fpRelIdSize = MAXALIGN(FastPathLockSlotsPerBackend() * sizeof(Oid));
|
||||||
|
|
||||||
fpPtr = ShmemAlloc(TotalProcs * (fpLockBitsSize + fpRelIdSize));
|
requestSize = FastPathLockShmemSize();
|
||||||
MemSet(fpPtr, 0, TotalProcs * (fpLockBitsSize + fpRelIdSize));
|
|
||||||
|
fpPtr = ShmemInitStruct("Fast-Path Lock Array",
|
||||||
|
requestSize,
|
||||||
|
&found);
|
||||||
|
|
||||||
|
MemSet(fpPtr, 0, requestSize);
|
||||||
|
|
||||||
/* For asserts checking we did not overflow. */
|
/* For asserts checking we did not overflow. */
|
||||||
fpEndPtr = fpPtr + (TotalProcs * (fpLockBitsSize + fpRelIdSize));
|
fpEndPtr = fpPtr + requestSize;
|
||||||
|
|
||||||
for (i = 0; i < TotalProcs; i++)
|
for (i = 0; i < TotalProcs; i++)
|
||||||
{
|
{
|
||||||
@ -330,7 +377,9 @@ InitProcGlobal(void)
|
|||||||
PreparedXactProcs = &procs[MaxBackends + NUM_AUXILIARY_PROCS];
|
PreparedXactProcs = &procs[MaxBackends + NUM_AUXILIARY_PROCS];
|
||||||
|
|
||||||
/* Create ProcStructLock spinlock, too */
|
/* Create ProcStructLock spinlock, too */
|
||||||
ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
|
ProcStructLock = (slock_t *) ShmemInitStruct("ProcStructLock spinlock",
|
||||||
|
sizeof(slock_t),
|
||||||
|
&found);
|
||||||
SpinLockInit(ProcStructLock);
|
SpinLockInit(ProcStructLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user