Revert the addition of GetMaxBackends() and related stuff.
This reverts commits0147fc7
,4567596
,aa64f23
, and5ecd018
. There is no longer agreement that introducing this function was the right way to address the problem. The consensus now seems to favor trying to make a correct value for MaxBackends available to mdules executing their _PG_init() functions. Nathan Bossart Discussion: http://postgr.es/m/20220323045229.i23skfscdbvrsuxa@jrouhaud
This commit is contained in:
parent
2c9381840f
commit
7fc0e7de9f
|
@ -2072,7 +2072,7 @@ BTreeShmemSize(void)
|
||||||
Size size;
|
Size size;
|
||||||
|
|
||||||
size = offsetof(BTVacInfo, vacuums);
|
size = offsetof(BTVacInfo, vacuums);
|
||||||
size = add_size(size, mul_size(GetMaxBackends(), sizeof(BTOneVacInfo)));
|
size = add_size(size, mul_size(MaxBackends, sizeof(BTOneVacInfo)));
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2101,7 +2101,7 @@ BTreeShmemInit(void)
|
||||||
btvacinfo->cycle_ctr = (BTCycleId) time(NULL);
|
btvacinfo->cycle_ctr = (BTCycleId) time(NULL);
|
||||||
|
|
||||||
btvacinfo->num_vacuums = 0;
|
btvacinfo->num_vacuums = 0;
|
||||||
btvacinfo->max_vacuums = GetMaxBackends();
|
btvacinfo->max_vacuums = MaxBackends;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Assert(found);
|
Assert(found);
|
||||||
|
|
|
@ -282,11 +282,12 @@ typedef struct MultiXactStateData
|
||||||
} MultiXactStateData;
|
} MultiXactStateData;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pointers to the state data in shared memory
|
* Last element of OldestMemberMXactId and OldestVisibleMXactId arrays.
|
||||||
*
|
* Valid elements are (1..MaxOldestSlot); element 0 is never used.
|
||||||
* The index of the last element of the OldestMemberMXactId and
|
|
||||||
* OldestVisibleMXactId arrays can be obtained with GetMaxOldestSlot().
|
|
||||||
*/
|
*/
|
||||||
|
#define MaxOldestSlot (MaxBackends + max_prepared_xacts)
|
||||||
|
|
||||||
|
/* Pointers to the state data in shared memory */
|
||||||
static MultiXactStateData *MultiXactState;
|
static MultiXactStateData *MultiXactState;
|
||||||
static MultiXactId *OldestMemberMXactId;
|
static MultiXactId *OldestMemberMXactId;
|
||||||
static MultiXactId *OldestVisibleMXactId;
|
static MultiXactId *OldestVisibleMXactId;
|
||||||
|
@ -341,7 +342,6 @@ static void MultiXactIdSetOldestVisible(void);
|
||||||
static void RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset,
|
static void RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset,
|
||||||
int nmembers, MultiXactMember *members);
|
int nmembers, MultiXactMember *members);
|
||||||
static MultiXactId GetNewMultiXactId(int nmembers, MultiXactOffset *offset);
|
static MultiXactId GetNewMultiXactId(int nmembers, MultiXactOffset *offset);
|
||||||
static inline int GetMaxOldestSlot(void);
|
|
||||||
|
|
||||||
/* MultiXact cache management */
|
/* MultiXact cache management */
|
||||||
static int mxactMemberComparator(const void *arg1, const void *arg2);
|
static int mxactMemberComparator(const void *arg1, const void *arg2);
|
||||||
|
@ -662,17 +662,6 @@ MultiXactIdSetOldestMember(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve the index of the last element of the OldestMemberMXactId and
|
|
||||||
* OldestVisibleMXactId arrays. Valid elements are (1..MaxOldestSlot); element
|
|
||||||
* 0 is never used.
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
GetMaxOldestSlot(void)
|
|
||||||
{
|
|
||||||
return GetMaxBackends() + max_prepared_xacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MultiXactIdSetOldestVisible
|
* MultiXactIdSetOldestVisible
|
||||||
* Save the oldest MultiXactId this transaction considers possibly live.
|
* Save the oldest MultiXactId this transaction considers possibly live.
|
||||||
|
@ -695,7 +684,6 @@ MultiXactIdSetOldestVisible(void)
|
||||||
if (!MultiXactIdIsValid(OldestVisibleMXactId[MyBackendId]))
|
if (!MultiXactIdIsValid(OldestVisibleMXactId[MyBackendId]))
|
||||||
{
|
{
|
||||||
MultiXactId oldestMXact;
|
MultiXactId oldestMXact;
|
||||||
int maxOldestSlot = GetMaxOldestSlot();
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE);
|
LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE);
|
||||||
|
@ -709,7 +697,7 @@ MultiXactIdSetOldestVisible(void)
|
||||||
if (oldestMXact < FirstMultiXactId)
|
if (oldestMXact < FirstMultiXactId)
|
||||||
oldestMXact = FirstMultiXactId;
|
oldestMXact = FirstMultiXactId;
|
||||||
|
|
||||||
for (i = 1; i <= maxOldestSlot; i++)
|
for (i = 1; i <= MaxOldestSlot; i++)
|
||||||
{
|
{
|
||||||
MultiXactId thisoldest = OldestMemberMXactId[i];
|
MultiXactId thisoldest = OldestMemberMXactId[i];
|
||||||
|
|
||||||
|
@ -1843,7 +1831,7 @@ MultiXactShmemSize(void)
|
||||||
/* We need 2*MaxOldestSlot + 1 perBackendXactIds[] entries */
|
/* We need 2*MaxOldestSlot + 1 perBackendXactIds[] entries */
|
||||||
#define SHARED_MULTIXACT_STATE_SIZE \
|
#define SHARED_MULTIXACT_STATE_SIZE \
|
||||||
add_size(offsetof(MultiXactStateData, perBackendXactIds) + sizeof(MultiXactId), \
|
add_size(offsetof(MultiXactStateData, perBackendXactIds) + sizeof(MultiXactId), \
|
||||||
mul_size(sizeof(MultiXactId) * 2, GetMaxOldestSlot()))
|
mul_size(sizeof(MultiXactId) * 2, MaxOldestSlot))
|
||||||
|
|
||||||
size = SHARED_MULTIXACT_STATE_SIZE;
|
size = SHARED_MULTIXACT_STATE_SIZE;
|
||||||
size = add_size(size, SimpleLruShmemSize(NUM_MULTIXACTOFFSET_BUFFERS, 0));
|
size = add_size(size, SimpleLruShmemSize(NUM_MULTIXACTOFFSET_BUFFERS, 0));
|
||||||
|
@ -1894,7 +1882,7 @@ MultiXactShmemInit(void)
|
||||||
* since we only use indexes 1..MaxOldestSlot in each array.
|
* since we only use indexes 1..MaxOldestSlot in each array.
|
||||||
*/
|
*/
|
||||||
OldestMemberMXactId = MultiXactState->perBackendXactIds;
|
OldestMemberMXactId = MultiXactState->perBackendXactIds;
|
||||||
OldestVisibleMXactId = OldestMemberMXactId + GetMaxOldestSlot();
|
OldestVisibleMXactId = OldestMemberMXactId + MaxOldestSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2519,7 +2507,6 @@ GetOldestMultiXactId(void)
|
||||||
{
|
{
|
||||||
MultiXactId oldestMXact;
|
MultiXactId oldestMXact;
|
||||||
MultiXactId nextMXact;
|
MultiXactId nextMXact;
|
||||||
int maxOldestSlot = GetMaxOldestSlot();
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2538,7 +2525,7 @@ GetOldestMultiXactId(void)
|
||||||
nextMXact = FirstMultiXactId;
|
nextMXact = FirstMultiXactId;
|
||||||
|
|
||||||
oldestMXact = nextMXact;
|
oldestMXact = nextMXact;
|
||||||
for (i = 1; i <= maxOldestSlot; i++)
|
for (i = 1; i <= MaxOldestSlot; i++)
|
||||||
{
|
{
|
||||||
MultiXactId thisoldest;
|
MultiXactId thisoldest;
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,6 @@ TwoPhaseShmemInit(void)
|
||||||
{
|
{
|
||||||
GlobalTransaction gxacts;
|
GlobalTransaction gxacts;
|
||||||
int i;
|
int i;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
Assert(!found);
|
Assert(!found);
|
||||||
TwoPhaseState->freeGXacts = NULL;
|
TwoPhaseState->freeGXacts = NULL;
|
||||||
|
@ -298,7 +297,7 @@ TwoPhaseShmemInit(void)
|
||||||
* prepared transaction. Currently multixact.c uses that
|
* prepared transaction. Currently multixact.c uses that
|
||||||
* technique.
|
* technique.
|
||||||
*/
|
*/
|
||||||
gxacts[i].dummyBackendId = max_backends + 1 + i;
|
gxacts[i].dummyBackendId = MaxBackends + 1 + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -518,7 +518,7 @@ AsyncShmemSize(void)
|
||||||
Size size;
|
Size size;
|
||||||
|
|
||||||
/* This had better match AsyncShmemInit */
|
/* This had better match AsyncShmemInit */
|
||||||
size = mul_size(GetMaxBackends() + 1, sizeof(QueueBackendStatus));
|
size = mul_size(MaxBackends + 1, sizeof(QueueBackendStatus));
|
||||||
size = add_size(size, offsetof(AsyncQueueControl, backend));
|
size = add_size(size, offsetof(AsyncQueueControl, backend));
|
||||||
|
|
||||||
size = add_size(size, SimpleLruShmemSize(NUM_NOTIFY_BUFFERS, 0));
|
size = add_size(size, SimpleLruShmemSize(NUM_NOTIFY_BUFFERS, 0));
|
||||||
|
@ -534,7 +534,6 @@ AsyncShmemInit(void)
|
||||||
{
|
{
|
||||||
bool found;
|
bool found;
|
||||||
Size size;
|
Size size;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create or attach to the AsyncQueueControl structure.
|
* Create or attach to the AsyncQueueControl structure.
|
||||||
|
@ -542,7 +541,7 @@ AsyncShmemInit(void)
|
||||||
* The used entries in the backend[] array run from 1 to MaxBackends; the
|
* The used entries in the backend[] array run from 1 to MaxBackends; the
|
||||||
* zero'th entry is unused but must be allocated.
|
* zero'th entry is unused but must be allocated.
|
||||||
*/
|
*/
|
||||||
size = mul_size(max_backends + 1, sizeof(QueueBackendStatus));
|
size = mul_size(MaxBackends + 1, sizeof(QueueBackendStatus));
|
||||||
size = add_size(size, offsetof(AsyncQueueControl, backend));
|
size = add_size(size, offsetof(AsyncQueueControl, backend));
|
||||||
|
|
||||||
asyncQueueControl = (AsyncQueueControl *)
|
asyncQueueControl = (AsyncQueueControl *)
|
||||||
|
@ -557,7 +556,7 @@ AsyncShmemInit(void)
|
||||||
QUEUE_FIRST_LISTENER = InvalidBackendId;
|
QUEUE_FIRST_LISTENER = InvalidBackendId;
|
||||||
asyncQueueControl->lastQueueFillWarn = 0;
|
asyncQueueControl->lastQueueFillWarn = 0;
|
||||||
/* zero'th entry won't be used, but let's initialize it anyway */
|
/* zero'th entry won't be used, but let's initialize it anyway */
|
||||||
for (int i = 0; i <= max_backends; i++)
|
for (int i = 0; i <= MaxBackends; i++)
|
||||||
{
|
{
|
||||||
QUEUE_BACKEND_PID(i) = InvalidPid;
|
QUEUE_BACKEND_PID(i) = InvalidPid;
|
||||||
QUEUE_BACKEND_DBOID(i) = InvalidOid;
|
QUEUE_BACKEND_DBOID(i) = InvalidOid;
|
||||||
|
@ -1633,7 +1632,6 @@ SignalBackends(void)
|
||||||
int32 *pids;
|
int32 *pids;
|
||||||
BackendId *ids;
|
BackendId *ids;
|
||||||
int count;
|
int count;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Identify backends that we need to signal. We don't want to send
|
* Identify backends that we need to signal. We don't want to send
|
||||||
|
@ -1643,8 +1641,8 @@ SignalBackends(void)
|
||||||
* XXX in principle these pallocs could fail, which would be bad. Maybe
|
* XXX in principle these pallocs could fail, which would be bad. Maybe
|
||||||
* preallocate the arrays? They're not that large, though.
|
* preallocate the arrays? They're not that large, though.
|
||||||
*/
|
*/
|
||||||
pids = (int32 *) palloc(max_backends * sizeof(int32));
|
pids = (int32 *) palloc(MaxBackends * sizeof(int32));
|
||||||
ids = (BackendId *) palloc(max_backends * sizeof(BackendId));
|
ids = (BackendId *) palloc(MaxBackends * sizeof(BackendId));
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE);
|
LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE);
|
||||||
|
|
|
@ -334,7 +334,6 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
|
||||||
struct addrinfo hint;
|
struct addrinfo hint;
|
||||||
int listen_index = 0;
|
int listen_index = 0;
|
||||||
int added = 0;
|
int added = 0;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
#ifdef HAVE_UNIX_SOCKETS
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
char unixSocketPath[MAXPGPATH];
|
char unixSocketPath[MAXPGPATH];
|
||||||
|
@ -557,7 +556,7 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber,
|
||||||
* intended to provide a clamp on the request on platforms where an
|
* intended to provide a clamp on the request on platforms where an
|
||||||
* overly large request provokes a kernel error (are there any?).
|
* overly large request provokes a kernel error (are there any?).
|
||||||
*/
|
*/
|
||||||
maxconn = max_backends * 2;
|
maxconn = MaxBackends * 2;
|
||||||
if (maxconn > PG_SOMAXCONN)
|
if (maxconn > PG_SOMAXCONN)
|
||||||
maxconn = PG_SOMAXCONN;
|
maxconn = PG_SOMAXCONN;
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ AuxiliaryProcessMain(AuxProcType auxtype)
|
||||||
* This will need rethinking if we ever want more than one of a particular
|
* This will need rethinking if we ever want more than one of a particular
|
||||||
* auxiliary process type.
|
* auxiliary process type.
|
||||||
*/
|
*/
|
||||||
ProcSignalInit(GetMaxBackends() + MyAuxProcType + 1);
|
ProcSignalInit(MaxBackends + MyAuxProcType + 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Auxiliary processes don't run transactions, but they may need a
|
* Auxiliary processes don't run transactions, but they may need a
|
||||||
|
|
|
@ -1005,8 +1005,10 @@ PostmasterMain(int argc, char *argv[])
|
||||||
LocalProcessControlFile(false);
|
LocalProcessControlFile(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the apply launcher. It's probably a good idea to call this
|
* Register the apply launcher. Since it registers a background worker,
|
||||||
* before any modules had a chance to take the background worker slots.
|
* it needs to be called before InitializeMaxBackends(), and it's probably
|
||||||
|
* a good idea to call it before any modules had chance to take the
|
||||||
|
* background worker slots.
|
||||||
*/
|
*/
|
||||||
ApplyLauncherRegister();
|
ApplyLauncherRegister();
|
||||||
|
|
||||||
|
@ -1027,8 +1029,8 @@ PostmasterMain(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that loadable modules have had their chance to alter any GUCs,
|
* Now that loadable modules have had their chance to register background
|
||||||
* calculate MaxBackends.
|
* workers, calculate MaxBackends.
|
||||||
*/
|
*/
|
||||||
InitializeMaxBackends();
|
InitializeMaxBackends();
|
||||||
|
|
||||||
|
@ -6142,7 +6144,7 @@ save_backend_variables(BackendParameters *param, Port *port,
|
||||||
param->query_id_enabled = query_id_enabled;
|
param->query_id_enabled = query_id_enabled;
|
||||||
param->max_safe_fds = max_safe_fds;
|
param->max_safe_fds = max_safe_fds;
|
||||||
|
|
||||||
param->MaxBackends = GetMaxBackends();
|
param->MaxBackends = MaxBackends;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
param->PostmasterHandle = PostmasterHandle;
|
param->PostmasterHandle = PostmasterHandle;
|
||||||
|
@ -6375,7 +6377,7 @@ restore_backend_variables(BackendParameters *param, Port *port)
|
||||||
query_id_enabled = param->query_id_enabled;
|
query_id_enabled = param->query_id_enabled;
|
||||||
max_safe_fds = param->max_safe_fds;
|
max_safe_fds = param->max_safe_fds;
|
||||||
|
|
||||||
SetMaxBackends(param->MaxBackends);
|
MaxBackends = param->MaxBackends;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
PostmasterHandle = param->PostmasterHandle;
|
PostmasterHandle = param->PostmasterHandle;
|
||||||
|
|
|
@ -166,7 +166,7 @@ dsm_postmaster_startup(PGShmemHeader *shim)
|
||||||
|
|
||||||
/* Determine size for new control segment. */
|
/* Determine size for new control segment. */
|
||||||
maxitems = PG_DYNSHMEM_FIXED_SLOTS
|
maxitems = PG_DYNSHMEM_FIXED_SLOTS
|
||||||
+ PG_DYNSHMEM_SLOTS_PER_BACKEND * GetMaxBackends();
|
+ PG_DYNSHMEM_SLOTS_PER_BACKEND * MaxBackends;
|
||||||
elog(DEBUG2, "dynamic shared memory system will support %u segments",
|
elog(DEBUG2, "dynamic shared memory system will support %u segments",
|
||||||
maxitems);
|
maxitems);
|
||||||
segsize = dsm_control_bytes_needed(maxitems);
|
segsize = dsm_control_bytes_needed(maxitems);
|
||||||
|
|
|
@ -97,7 +97,7 @@ typedef struct ProcArrayStruct
|
||||||
/* oldest catalog xmin of any replication slot */
|
/* oldest catalog xmin of any replication slot */
|
||||||
TransactionId replication_slot_catalog_xmin;
|
TransactionId replication_slot_catalog_xmin;
|
||||||
|
|
||||||
/* indexes into allProcs[], has ProcArrayMaxProcs entries */
|
/* indexes into allProcs[], has PROCARRAY_MAXPROCS entries */
|
||||||
int pgprocnos[FLEXIBLE_ARRAY_MEMBER];
|
int pgprocnos[FLEXIBLE_ARRAY_MEMBER];
|
||||||
} ProcArrayStruct;
|
} ProcArrayStruct;
|
||||||
|
|
||||||
|
@ -355,17 +355,6 @@ static void MaintainLatestCompletedXidRecovery(TransactionId latestXid);
|
||||||
static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
|
static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
|
||||||
TransactionId xid);
|
TransactionId xid);
|
||||||
static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
|
static void GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons);
|
||||||
static inline int GetProcArrayMaxProcs(void);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve the number of slots in the ProcArray structure.
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
GetProcArrayMaxProcs(void)
|
|
||||||
{
|
|
||||||
return GetMaxBackends() + max_prepared_xacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Report shared-memory space needed by CreateSharedProcArray.
|
* Report shared-memory space needed by CreateSharedProcArray.
|
||||||
|
@ -376,8 +365,10 @@ ProcArrayShmemSize(void)
|
||||||
Size size;
|
Size size;
|
||||||
|
|
||||||
/* Size of the ProcArray structure itself */
|
/* Size of the ProcArray structure itself */
|
||||||
|
#define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts)
|
||||||
|
|
||||||
size = offsetof(ProcArrayStruct, pgprocnos);
|
size = offsetof(ProcArrayStruct, pgprocnos);
|
||||||
size = add_size(size, mul_size(sizeof(int), GetProcArrayMaxProcs()));
|
size = add_size(size, mul_size(sizeof(int), PROCARRAY_MAXPROCS));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* During Hot Standby processing we have a data structure called
|
* During Hot Standby processing we have a data structure called
|
||||||
|
@ -393,7 +384,7 @@ ProcArrayShmemSize(void)
|
||||||
* shared memory is being set up.
|
* shared memory is being set up.
|
||||||
*/
|
*/
|
||||||
#define TOTAL_MAX_CACHED_SUBXIDS \
|
#define TOTAL_MAX_CACHED_SUBXIDS \
|
||||||
((PGPROC_MAX_CACHED_SUBXIDS + 1) * GetProcArrayMaxProcs())
|
((PGPROC_MAX_CACHED_SUBXIDS + 1) * PROCARRAY_MAXPROCS)
|
||||||
|
|
||||||
if (EnableHotStandby)
|
if (EnableHotStandby)
|
||||||
{
|
{
|
||||||
|
@ -420,7 +411,7 @@ CreateSharedProcArray(void)
|
||||||
ShmemInitStruct("Proc Array",
|
ShmemInitStruct("Proc Array",
|
||||||
add_size(offsetof(ProcArrayStruct, pgprocnos),
|
add_size(offsetof(ProcArrayStruct, pgprocnos),
|
||||||
mul_size(sizeof(int),
|
mul_size(sizeof(int),
|
||||||
GetProcArrayMaxProcs())),
|
PROCARRAY_MAXPROCS)),
|
||||||
&found);
|
&found);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
|
@ -429,7 +420,7 @@ CreateSharedProcArray(void)
|
||||||
* We're the first - initialize.
|
* We're the first - initialize.
|
||||||
*/
|
*/
|
||||||
procArray->numProcs = 0;
|
procArray->numProcs = 0;
|
||||||
procArray->maxProcs = GetProcArrayMaxProcs();
|
procArray->maxProcs = PROCARRAY_MAXPROCS;
|
||||||
procArray->maxKnownAssignedXids = TOTAL_MAX_CACHED_SUBXIDS;
|
procArray->maxKnownAssignedXids = TOTAL_MAX_CACHED_SUBXIDS;
|
||||||
procArray->numKnownAssignedXids = 0;
|
procArray->numKnownAssignedXids = 0;
|
||||||
procArray->tailKnownAssignedXids = 0;
|
procArray->tailKnownAssignedXids = 0;
|
||||||
|
@ -4645,7 +4636,7 @@ KnownAssignedXidsCompress(bool force)
|
||||||
*/
|
*/
|
||||||
int nelements = head - tail;
|
int nelements = head - tail;
|
||||||
|
|
||||||
if (nelements < 4 * GetProcArrayMaxProcs() ||
|
if (nelements < 4 * PROCARRAY_MAXPROCS ||
|
||||||
nelements < 2 * pArray->numKnownAssignedXids)
|
nelements < 2 * pArray->numKnownAssignedXids)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,13 @@ typedef struct
|
||||||
ProcSignalSlot psh_slot[FLEXIBLE_ARRAY_MEMBER];
|
ProcSignalSlot psh_slot[FLEXIBLE_ARRAY_MEMBER];
|
||||||
} ProcSignalHeader;
|
} ProcSignalHeader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We reserve a slot for each possible BackendId, plus one for each
|
||||||
|
* possible auxiliary process type. (This scheme assumes there is not
|
||||||
|
* more than one of any auxiliary process type at a time.)
|
||||||
|
*/
|
||||||
|
#define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES)
|
||||||
|
|
||||||
/* Check whether the relevant type bit is set in the flags. */
|
/* Check whether the relevant type bit is set in the flags. */
|
||||||
#define BARRIER_SHOULD_CHECK(flags, type) \
|
#define BARRIER_SHOULD_CHECK(flags, type) \
|
||||||
(((flags) & (((uint32) 1) << (uint32) (type))) != 0)
|
(((flags) & (((uint32) 1) << (uint32) (type))) != 0)
|
||||||
|
@ -95,20 +102,6 @@ static ProcSignalSlot *MyProcSignalSlot = NULL;
|
||||||
static bool CheckProcSignal(ProcSignalReason reason);
|
static bool CheckProcSignal(ProcSignalReason reason);
|
||||||
static void CleanupProcSignalState(int status, Datum arg);
|
static void CleanupProcSignalState(int status, Datum arg);
|
||||||
static void ResetProcSignalBarrierBits(uint32 flags);
|
static void ResetProcSignalBarrierBits(uint32 flags);
|
||||||
static inline int GetNumProcSignalSlots(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetNumProcSignalSlots
|
|
||||||
*
|
|
||||||
* We reserve a slot for each possible BackendId, plus one for each possible
|
|
||||||
* auxiliary process type. (This scheme assume there is not more than one of
|
|
||||||
* any auxiliary process type at a time.)
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
GetNumProcSignalSlots(void)
|
|
||||||
{
|
|
||||||
return GetMaxBackends() + NUM_AUXPROCTYPES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ProcSignalShmemSize
|
* ProcSignalShmemSize
|
||||||
|
@ -119,7 +112,7 @@ ProcSignalShmemSize(void)
|
||||||
{
|
{
|
||||||
Size size;
|
Size size;
|
||||||
|
|
||||||
size = mul_size(GetNumProcSignalSlots(), sizeof(ProcSignalSlot));
|
size = mul_size(NumProcSignalSlots, sizeof(ProcSignalSlot));
|
||||||
size = add_size(size, offsetof(ProcSignalHeader, psh_slot));
|
size = add_size(size, offsetof(ProcSignalHeader, psh_slot));
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +126,6 @@ ProcSignalShmemInit(void)
|
||||||
{
|
{
|
||||||
Size size = ProcSignalShmemSize();
|
Size size = ProcSignalShmemSize();
|
||||||
bool found;
|
bool found;
|
||||||
int numProcSignalSlots = GetNumProcSignalSlots();
|
|
||||||
|
|
||||||
ProcSignal = (ProcSignalHeader *)
|
ProcSignal = (ProcSignalHeader *)
|
||||||
ShmemInitStruct("ProcSignal", size, &found);
|
ShmemInitStruct("ProcSignal", size, &found);
|
||||||
|
@ -145,7 +137,7 @@ ProcSignalShmemInit(void)
|
||||||
|
|
||||||
pg_atomic_init_u64(&ProcSignal->psh_barrierGeneration, 0);
|
pg_atomic_init_u64(&ProcSignal->psh_barrierGeneration, 0);
|
||||||
|
|
||||||
for (i = 0; i < numProcSignalSlots; ++i)
|
for (i = 0; i < NumProcSignalSlots; ++i)
|
||||||
{
|
{
|
||||||
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
||||||
|
|
||||||
|
@ -171,7 +163,7 @@ ProcSignalInit(int pss_idx)
|
||||||
ProcSignalSlot *slot;
|
ProcSignalSlot *slot;
|
||||||
uint64 barrier_generation;
|
uint64 barrier_generation;
|
||||||
|
|
||||||
Assert(pss_idx >= 1 && pss_idx <= GetNumProcSignalSlots());
|
Assert(pss_idx >= 1 && pss_idx <= NumProcSignalSlots);
|
||||||
|
|
||||||
slot = &ProcSignal->psh_slot[pss_idx - 1];
|
slot = &ProcSignal->psh_slot[pss_idx - 1];
|
||||||
|
|
||||||
|
@ -300,7 +292,7 @@ SendProcSignal(pid_t pid, ProcSignalReason reason, BackendId backendId)
|
||||||
*/
|
*/
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = GetNumProcSignalSlots() - 1; i >= 0; i--)
|
for (i = NumProcSignalSlots - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
slot = &ProcSignal->psh_slot[i];
|
slot = &ProcSignal->psh_slot[i];
|
||||||
|
|
||||||
|
@ -341,7 +333,6 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
|
||||||
{
|
{
|
||||||
uint32 flagbit = 1 << (uint32) type;
|
uint32 flagbit = 1 << (uint32) type;
|
||||||
uint64 generation;
|
uint64 generation;
|
||||||
int numProcSignalSlots = GetNumProcSignalSlots();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set all the flags.
|
* Set all the flags.
|
||||||
|
@ -351,7 +342,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
|
||||||
* anything that we do afterwards. (This is also true of the later call to
|
* anything that we do afterwards. (This is also true of the later call to
|
||||||
* pg_atomic_add_fetch_u64.)
|
* pg_atomic_add_fetch_u64.)
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < numProcSignalSlots; i++)
|
for (int i = 0; i < NumProcSignalSlots; i++)
|
||||||
{
|
{
|
||||||
volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
||||||
|
|
||||||
|
@ -377,7 +368,7 @@ EmitProcSignalBarrier(ProcSignalBarrierType type)
|
||||||
* backends that need to update state - but they won't actually need to
|
* backends that need to update state - but they won't actually need to
|
||||||
* change any state.
|
* change any state.
|
||||||
*/
|
*/
|
||||||
for (int i = numProcSignalSlots - 1; i >= 0; i--)
|
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
||||||
pid_t pid = slot->pss_pid;
|
pid_t pid = slot->pss_pid;
|
||||||
|
@ -402,7 +393,7 @@ WaitForProcSignalBarrier(uint64 generation)
|
||||||
{
|
{
|
||||||
Assert(generation <= pg_atomic_read_u64(&ProcSignal->psh_barrierGeneration));
|
Assert(generation <= pg_atomic_read_u64(&ProcSignal->psh_barrierGeneration));
|
||||||
|
|
||||||
for (int i = GetNumProcSignalSlots() - 1; i >= 0; i--)
|
for (int i = NumProcSignalSlots - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
ProcSignalSlot *slot = &ProcSignal->psh_slot[i];
|
||||||
uint64 oldval;
|
uint64 oldval;
|
||||||
|
|
|
@ -213,7 +213,7 @@ SInvalShmemSize(void)
|
||||||
* free slot. This is because the autovacuum launcher and worker processes,
|
* free slot. This is because the autovacuum launcher and worker processes,
|
||||||
* which are included in MaxBackends, are not started in Hot Standby mode.
|
* which are included in MaxBackends, are not started in Hot Standby mode.
|
||||||
*/
|
*/
|
||||||
size = add_size(size, mul_size(sizeof(ProcState), GetMaxBackends()));
|
size = add_size(size, mul_size(sizeof(ProcState), MaxBackends));
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ CreateSharedInvalidationState(void)
|
||||||
shmInvalBuffer->maxMsgNum = 0;
|
shmInvalBuffer->maxMsgNum = 0;
|
||||||
shmInvalBuffer->nextThreshold = CLEANUP_MIN;
|
shmInvalBuffer->nextThreshold = CLEANUP_MIN;
|
||||||
shmInvalBuffer->lastBackend = 0;
|
shmInvalBuffer->lastBackend = 0;
|
||||||
shmInvalBuffer->maxBackends = GetMaxBackends();
|
shmInvalBuffer->maxBackends = MaxBackends;
|
||||||
SpinLockInit(&shmInvalBuffer->msgnumLock);
|
SpinLockInit(&shmInvalBuffer->msgnumLock);
|
||||||
|
|
||||||
/* The buffer[] array is initially all unused, so we need not fill it */
|
/* The buffer[] array is initially all unused, so we need not fill it */
|
||||||
|
|
|
@ -143,7 +143,6 @@ void
|
||||||
InitDeadLockChecking(void)
|
InitDeadLockChecking(void)
|
||||||
{
|
{
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
/* Make sure allocations are permanent */
|
/* Make sure allocations are permanent */
|
||||||
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
|
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
|
||||||
|
@ -152,16 +151,16 @@ InitDeadLockChecking(void)
|
||||||
* FindLockCycle needs at most MaxBackends entries in visitedProcs[] and
|
* FindLockCycle needs at most MaxBackends entries in visitedProcs[] and
|
||||||
* deadlockDetails[].
|
* deadlockDetails[].
|
||||||
*/
|
*/
|
||||||
visitedProcs = (PGPROC **) palloc(max_backends * sizeof(PGPROC *));
|
visitedProcs = (PGPROC **) palloc(MaxBackends * sizeof(PGPROC *));
|
||||||
deadlockDetails = (DEADLOCK_INFO *) palloc(max_backends * sizeof(DEADLOCK_INFO));
|
deadlockDetails = (DEADLOCK_INFO *) palloc(MaxBackends * sizeof(DEADLOCK_INFO));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TopoSort needs to consider at most MaxBackends wait-queue entries, and
|
* TopoSort needs to consider at most MaxBackends wait-queue entries, and
|
||||||
* it needn't run concurrently with FindLockCycle.
|
* it needn't run concurrently with FindLockCycle.
|
||||||
*/
|
*/
|
||||||
topoProcs = visitedProcs; /* re-use this space */
|
topoProcs = visitedProcs; /* re-use this space */
|
||||||
beforeConstraints = (int *) palloc(max_backends * sizeof(int));
|
beforeConstraints = (int *) palloc(MaxBackends * sizeof(int));
|
||||||
afterConstraints = (int *) palloc(max_backends * sizeof(int));
|
afterConstraints = (int *) palloc(MaxBackends * sizeof(int));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to consider rearranging at most MaxBackends/2 wait queues
|
* We need to consider rearranging at most MaxBackends/2 wait queues
|
||||||
|
@ -170,8 +169,8 @@ InitDeadLockChecking(void)
|
||||||
* MaxBackends total waiters.
|
* MaxBackends total waiters.
|
||||||
*/
|
*/
|
||||||
waitOrders = (WAIT_ORDER *)
|
waitOrders = (WAIT_ORDER *)
|
||||||
palloc((max_backends / 2) * sizeof(WAIT_ORDER));
|
palloc((MaxBackends / 2) * sizeof(WAIT_ORDER));
|
||||||
waitOrderProcs = (PGPROC **) palloc(max_backends * sizeof(PGPROC *));
|
waitOrderProcs = (PGPROC **) palloc(MaxBackends * sizeof(PGPROC *));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow at most MaxBackends distinct constraints in a configuration. (Is
|
* Allow at most MaxBackends distinct constraints in a configuration. (Is
|
||||||
|
@ -181,7 +180,7 @@ InitDeadLockChecking(void)
|
||||||
* limits the maximum recursion depth of DeadLockCheckRecurse. Making it
|
* limits the maximum recursion depth of DeadLockCheckRecurse. Making it
|
||||||
* really big might potentially allow a stack-overflow problem.
|
* really big might potentially allow a stack-overflow problem.
|
||||||
*/
|
*/
|
||||||
maxCurConstraints = max_backends;
|
maxCurConstraints = MaxBackends;
|
||||||
curConstraints = (EDGE *) palloc(maxCurConstraints * sizeof(EDGE));
|
curConstraints = (EDGE *) palloc(maxCurConstraints * sizeof(EDGE));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -192,7 +191,7 @@ InitDeadLockChecking(void)
|
||||||
* last MaxBackends entries in possibleConstraints[] are reserved as
|
* last MaxBackends entries in possibleConstraints[] are reserved as
|
||||||
* output workspace for FindLockCycle.
|
* output workspace for FindLockCycle.
|
||||||
*/
|
*/
|
||||||
maxPossibleConstraints = max_backends * 4;
|
maxPossibleConstraints = MaxBackends * 4;
|
||||||
possibleConstraints =
|
possibleConstraints =
|
||||||
(EDGE *) palloc(maxPossibleConstraints * sizeof(EDGE));
|
(EDGE *) palloc(maxPossibleConstraints * sizeof(EDGE));
|
||||||
|
|
||||||
|
@ -328,7 +327,7 @@ DeadLockCheckRecurse(PGPROC *proc)
|
||||||
if (nCurConstraints >= maxCurConstraints)
|
if (nCurConstraints >= maxCurConstraints)
|
||||||
return true; /* out of room for active constraints? */
|
return true; /* out of room for active constraints? */
|
||||||
oldPossibleConstraints = nPossibleConstraints;
|
oldPossibleConstraints = nPossibleConstraints;
|
||||||
if (nPossibleConstraints + nEdges + GetMaxBackends() <= maxPossibleConstraints)
|
if (nPossibleConstraints + nEdges + MaxBackends <= maxPossibleConstraints)
|
||||||
{
|
{
|
||||||
/* We can save the edge list in possibleConstraints[] */
|
/* We can save the edge list in possibleConstraints[] */
|
||||||
nPossibleConstraints += nEdges;
|
nPossibleConstraints += nEdges;
|
||||||
|
@ -389,7 +388,7 @@ TestConfiguration(PGPROC *startProc)
|
||||||
/*
|
/*
|
||||||
* Make sure we have room for FindLockCycle's output.
|
* Make sure we have room for FindLockCycle's output.
|
||||||
*/
|
*/
|
||||||
if (nPossibleConstraints + GetMaxBackends() > maxPossibleConstraints)
|
if (nPossibleConstraints + MaxBackends > maxPossibleConstraints)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -487,7 +486,7 @@ FindLockCycleRecurse(PGPROC *checkProc,
|
||||||
* record total length of cycle --- outer levels will now fill
|
* record total length of cycle --- outer levels will now fill
|
||||||
* deadlockDetails[]
|
* deadlockDetails[]
|
||||||
*/
|
*/
|
||||||
Assert(depth <= GetMaxBackends());
|
Assert(depth <= MaxBackends);
|
||||||
nDeadlockDetails = depth;
|
nDeadlockDetails = depth;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -501,7 +500,7 @@ FindLockCycleRecurse(PGPROC *checkProc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Mark proc as seen */
|
/* Mark proc as seen */
|
||||||
Assert(nVisitedProcs < GetMaxBackends());
|
Assert(nVisitedProcs < MaxBackends);
|
||||||
visitedProcs[nVisitedProcs++] = checkProc;
|
visitedProcs[nVisitedProcs++] = checkProc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -699,7 +698,7 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
|
||||||
/*
|
/*
|
||||||
* Add this edge to the list of soft edges in the cycle
|
* Add this edge to the list of soft edges in the cycle
|
||||||
*/
|
*/
|
||||||
Assert(*nSoftEdges < GetMaxBackends());
|
Assert(*nSoftEdges < MaxBackends);
|
||||||
softEdges[*nSoftEdges].waiter = checkProcLeader;
|
softEdges[*nSoftEdges].waiter = checkProcLeader;
|
||||||
softEdges[*nSoftEdges].blocker = leader;
|
softEdges[*nSoftEdges].blocker = leader;
|
||||||
softEdges[*nSoftEdges].lock = lock;
|
softEdges[*nSoftEdges].lock = lock;
|
||||||
|
@ -772,7 +771,7 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
|
||||||
/*
|
/*
|
||||||
* Add this edge to the list of soft edges in the cycle
|
* Add this edge to the list of soft edges in the cycle
|
||||||
*/
|
*/
|
||||||
Assert(*nSoftEdges < GetMaxBackends());
|
Assert(*nSoftEdges < MaxBackends);
|
||||||
softEdges[*nSoftEdges].waiter = checkProcLeader;
|
softEdges[*nSoftEdges].waiter = checkProcLeader;
|
||||||
softEdges[*nSoftEdges].blocker = leader;
|
softEdges[*nSoftEdges].blocker = leader;
|
||||||
softEdges[*nSoftEdges].lock = lock;
|
softEdges[*nSoftEdges].lock = lock;
|
||||||
|
@ -835,7 +834,7 @@ ExpandConstraints(EDGE *constraints,
|
||||||
waitOrders[nWaitOrders].procs = waitOrderProcs + nWaitOrderProcs;
|
waitOrders[nWaitOrders].procs = waitOrderProcs + nWaitOrderProcs;
|
||||||
waitOrders[nWaitOrders].nProcs = lock->waitProcs.size;
|
waitOrders[nWaitOrders].nProcs = lock->waitProcs.size;
|
||||||
nWaitOrderProcs += lock->waitProcs.size;
|
nWaitOrderProcs += lock->waitProcs.size;
|
||||||
Assert(nWaitOrderProcs <= GetMaxBackends());
|
Assert(nWaitOrderProcs <= MaxBackends);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the topo sort. TopoSort need not examine constraints after this
|
* Do the topo sort. TopoSort need not examine constraints after this
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
int max_locks_per_xact; /* set by guc.c */
|
int max_locks_per_xact; /* set by guc.c */
|
||||||
|
|
||||||
#define NLOCKENTS() \
|
#define NLOCKENTS() \
|
||||||
mul_size(max_locks_per_xact, add_size(GetMaxBackends(), max_prepared_xacts))
|
mul_size(max_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2924,7 +2924,6 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
|
||||||
LWLock *partitionLock;
|
LWLock *partitionLock;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int fast_count = 0;
|
int fast_count = 0;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
|
if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods))
|
||||||
elog(ERROR, "unrecognized lock method: %d", lockmethodid);
|
elog(ERROR, "unrecognized lock method: %d", lockmethodid);
|
||||||
|
@ -2943,12 +2942,12 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
|
||||||
vxids = (VirtualTransactionId *)
|
vxids = (VirtualTransactionId *)
|
||||||
MemoryContextAlloc(TopMemoryContext,
|
MemoryContextAlloc(TopMemoryContext,
|
||||||
sizeof(VirtualTransactionId) *
|
sizeof(VirtualTransactionId) *
|
||||||
(max_backends + max_prepared_xacts + 1));
|
(MaxBackends + max_prepared_xacts + 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vxids = (VirtualTransactionId *)
|
vxids = (VirtualTransactionId *)
|
||||||
palloc0(sizeof(VirtualTransactionId) *
|
palloc0(sizeof(VirtualTransactionId) *
|
||||||
(max_backends + max_prepared_xacts + 1));
|
(MaxBackends + max_prepared_xacts + 1));
|
||||||
|
|
||||||
/* Compute hash code and partition lock, and look up conflicting modes. */
|
/* Compute hash code and partition lock, and look up conflicting modes. */
|
||||||
hashcode = LockTagHashCode(locktag);
|
hashcode = LockTagHashCode(locktag);
|
||||||
|
@ -3105,7 +3104,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
|
||||||
|
|
||||||
LWLockRelease(partitionLock);
|
LWLockRelease(partitionLock);
|
||||||
|
|
||||||
if (count > max_backends + max_prepared_xacts) /* should never happen */
|
if (count > MaxBackends + max_prepared_xacts) /* should never happen */
|
||||||
elog(PANIC, "too many conflicting locks found");
|
elog(PANIC, "too many conflicting locks found");
|
||||||
|
|
||||||
vxids[count].backendId = InvalidBackendId;
|
vxids[count].backendId = InvalidBackendId;
|
||||||
|
@ -3652,12 +3651,11 @@ GetLockStatusData(void)
|
||||||
int els;
|
int els;
|
||||||
int el;
|
int el;
|
||||||
int i;
|
int i;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
data = (LockData *) palloc(sizeof(LockData));
|
data = (LockData *) palloc(sizeof(LockData));
|
||||||
|
|
||||||
/* Guess how much space we'll need. */
|
/* Guess how much space we'll need. */
|
||||||
els = max_backends;
|
els = MaxBackends;
|
||||||
el = 0;
|
el = 0;
|
||||||
data->locks = (LockInstanceData *) palloc(sizeof(LockInstanceData) * els);
|
data->locks = (LockInstanceData *) palloc(sizeof(LockInstanceData) * els);
|
||||||
|
|
||||||
|
@ -3691,7 +3689,7 @@ GetLockStatusData(void)
|
||||||
|
|
||||||
if (el >= els)
|
if (el >= els)
|
||||||
{
|
{
|
||||||
els += max_backends;
|
els += MaxBackends;
|
||||||
data->locks = (LockInstanceData *)
|
data->locks = (LockInstanceData *)
|
||||||
repalloc(data->locks, sizeof(LockInstanceData) * els);
|
repalloc(data->locks, sizeof(LockInstanceData) * els);
|
||||||
}
|
}
|
||||||
|
@ -3723,7 +3721,7 @@ GetLockStatusData(void)
|
||||||
|
|
||||||
if (el >= els)
|
if (el >= els)
|
||||||
{
|
{
|
||||||
els += max_backends;
|
els += MaxBackends;
|
||||||
data->locks = (LockInstanceData *)
|
data->locks = (LockInstanceData *)
|
||||||
repalloc(data->locks, sizeof(LockInstanceData) * els);
|
repalloc(data->locks, sizeof(LockInstanceData) * els);
|
||||||
}
|
}
|
||||||
|
@ -3852,7 +3850,7 @@ GetBlockerStatusData(int blocked_pid)
|
||||||
* for the procs[] array; the other two could need enlargement, though.)
|
* for the procs[] array; the other two could need enlargement, though.)
|
||||||
*/
|
*/
|
||||||
data->nprocs = data->nlocks = data->npids = 0;
|
data->nprocs = data->nlocks = data->npids = 0;
|
||||||
data->maxprocs = data->maxlocks = data->maxpids = GetMaxBackends();
|
data->maxprocs = data->maxlocks = data->maxpids = MaxBackends;
|
||||||
data->procs = (BlockedProcData *) palloc(sizeof(BlockedProcData) * data->maxprocs);
|
data->procs = (BlockedProcData *) palloc(sizeof(BlockedProcData) * data->maxprocs);
|
||||||
data->locks = (LockInstanceData *) palloc(sizeof(LockInstanceData) * data->maxlocks);
|
data->locks = (LockInstanceData *) palloc(sizeof(LockInstanceData) * data->maxlocks);
|
||||||
data->waiter_pids = (int *) palloc(sizeof(int) * data->maxpids);
|
data->waiter_pids = (int *) palloc(sizeof(int) * data->maxpids);
|
||||||
|
@ -3927,7 +3925,6 @@ GetSingleProcBlockerStatusData(PGPROC *blocked_proc, BlockedProcsData *data)
|
||||||
PGPROC *proc;
|
PGPROC *proc;
|
||||||
int queue_size;
|
int queue_size;
|
||||||
int i;
|
int i;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
/* Nothing to do if this proc is not blocked */
|
/* Nothing to do if this proc is not blocked */
|
||||||
if (theLock == NULL)
|
if (theLock == NULL)
|
||||||
|
@ -3956,7 +3953,7 @@ GetSingleProcBlockerStatusData(PGPROC *blocked_proc, BlockedProcsData *data)
|
||||||
|
|
||||||
if (data->nlocks >= data->maxlocks)
|
if (data->nlocks >= data->maxlocks)
|
||||||
{
|
{
|
||||||
data->maxlocks += max_backends;
|
data->maxlocks += MaxBackends;
|
||||||
data->locks = (LockInstanceData *)
|
data->locks = (LockInstanceData *)
|
||||||
repalloc(data->locks, sizeof(LockInstanceData) * data->maxlocks);
|
repalloc(data->locks, sizeof(LockInstanceData) * data->maxlocks);
|
||||||
}
|
}
|
||||||
|
@ -3985,7 +3982,7 @@ GetSingleProcBlockerStatusData(PGPROC *blocked_proc, BlockedProcsData *data)
|
||||||
|
|
||||||
if (queue_size > data->maxpids - data->npids)
|
if (queue_size > data->maxpids - data->npids)
|
||||||
{
|
{
|
||||||
data->maxpids = Max(data->maxpids + max_backends,
|
data->maxpids = Max(data->maxpids + MaxBackends,
|
||||||
data->npids + queue_size);
|
data->npids + queue_size);
|
||||||
data->waiter_pids = (int *) repalloc(data->waiter_pids,
|
data->waiter_pids = (int *) repalloc(data->waiter_pids,
|
||||||
sizeof(int) * data->maxpids);
|
sizeof(int) * data->maxpids);
|
||||||
|
|
|
@ -257,7 +257,7 @@
|
||||||
(&MainLWLockArray[PREDICATELOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
|
(&MainLWLockArray[PREDICATELOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
|
||||||
|
|
||||||
#define NPREDICATELOCKTARGETENTS() \
|
#define NPREDICATELOCKTARGETENTS() \
|
||||||
mul_size(max_predicate_locks_per_xact, add_size(GetMaxBackends(), max_prepared_xacts))
|
mul_size(max_predicate_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
|
||||||
|
|
||||||
#define SxactIsOnFinishedList(sxact) (!SHMQueueIsDetached(&((sxact)->finishedLink)))
|
#define SxactIsOnFinishedList(sxact) (!SHMQueueIsDetached(&((sxact)->finishedLink)))
|
||||||
|
|
||||||
|
@ -1222,7 +1222,7 @@ InitPredicateLocks(void)
|
||||||
* Compute size for serializable transaction hashtable. Note these
|
* Compute size for serializable transaction hashtable. Note these
|
||||||
* calculations must agree with PredicateLockShmemSize!
|
* calculations must agree with PredicateLockShmemSize!
|
||||||
*/
|
*/
|
||||||
max_table_size = (GetMaxBackends() + max_prepared_xacts);
|
max_table_size = (MaxBackends + max_prepared_xacts);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a list to hold information on transactions participating in
|
* Allocate a list to hold information on transactions participating in
|
||||||
|
@ -1375,7 +1375,7 @@ PredicateLockShmemSize(void)
|
||||||
size = add_size(size, size / 10);
|
size = add_size(size, size / 10);
|
||||||
|
|
||||||
/* transaction list */
|
/* transaction list */
|
||||||
max_table_size = GetMaxBackends() + max_prepared_xacts;
|
max_table_size = MaxBackends + max_prepared_xacts;
|
||||||
max_table_size *= 10;
|
max_table_size *= 10;
|
||||||
size = add_size(size, PredXactListDataSize);
|
size = add_size(size, PredXactListDataSize);
|
||||||
size = add_size(size, mul_size((Size) max_table_size,
|
size = add_size(size, mul_size((Size) max_table_size,
|
||||||
|
@ -1907,7 +1907,7 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
|
||||||
{
|
{
|
||||||
++(PredXact->WritableSxactCount);
|
++(PredXact->WritableSxactCount);
|
||||||
Assert(PredXact->WritableSxactCount <=
|
Assert(PredXact->WritableSxactCount <=
|
||||||
(GetMaxBackends() + max_prepared_xacts));
|
(MaxBackends + max_prepared_xacts));
|
||||||
}
|
}
|
||||||
|
|
||||||
MySerializableXact = sxact;
|
MySerializableXact = sxact;
|
||||||
|
@ -5111,7 +5111,7 @@ predicatelock_twophase_recover(TransactionId xid, uint16 info,
|
||||||
{
|
{
|
||||||
++(PredXact->WritableSxactCount);
|
++(PredXact->WritableSxactCount);
|
||||||
Assert(PredXact->WritableSxactCount <=
|
Assert(PredXact->WritableSxactCount <=
|
||||||
(GetMaxBackends() + max_prepared_xacts));
|
(MaxBackends + max_prepared_xacts));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -103,7 +103,7 @@ ProcGlobalShmemSize(void)
|
||||||
{
|
{
|
||||||
Size size = 0;
|
Size size = 0;
|
||||||
Size TotalProcs =
|
Size TotalProcs =
|
||||||
add_size(GetMaxBackends(), add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
|
add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts));
|
||||||
|
|
||||||
/* ProcGlobal */
|
/* ProcGlobal */
|
||||||
size = add_size(size, sizeof(PROC_HDR));
|
size = add_size(size, sizeof(PROC_HDR));
|
||||||
|
@ -127,7 +127,7 @@ ProcGlobalSemas(void)
|
||||||
* We need a sema per backend (including autovacuum), plus one for each
|
* We need a sema per backend (including autovacuum), plus one for each
|
||||||
* auxiliary process.
|
* auxiliary process.
|
||||||
*/
|
*/
|
||||||
return GetMaxBackends() + NUM_AUXILIARY_PROCS;
|
return MaxBackends + NUM_AUXILIARY_PROCS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -162,8 +162,7 @@ InitProcGlobal(void)
|
||||||
int i,
|
int i,
|
||||||
j;
|
j;
|
||||||
bool found;
|
bool found;
|
||||||
int max_backends = GetMaxBackends();
|
uint32 TotalProcs = MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
|
||||||
uint32 TotalProcs = max_backends + NUM_AUXILIARY_PROCS + max_prepared_xacts;
|
|
||||||
|
|
||||||
/* Create the ProcGlobal shared structure */
|
/* Create the ProcGlobal shared structure */
|
||||||
ProcGlobal = (PROC_HDR *)
|
ProcGlobal = (PROC_HDR *)
|
||||||
|
@ -196,7 +195,7 @@ InitProcGlobal(void)
|
||||||
MemSet(procs, 0, TotalProcs * sizeof(PGPROC));
|
MemSet(procs, 0, 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 = max_backends + NUM_AUXILIARY_PROCS;
|
ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate arrays mirroring PGPROC fields in a dense manner. See
|
* Allocate arrays mirroring PGPROC fields in a dense manner. See
|
||||||
|
@ -222,7 +221,7 @@ InitProcGlobal(void)
|
||||||
* dummy PGPROCs don't need these though - they're never associated
|
* dummy PGPROCs don't need these though - they're never associated
|
||||||
* with a real process
|
* with a real process
|
||||||
*/
|
*/
|
||||||
if (i < max_backends + NUM_AUXILIARY_PROCS)
|
if (i < MaxBackends + NUM_AUXILIARY_PROCS)
|
||||||
{
|
{
|
||||||
procs[i].sem = PGSemaphoreCreate();
|
procs[i].sem = PGSemaphoreCreate();
|
||||||
InitSharedLatch(&(procs[i].procLatch));
|
InitSharedLatch(&(procs[i].procLatch));
|
||||||
|
@ -259,7 +258,7 @@ InitProcGlobal(void)
|
||||||
ProcGlobal->bgworkerFreeProcs = &procs[i];
|
ProcGlobal->bgworkerFreeProcs = &procs[i];
|
||||||
procs[i].procgloballist = &ProcGlobal->bgworkerFreeProcs;
|
procs[i].procgloballist = &ProcGlobal->bgworkerFreeProcs;
|
||||||
}
|
}
|
||||||
else if (i < max_backends)
|
else if (i < MaxBackends)
|
||||||
{
|
{
|
||||||
/* PGPROC for walsender, add to walsenderFreeProcs list */
|
/* PGPROC for walsender, add to walsenderFreeProcs list */
|
||||||
procs[i].links.next = (SHM_QUEUE *) ProcGlobal->walsenderFreeProcs;
|
procs[i].links.next = (SHM_QUEUE *) ProcGlobal->walsenderFreeProcs;
|
||||||
|
@ -287,8 +286,8 @@ InitProcGlobal(void)
|
||||||
* Save pointers to the blocks of PGPROC structures reserved for auxiliary
|
* Save pointers to the blocks of PGPROC structures reserved for auxiliary
|
||||||
* processes and prepared transactions.
|
* processes and prepared transactions.
|
||||||
*/
|
*/
|
||||||
AuxiliaryProcs = &procs[max_backends];
|
AuxiliaryProcs = &procs[MaxBackends];
|
||||||
PreparedXactProcs = &procs[max_backends + 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 *) ShmemAlloc(sizeof(slock_t));
|
||||||
|
|
|
@ -26,6 +26,18 @@
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------
|
||||||
|
* Total number of backends including auxiliary
|
||||||
|
*
|
||||||
|
* We reserve a slot for each possible BackendId, plus one for each
|
||||||
|
* possible auxiliary process type. (This scheme assumes there is not
|
||||||
|
* more than one of any auxiliary process type at a time.) MaxBackends
|
||||||
|
* includes autovacuum workers and background workers as well.
|
||||||
|
* ----------
|
||||||
|
*/
|
||||||
|
#define NumBackendStatSlots (MaxBackends + NUM_AUXPROCTYPES)
|
||||||
|
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* GUC parameters
|
* GUC parameters
|
||||||
* ----------
|
* ----------
|
||||||
|
@ -63,23 +75,8 @@ static MemoryContext backendStatusSnapContext;
|
||||||
static void pgstat_beshutdown_hook(int code, Datum arg);
|
static void pgstat_beshutdown_hook(int code, Datum arg);
|
||||||
static void pgstat_read_current_status(void);
|
static void pgstat_read_current_status(void);
|
||||||
static void pgstat_setup_backend_status_context(void);
|
static void pgstat_setup_backend_status_context(void);
|
||||||
static inline int GetNumBackendStatSlots(void);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve the total number of backends including auxiliary
|
|
||||||
*
|
|
||||||
* We reserve a slot for each possible BackendId, plus one for each possible
|
|
||||||
* auxiliary process type. (This scheme assumes there is not more than one of
|
|
||||||
* any auxiliary process type at a time.) MaxBackends includes autovacuum
|
|
||||||
* workers and background workers as well.
|
|
||||||
*/
|
|
||||||
static inline int
|
|
||||||
GetNumBackendStatSlots(void)
|
|
||||||
{
|
|
||||||
return GetMaxBackends() + NUM_AUXPROCTYPES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Report shared-memory space needed by CreateSharedBackendStatus.
|
* Report shared-memory space needed by CreateSharedBackendStatus.
|
||||||
*/
|
*/
|
||||||
|
@ -87,28 +84,27 @@ Size
|
||||||
BackendStatusShmemSize(void)
|
BackendStatusShmemSize(void)
|
||||||
{
|
{
|
||||||
Size size;
|
Size size;
|
||||||
int numBackendStatSlots = GetNumBackendStatSlots();
|
|
||||||
|
|
||||||
/* BackendStatusArray: */
|
/* BackendStatusArray: */
|
||||||
size = mul_size(sizeof(PgBackendStatus), numBackendStatSlots);
|
size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
|
||||||
/* BackendAppnameBuffer: */
|
/* BackendAppnameBuffer: */
|
||||||
size = add_size(size,
|
size = add_size(size,
|
||||||
mul_size(NAMEDATALEN, numBackendStatSlots));
|
mul_size(NAMEDATALEN, NumBackendStatSlots));
|
||||||
/* BackendClientHostnameBuffer: */
|
/* BackendClientHostnameBuffer: */
|
||||||
size = add_size(size,
|
size = add_size(size,
|
||||||
mul_size(NAMEDATALEN, numBackendStatSlots));
|
mul_size(NAMEDATALEN, NumBackendStatSlots));
|
||||||
/* BackendActivityBuffer: */
|
/* BackendActivityBuffer: */
|
||||||
size = add_size(size,
|
size = add_size(size,
|
||||||
mul_size(pgstat_track_activity_query_size, numBackendStatSlots));
|
mul_size(pgstat_track_activity_query_size, NumBackendStatSlots));
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
/* BackendSslStatusBuffer: */
|
/* BackendSslStatusBuffer: */
|
||||||
size = add_size(size,
|
size = add_size(size,
|
||||||
mul_size(sizeof(PgBackendSSLStatus), numBackendStatSlots));
|
mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots));
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_GSS
|
#ifdef ENABLE_GSS
|
||||||
/* BackendGssStatusBuffer: */
|
/* BackendGssStatusBuffer: */
|
||||||
size = add_size(size,
|
size = add_size(size,
|
||||||
mul_size(sizeof(PgBackendGSSStatus), numBackendStatSlots));
|
mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots));
|
||||||
#endif
|
#endif
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -124,10 +120,9 @@ CreateSharedBackendStatus(void)
|
||||||
bool found;
|
bool found;
|
||||||
int i;
|
int i;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int numBackendStatSlots = GetNumBackendStatSlots();
|
|
||||||
|
|
||||||
/* Create or attach to the shared array */
|
/* Create or attach to the shared array */
|
||||||
size = mul_size(sizeof(PgBackendStatus), numBackendStatSlots);
|
size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
|
||||||
BackendStatusArray = (PgBackendStatus *)
|
BackendStatusArray = (PgBackendStatus *)
|
||||||
ShmemInitStruct("Backend Status Array", size, &found);
|
ShmemInitStruct("Backend Status Array", size, &found);
|
||||||
|
|
||||||
|
@ -140,7 +135,7 @@ CreateSharedBackendStatus(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create or attach to the shared appname buffer */
|
/* Create or attach to the shared appname buffer */
|
||||||
size = mul_size(NAMEDATALEN, numBackendStatSlots);
|
size = mul_size(NAMEDATALEN, NumBackendStatSlots);
|
||||||
BackendAppnameBuffer = (char *)
|
BackendAppnameBuffer = (char *)
|
||||||
ShmemInitStruct("Backend Application Name Buffer", size, &found);
|
ShmemInitStruct("Backend Application Name Buffer", size, &found);
|
||||||
|
|
||||||
|
@ -150,7 +145,7 @@ CreateSharedBackendStatus(void)
|
||||||
|
|
||||||
/* Initialize st_appname pointers. */
|
/* Initialize st_appname pointers. */
|
||||||
buffer = BackendAppnameBuffer;
|
buffer = BackendAppnameBuffer;
|
||||||
for (i = 0; i < numBackendStatSlots; i++)
|
for (i = 0; i < NumBackendStatSlots; i++)
|
||||||
{
|
{
|
||||||
BackendStatusArray[i].st_appname = buffer;
|
BackendStatusArray[i].st_appname = buffer;
|
||||||
buffer += NAMEDATALEN;
|
buffer += NAMEDATALEN;
|
||||||
|
@ -158,7 +153,7 @@ CreateSharedBackendStatus(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create or attach to the shared client hostname buffer */
|
/* Create or attach to the shared client hostname buffer */
|
||||||
size = mul_size(NAMEDATALEN, numBackendStatSlots);
|
size = mul_size(NAMEDATALEN, NumBackendStatSlots);
|
||||||
BackendClientHostnameBuffer = (char *)
|
BackendClientHostnameBuffer = (char *)
|
||||||
ShmemInitStruct("Backend Client Host Name Buffer", size, &found);
|
ShmemInitStruct("Backend Client Host Name Buffer", size, &found);
|
||||||
|
|
||||||
|
@ -168,7 +163,7 @@ CreateSharedBackendStatus(void)
|
||||||
|
|
||||||
/* Initialize st_clienthostname pointers. */
|
/* Initialize st_clienthostname pointers. */
|
||||||
buffer = BackendClientHostnameBuffer;
|
buffer = BackendClientHostnameBuffer;
|
||||||
for (i = 0; i < numBackendStatSlots; i++)
|
for (i = 0; i < NumBackendStatSlots; i++)
|
||||||
{
|
{
|
||||||
BackendStatusArray[i].st_clienthostname = buffer;
|
BackendStatusArray[i].st_clienthostname = buffer;
|
||||||
buffer += NAMEDATALEN;
|
buffer += NAMEDATALEN;
|
||||||
|
@ -177,7 +172,7 @@ CreateSharedBackendStatus(void)
|
||||||
|
|
||||||
/* Create or attach to the shared activity buffer */
|
/* Create or attach to the shared activity buffer */
|
||||||
BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
|
BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
|
||||||
numBackendStatSlots);
|
NumBackendStatSlots);
|
||||||
BackendActivityBuffer = (char *)
|
BackendActivityBuffer = (char *)
|
||||||
ShmemInitStruct("Backend Activity Buffer",
|
ShmemInitStruct("Backend Activity Buffer",
|
||||||
BackendActivityBufferSize,
|
BackendActivityBufferSize,
|
||||||
|
@ -189,7 +184,7 @@ CreateSharedBackendStatus(void)
|
||||||
|
|
||||||
/* Initialize st_activity pointers. */
|
/* Initialize st_activity pointers. */
|
||||||
buffer = BackendActivityBuffer;
|
buffer = BackendActivityBuffer;
|
||||||
for (i = 0; i < numBackendStatSlots; i++)
|
for (i = 0; i < NumBackendStatSlots; i++)
|
||||||
{
|
{
|
||||||
BackendStatusArray[i].st_activity_raw = buffer;
|
BackendStatusArray[i].st_activity_raw = buffer;
|
||||||
buffer += pgstat_track_activity_query_size;
|
buffer += pgstat_track_activity_query_size;
|
||||||
|
@ -198,7 +193,7 @@ CreateSharedBackendStatus(void)
|
||||||
|
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
/* Create or attach to the shared SSL status buffer */
|
/* Create or attach to the shared SSL status buffer */
|
||||||
size = mul_size(sizeof(PgBackendSSLStatus), numBackendStatSlots);
|
size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots);
|
||||||
BackendSslStatusBuffer = (PgBackendSSLStatus *)
|
BackendSslStatusBuffer = (PgBackendSSLStatus *)
|
||||||
ShmemInitStruct("Backend SSL Status Buffer", size, &found);
|
ShmemInitStruct("Backend SSL Status Buffer", size, &found);
|
||||||
|
|
||||||
|
@ -210,7 +205,7 @@ CreateSharedBackendStatus(void)
|
||||||
|
|
||||||
/* Initialize st_sslstatus pointers. */
|
/* Initialize st_sslstatus pointers. */
|
||||||
ptr = BackendSslStatusBuffer;
|
ptr = BackendSslStatusBuffer;
|
||||||
for (i = 0; i < numBackendStatSlots; i++)
|
for (i = 0; i < NumBackendStatSlots; i++)
|
||||||
{
|
{
|
||||||
BackendStatusArray[i].st_sslstatus = ptr;
|
BackendStatusArray[i].st_sslstatus = ptr;
|
||||||
ptr++;
|
ptr++;
|
||||||
|
@ -220,7 +215,7 @@ CreateSharedBackendStatus(void)
|
||||||
|
|
||||||
#ifdef ENABLE_GSS
|
#ifdef ENABLE_GSS
|
||||||
/* Create or attach to the shared GSSAPI status buffer */
|
/* Create or attach to the shared GSSAPI status buffer */
|
||||||
size = mul_size(sizeof(PgBackendGSSStatus), numBackendStatSlots);
|
size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots);
|
||||||
BackendGssStatusBuffer = (PgBackendGSSStatus *)
|
BackendGssStatusBuffer = (PgBackendGSSStatus *)
|
||||||
ShmemInitStruct("Backend GSS Status Buffer", size, &found);
|
ShmemInitStruct("Backend GSS Status Buffer", size, &found);
|
||||||
|
|
||||||
|
@ -232,7 +227,7 @@ CreateSharedBackendStatus(void)
|
||||||
|
|
||||||
/* Initialize st_gssstatus pointers. */
|
/* Initialize st_gssstatus pointers. */
|
||||||
ptr = BackendGssStatusBuffer;
|
ptr = BackendGssStatusBuffer;
|
||||||
for (i = 0; i < numBackendStatSlots; i++)
|
for (i = 0; i < NumBackendStatSlots; i++)
|
||||||
{
|
{
|
||||||
BackendStatusArray[i].st_gssstatus = ptr;
|
BackendStatusArray[i].st_gssstatus = ptr;
|
||||||
ptr++;
|
ptr++;
|
||||||
|
@ -256,7 +251,7 @@ pgstat_beinit(void)
|
||||||
/* Initialize MyBEEntry */
|
/* Initialize MyBEEntry */
|
||||||
if (MyBackendId != InvalidBackendId)
|
if (MyBackendId != InvalidBackendId)
|
||||||
{
|
{
|
||||||
Assert(MyBackendId >= 1 && MyBackendId <= GetMaxBackends());
|
Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends);
|
||||||
MyBEEntry = &BackendStatusArray[MyBackendId - 1];
|
MyBEEntry = &BackendStatusArray[MyBackendId - 1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -272,7 +267,7 @@ pgstat_beinit(void)
|
||||||
* MaxBackends + AuxBackendType + 1 as the index of the slot for an
|
* MaxBackends + AuxBackendType + 1 as the index of the slot for an
|
||||||
* auxiliary process.
|
* auxiliary process.
|
||||||
*/
|
*/
|
||||||
MyBEEntry = &BackendStatusArray[GetMaxBackends() + MyAuxProcType];
|
MyBEEntry = &BackendStatusArray[MaxBackends + MyAuxProcType];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up a process-exit hook to clean up */
|
/* Set up a process-exit hook to clean up */
|
||||||
|
@ -744,7 +739,6 @@ pgstat_read_current_status(void)
|
||||||
PgBackendGSSStatus *localgssstatus;
|
PgBackendGSSStatus *localgssstatus;
|
||||||
#endif
|
#endif
|
||||||
int i;
|
int i;
|
||||||
int numBackendStatSlots = GetNumBackendStatSlots();
|
|
||||||
|
|
||||||
if (localBackendStatusTable)
|
if (localBackendStatusTable)
|
||||||
return; /* already done */
|
return; /* already done */
|
||||||
|
@ -761,32 +755,32 @@ pgstat_read_current_status(void)
|
||||||
*/
|
*/
|
||||||
localtable = (LocalPgBackendStatus *)
|
localtable = (LocalPgBackendStatus *)
|
||||||
MemoryContextAlloc(backendStatusSnapContext,
|
MemoryContextAlloc(backendStatusSnapContext,
|
||||||
sizeof(LocalPgBackendStatus) * numBackendStatSlots);
|
sizeof(LocalPgBackendStatus) * NumBackendStatSlots);
|
||||||
localappname = (char *)
|
localappname = (char *)
|
||||||
MemoryContextAlloc(backendStatusSnapContext,
|
MemoryContextAlloc(backendStatusSnapContext,
|
||||||
NAMEDATALEN * numBackendStatSlots);
|
NAMEDATALEN * NumBackendStatSlots);
|
||||||
localclienthostname = (char *)
|
localclienthostname = (char *)
|
||||||
MemoryContextAlloc(backendStatusSnapContext,
|
MemoryContextAlloc(backendStatusSnapContext,
|
||||||
NAMEDATALEN * numBackendStatSlots);
|
NAMEDATALEN * NumBackendStatSlots);
|
||||||
localactivity = (char *)
|
localactivity = (char *)
|
||||||
MemoryContextAllocHuge(backendStatusSnapContext,
|
MemoryContextAllocHuge(backendStatusSnapContext,
|
||||||
pgstat_track_activity_query_size * numBackendStatSlots);
|
pgstat_track_activity_query_size * NumBackendStatSlots);
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
localsslstatus = (PgBackendSSLStatus *)
|
localsslstatus = (PgBackendSSLStatus *)
|
||||||
MemoryContextAlloc(backendStatusSnapContext,
|
MemoryContextAlloc(backendStatusSnapContext,
|
||||||
sizeof(PgBackendSSLStatus) * numBackendStatSlots);
|
sizeof(PgBackendSSLStatus) * NumBackendStatSlots);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_GSS
|
#ifdef ENABLE_GSS
|
||||||
localgssstatus = (PgBackendGSSStatus *)
|
localgssstatus = (PgBackendGSSStatus *)
|
||||||
MemoryContextAlloc(backendStatusSnapContext,
|
MemoryContextAlloc(backendStatusSnapContext,
|
||||||
sizeof(PgBackendGSSStatus) * numBackendStatSlots);
|
sizeof(PgBackendGSSStatus) * NumBackendStatSlots);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
localNumBackends = 0;
|
localNumBackends = 0;
|
||||||
|
|
||||||
beentry = BackendStatusArray;
|
beentry = BackendStatusArray;
|
||||||
localentry = localtable;
|
localentry = localtable;
|
||||||
for (i = 1; i <= numBackendStatSlots; i++)
|
for (i = 1; i <= NumBackendStatSlots; i++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Follow the protocol of retrying if st_changecount changes while we
|
* Follow the protocol of retrying if st_changecount changes while we
|
||||||
|
@ -899,10 +893,9 @@ pgstat_get_backend_current_activity(int pid, bool checkUser)
|
||||||
{
|
{
|
||||||
PgBackendStatus *beentry;
|
PgBackendStatus *beentry;
|
||||||
int i;
|
int i;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
beentry = BackendStatusArray;
|
beentry = BackendStatusArray;
|
||||||
for (i = 1; i <= max_backends; i++)
|
for (i = 1; i <= MaxBackends; i++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Although we expect the target backend's entry to be stable, that
|
* Although we expect the target backend's entry to be stable, that
|
||||||
|
@ -978,7 +971,6 @@ pgstat_get_crashed_backend_activity(int pid, char *buffer, int buflen)
|
||||||
{
|
{
|
||||||
volatile PgBackendStatus *beentry;
|
volatile PgBackendStatus *beentry;
|
||||||
int i;
|
int i;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
beentry = BackendStatusArray;
|
beentry = BackendStatusArray;
|
||||||
|
|
||||||
|
@ -989,7 +981,7 @@ pgstat_get_crashed_backend_activity(int pid, char *buffer, int buflen)
|
||||||
if (beentry == NULL || BackendActivityBuffer == NULL)
|
if (beentry == NULL || BackendActivityBuffer == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 1; i <= max_backends; i++)
|
for (i = 1; i <= MaxBackends; i++)
|
||||||
{
|
{
|
||||||
if (beentry->st_procpid == pid)
|
if (beentry->st_procpid == pid)
|
||||||
{
|
{
|
||||||
|
|
|
@ -559,14 +559,13 @@ pg_safe_snapshot_blocking_pids(PG_FUNCTION_ARGS)
|
||||||
int *blockers;
|
int *blockers;
|
||||||
int num_blockers;
|
int num_blockers;
|
||||||
Datum *blocker_datums;
|
Datum *blocker_datums;
|
||||||
int max_backends = GetMaxBackends();
|
|
||||||
|
|
||||||
/* A buffer big enough for any possible blocker list without truncation */
|
/* A buffer big enough for any possible blocker list without truncation */
|
||||||
blockers = (int *) palloc(max_backends * sizeof(int));
|
blockers = (int *) palloc(MaxBackends * sizeof(int));
|
||||||
|
|
||||||
/* Collect a snapshot of processes waited for by GetSafeSnapshot */
|
/* Collect a snapshot of processes waited for by GetSafeSnapshot */
|
||||||
num_blockers =
|
num_blockers =
|
||||||
GetSafeSnapshotBlockingPids(blocked_pid, blockers, max_backends);
|
GetSafeSnapshotBlockingPids(blocked_pid, blockers, MaxBackends);
|
||||||
|
|
||||||
/* Convert int array to Datum array */
|
/* Convert int array to Datum array */
|
||||||
if (num_blockers > 0)
|
if (num_blockers > 0)
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "access/session.h"
|
#include "access/session.h"
|
||||||
#include "access/sysattr.h"
|
#include "access/sysattr.h"
|
||||||
#include "access/tableam.h"
|
#include "access/tableam.h"
|
||||||
#include "access/twophase.h"
|
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "access/xlog.h"
|
#include "access/xlog.h"
|
||||||
#include "access/xloginsert.h"
|
#include "access/xloginsert.h"
|
||||||
|
@ -68,9 +67,6 @@
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "utils/timeout.h"
|
#include "utils/timeout.h"
|
||||||
|
|
||||||
static int MaxBackends = 0;
|
|
||||||
static int MaxBackendsInitialized = false;
|
|
||||||
|
|
||||||
static HeapTuple GetDatabaseTuple(const char *dbname);
|
static HeapTuple GetDatabaseTuple(const char *dbname);
|
||||||
static HeapTuple GetDatabaseTupleByOid(Oid dboid);
|
static HeapTuple GetDatabaseTupleByOid(Oid dboid);
|
||||||
static void PerformAuthentication(Port *port);
|
static void PerformAuthentication(Port *port);
|
||||||
|
@ -542,8 +538,9 @@ pg_split_opts(char **argv, int *argcp, const char *optstr)
|
||||||
/*
|
/*
|
||||||
* Initialize MaxBackends value from config options.
|
* Initialize MaxBackends value from config options.
|
||||||
*
|
*
|
||||||
* This must be called after modules have had the chance to alter GUCs in
|
* This must be called after modules have had the chance to register background
|
||||||
* shared_preload_libraries and before shared memory size is determined.
|
* workers in shared_preload_libraries, and before shared memory size is
|
||||||
|
* determined.
|
||||||
*
|
*
|
||||||
* Note that in EXEC_BACKEND environment, the value is passed down from
|
* Note that in EXEC_BACKEND environment, the value is passed down from
|
||||||
* postmaster to subprocesses via BackendParameters in SubPostmasterMain; only
|
* postmaster to subprocesses via BackendParameters in SubPostmasterMain; only
|
||||||
|
@ -553,49 +550,15 @@ pg_split_opts(char **argv, int *argcp, const char *optstr)
|
||||||
void
|
void
|
||||||
InitializeMaxBackends(void)
|
InitializeMaxBackends(void)
|
||||||
{
|
{
|
||||||
|
Assert(MaxBackends == 0);
|
||||||
|
|
||||||
/* the extra unit accounts for the autovacuum launcher */
|
/* the extra unit accounts for the autovacuum launcher */
|
||||||
SetMaxBackends(MaxConnections + autovacuum_max_workers + 1 +
|
MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
|
||||||
max_worker_processes + max_wal_senders);
|
max_worker_processes + max_wal_senders;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Safely retrieve the value of MaxBackends.
|
|
||||||
*
|
|
||||||
* Previously, MaxBackends was externally visible, but it was often used before
|
|
||||||
* it was initialized (e.g., in preloaded libraries' _PG_init() functions).
|
|
||||||
* Unfortunately, we cannot initialize MaxBackends before processing
|
|
||||||
* shared_preload_libraries because the libraries sometimes alter GUCs that are
|
|
||||||
* used to calculate its value. Instead, we provide this function for accessing
|
|
||||||
* MaxBackends, and we ERROR if someone calls it before it is initialized.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
GetMaxBackends(void)
|
|
||||||
{
|
|
||||||
if (unlikely(!MaxBackendsInitialized))
|
|
||||||
elog(ERROR, "MaxBackends not yet initialized");
|
|
||||||
|
|
||||||
return MaxBackends;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the value of MaxBackends.
|
|
||||||
*
|
|
||||||
* This should only be used by InitializeMaxBackends() and
|
|
||||||
* restore_backend_variables(). If MaxBackends is already initialized or the
|
|
||||||
* specified value is greater than the maximum, this will ERROR.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
SetMaxBackends(int max_backends)
|
|
||||||
{
|
|
||||||
if (MaxBackendsInitialized)
|
|
||||||
elog(ERROR, "MaxBackends already initialized");
|
|
||||||
|
|
||||||
/* internal error because the values were all checked previously */
|
/* internal error because the values were all checked previously */
|
||||||
if (max_backends > MAX_BACKENDS)
|
if (MaxBackends > MAX_BACKENDS)
|
||||||
elog(ERROR, "too many backends configured");
|
elog(ERROR, "too many backends configured");
|
||||||
|
|
||||||
MaxBackends = max_backends;
|
|
||||||
MaxBackendsInitialized = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -707,7 +670,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
|
||||||
|
|
||||||
SharedInvalBackendInit(false);
|
SharedInvalBackendInit(false);
|
||||||
|
|
||||||
if (MyBackendId > GetMaxBackends() || MyBackendId <= 0)
|
if (MyBackendId > MaxBackends || MyBackendId <= 0)
|
||||||
elog(FATAL, "bad backend ID: %d", MyBackendId);
|
elog(FATAL, "bad backend ID: %d", MyBackendId);
|
||||||
|
|
||||||
/* Now that we have a BackendId, we can participate in ProcSignal */
|
/* Now that we have a BackendId, we can participate in ProcSignal */
|
||||||
|
|
|
@ -173,6 +173,7 @@ extern PGDLLIMPORT char *DataDir;
|
||||||
extern PGDLLIMPORT int data_directory_mode;
|
extern PGDLLIMPORT int data_directory_mode;
|
||||||
|
|
||||||
extern PGDLLIMPORT int NBuffers;
|
extern PGDLLIMPORT int NBuffers;
|
||||||
|
extern PGDLLIMPORT int MaxBackends;
|
||||||
extern PGDLLIMPORT int MaxConnections;
|
extern PGDLLIMPORT int MaxConnections;
|
||||||
extern PGDLLIMPORT int max_worker_processes;
|
extern PGDLLIMPORT int max_worker_processes;
|
||||||
extern PGDLLIMPORT int max_parallel_workers;
|
extern PGDLLIMPORT int max_parallel_workers;
|
||||||
|
@ -456,8 +457,6 @@ extern PGDLLIMPORT AuxProcType MyAuxProcType;
|
||||||
/* in utils/init/postinit.c */
|
/* in utils/init/postinit.c */
|
||||||
extern void pg_split_opts(char **argv, int *argcp, const char *optstr);
|
extern void pg_split_opts(char **argv, int *argcp, const char *optstr);
|
||||||
extern void InitializeMaxBackends(void);
|
extern void InitializeMaxBackends(void);
|
||||||
extern int GetMaxBackends(void);
|
|
||||||
extern void SetMaxBackends(int max_backends);
|
|
||||||
extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
|
extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username,
|
||||||
Oid useroid, char *out_dbname, bool override_allow_connections);
|
Oid useroid, char *out_dbname, bool override_allow_connections);
|
||||||
extern void BaseInit(void);
|
extern void BaseInit(void);
|
||||||
|
|
Loading…
Reference in New Issue