diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 128ee13b5f7f2230b46b028a3df8f31b55c122c7..5b58d2e84dcf064c27d433ee29caa3da272bd437 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -646,18 +646,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser <itemizedlist> <listitem> <para> - <literal>LWLockNamed</>: The backend is waiting for a specific named - lightweight lock. Each such lock protects a particular data - structure in shared memory. <literal>wait_event</> will contain - the name of the lightweight lock. - </para> - </listitem> - <listitem> - <para> - <literal>LWLockTranche</>: The backend is waiting for one of a - group of related lightweight locks. All locks in the group perform - a similar function; <literal>wait_event</> will identify the general - purpose of locks in that group. + <literal>LWLock</>: The backend is waiting for a lightweight lock. + Each such lock protects a particular data structure in shared memory. + <literal>wait_event</> will contain a name identifying the purpose + of the lightweight lock. (Some locks have specific names; others + are part of a group of locks each with a similar purpose.) </para> </listitem> <listitem> @@ -825,7 +818,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser <tbody> <row> - <entry morerows="41"><literal>LWLockNamed</></entry> + <entry morerows="57"><literal>LWLock</></entry> <entry><literal>ShmemIndexLock</></entry> <entry>Waiting to find or allocate space in shared memory.</entry> </row> @@ -1011,7 +1004,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser <entry>Waiting to read or update old snapshot control information.</entry> </row> <row> - <entry morerows="15"><literal>LWLockTranche</></entry> <entry><literal>clog</></entry> <entry>Waiting for I/O on a clog (transaction status) buffer.</entry> </row> @@ -1279,7 +1271,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i pid | wait_event_type | wait_event ------+-----------------+--------------- 2540 | Lock | relation - 6644 | LWLockNamed | ProcArrayLock + 6644 | LWLock | ProcArrayLock (2 rows) </programlisting> </para> @@ -3347,55 +3339,49 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, </row> <row> <entry><literal>lwlock-acquire</literal></entry> - <entry><literal>(char *, int, LWLockMode)</literal></entry> + <entry><literal>(char *, LWLockMode)</literal></entry> <entry>Probe that fires when an LWLock has been acquired. arg0 is the LWLock's tranche. - arg1 is the LWLock's offset within its tranche. - arg2 is the requested lock mode, either exclusive or shared.</entry> + arg1 is the requested lock mode, either exclusive or shared.</entry> </row> <row> <entry><literal>lwlock-release</literal></entry> - <entry><literal>(char *, int)</literal></entry> + <entry><literal>(char *)</literal></entry> <entry>Probe that fires when an LWLock has been released (but note that any released waiters have not yet been awakened). - arg0 is the LWLock's tranche. - arg1 is the LWLock's offset within its tranche.</entry> + arg0 is the LWLock's tranche.</entry> </row> <row> <entry><literal>lwlock-wait-start</literal></entry> - <entry><literal>(char *, int, LWLockMode)</literal></entry> + <entry><literal>(char *, LWLockMode)</literal></entry> <entry>Probe that fires when an LWLock was not immediately available and a server process has begun to wait for the lock to become available. arg0 is the LWLock's tranche. - arg1 is the LWLock's offset within its tranche. - arg2 is the requested lock mode, either exclusive or shared.</entry> + arg1 is the requested lock mode, either exclusive or shared.</entry> </row> <row> <entry><literal>lwlock-wait-done</literal></entry> - <entry><literal>(char *, int, LWLockMode)</literal></entry> + <entry><literal>(char *, LWLockMode)</literal></entry> <entry>Probe that fires when a server process has been released from its wait for an LWLock (it does not actually have the lock yet). arg0 is the LWLock's tranche. - arg1 is the LWLock's offset within its tranche. - arg2 is the requested lock mode, either exclusive or shared.</entry> + arg1 is the requested lock mode, either exclusive or shared.</entry> </row> <row> <entry><literal>lwlock-condacquire</literal></entry> - <entry><literal>(char *, int, LWLockMode)</literal></entry> + <entry><literal>(char *, LWLockMode)</literal></entry> <entry>Probe that fires when an LWLock was successfully acquired when the caller specified no waiting. arg0 is the LWLock's tranche. - arg1 is the LWLock's offset within its tranche. - arg2 is the requested lock mode, either exclusive or shared.</entry> + arg1 is the requested lock mode, either exclusive or shared.</entry> </row> <row> <entry><literal>lwlock-condacquire-fail</literal></entry> - <entry><literal>(char *, int, LWLockMode)</literal></entry> + <entry><literal>(char *, LWLockMode)</literal></entry> <entry>Probe that fires when an LWLock was not successfully acquired when the caller specified no waiting. arg0 is the LWLock's tranche. - arg1 is the LWLock's offset within its tranche. - arg2 is the requested lock mode, either exclusive or shared.</entry> + arg1 is the requested lock mode, either exclusive or shared.</entry> </row> <row> <entry><literal>lock-wait-start</literal></entry> diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c index bbae5847f2d5dab6d533c921de1aafd1134fc9cb..8b95f35dbaf412c57deb8cf048d9ef9299bb4b6b 100644 --- a/src/backend/access/transam/slru.c +++ b/src/backend/access/transam/slru.c @@ -216,9 +216,6 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, Assert(strlen(name) + 1 < SLRU_MAX_NAME_LENGTH); strlcpy(shared->lwlock_tranche_name, name, SLRU_MAX_NAME_LENGTH); shared->lwlock_tranche_id = tranche_id; - shared->lwlock_tranche.name = shared->lwlock_tranche_name; - shared->lwlock_tranche.array_base = shared->buffer_locks; - shared->lwlock_tranche.array_stride = sizeof(LWLockPadded); ptr += BUFFERALIGN(offset); for (slotno = 0; slotno < nslots; slotno++) @@ -237,7 +234,8 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, Assert(found); /* Register SLRU tranche in the main tranches array */ - LWLockRegisterTranche(shared->lwlock_tranche_id, &shared->lwlock_tranche); + LWLockRegisterTranche(shared->lwlock_tranche_id, + shared->lwlock_tranche_name); /* * Initialize the unshared control struct, including directory path. We diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 084401d2f238d729243bca4e3fdad4ff5a82f123..aa9ee5a0dd84cad03895ab3a63e99c97a4eadbd1 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -517,7 +517,6 @@ typedef struct XLogCtlInsert * WAL insertion locks. */ WALInsertLockPadded *WALInsertLocks; - LWLockTranche WALInsertLockTranche; } XLogCtlInsert; /* @@ -4688,7 +4687,7 @@ XLOGShmemInit(void) /* Initialize local copy of WALInsertLocks and register the tranche */ WALInsertLocks = XLogCtl->Insert.WALInsertLocks; LWLockRegisterTranche(LWTRANCHE_WAL_INSERT, - &XLogCtl->Insert.WALInsertLockTranche); + "wal_insert"); return; } memset(XLogCtl, 0, sizeof(XLogCtlData)); @@ -4711,11 +4710,7 @@ XLOGShmemInit(void) (WALInsertLockPadded *) allocptr; allocptr += sizeof(WALInsertLockPadded) * NUM_XLOGINSERT_LOCKS; - XLogCtl->Insert.WALInsertLockTranche.name = "wal_insert"; - XLogCtl->Insert.WALInsertLockTranche.array_base = WALInsertLocks; - XLogCtl->Insert.WALInsertLockTranche.array_stride = sizeof(WALInsertLockPadded); - - LWLockRegisterTranche(LWTRANCHE_WAL_INSERT, &XLogCtl->Insert.WALInsertLockTranche); + LWLockRegisterTranche(LWTRANCHE_WAL_INSERT, "wal_insert"); for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++) { LWLockInitialize(&WALInsertLocks[i].l.lock, LWTRANCHE_WAL_INSERT); diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index c7584cb1d3492e89684bf986c163e926a86d3bae..61e6a2cd3390e8d56b94572e6103752b0b927d5e 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -3152,11 +3152,8 @@ pgstat_get_wait_event_type(uint32 wait_event_info) switch (classId) { - case PG_WAIT_LWLOCK_NAMED: - event_type = "LWLockNamed"; - break; - case PG_WAIT_LWLOCK_TRANCHE: - event_type = "LWLockTranche"; + case PG_WAIT_LWLOCK: + event_type = "LWLock"; break; case PG_WAIT_LOCK: event_type = "Lock"; @@ -3209,8 +3206,7 @@ pgstat_get_wait_event(uint32 wait_event_info) switch (classId) { - case PG_WAIT_LWLOCK_NAMED: - case PG_WAIT_LWLOCK_TRANCHE: + case PG_WAIT_LWLOCK: event_name = GetLWLockIdentifier(classId, eventId); break; case PG_WAIT_LOCK: diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index cc2b513236623b39570bb7eb916c4a348a29e249..0deec75dc260a334560d7711c484b751537930cf 100644 --- a/src/backend/replication/logical/origin.c +++ b/src/backend/replication/logical/origin.c @@ -143,7 +143,6 @@ typedef struct ReplicationStateOnDisk typedef struct ReplicationStateCtl { int tranche_id; - LWLockTranche tranche; ReplicationState states[FLEXIBLE_ARRAY_MEMBER]; } ReplicationStateCtl; @@ -474,11 +473,6 @@ ReplicationOriginShmemInit(void) int i; replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN; - replication_states_ctl->tranche.name = "replication_origin"; - replication_states_ctl->tranche.array_base = - &replication_states[0].lock; - replication_states_ctl->tranche.array_stride = - sizeof(ReplicationState); MemSet(replication_states, 0, ReplicationOriginShmemSize()); @@ -488,7 +482,7 @@ ReplicationOriginShmemInit(void) } LWLockRegisterTranche(replication_states_ctl->tranche_id, - &replication_states_ctl->tranche); + "replication_origin"); } /* --------------------------------------------------------------------------- diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index d8ed005e7ece28243a7db90889a4a21f60db568e..cf814d11a2311f39e437634df9f565c2300e30ba 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -98,8 +98,6 @@ ReplicationSlot *MyReplicationSlot = NULL; int max_replication_slots = 0; /* the maximum number of replication * slots */ -static LWLockTranche ReplSlotIOLWLockTranche; - static void ReplicationSlotDropAcquired(void); static void ReplicationSlotDropPtr(ReplicationSlot *slot); @@ -141,12 +139,8 @@ ReplicationSlotsShmemInit(void) ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(), &found); - ReplSlotIOLWLockTranche.name = "replication_slot_io"; - ReplSlotIOLWLockTranche.array_base = - ((char *) ReplicationSlotCtl) + offsetof(ReplicationSlotCtlData, replication_slots) +offsetof(ReplicationSlot, io_in_progress_lock); - ReplSlotIOLWLockTranche.array_stride = sizeof(ReplicationSlot); LWLockRegisterTranche(LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS, - &ReplSlotIOLWLockTranche); + "replication_slot_io"); if (!found) { diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c index a4163cf717d91a85a328c58a00d29852567fb2bf..c507389a050b986a90c5469497405e94e20ebd82 100644 --- a/src/backend/storage/buffer/buf_init.c +++ b/src/backend/storage/buffer/buf_init.c @@ -21,8 +21,6 @@ BufferDescPadded *BufferDescriptors; char *BufferBlocks; LWLockMinimallyPadded *BufferIOLWLockArray = NULL; -LWLockTranche BufferIOLWLockTranche; -LWLockTranche BufferContentLWLockTranche; WritebackContext BackendWritebackContext; CkptSortItem *CkptBufferIds; @@ -90,18 +88,8 @@ InitBufferPool(void) NBuffers * (Size) sizeof(LWLockMinimallyPadded), &foundIOLocks); - BufferIOLWLockTranche.name = "buffer_io"; - BufferIOLWLockTranche.array_base = BufferIOLWLockArray; - BufferIOLWLockTranche.array_stride = sizeof(LWLockMinimallyPadded); - LWLockRegisterTranche(LWTRANCHE_BUFFER_IO_IN_PROGRESS, - &BufferIOLWLockTranche); - - BufferContentLWLockTranche.name = "buffer_content"; - BufferContentLWLockTranche.array_base = - ((char *) BufferDescriptors) + offsetof(BufferDesc, content_lock); - BufferContentLWLockTranche.array_stride = sizeof(BufferDescPadded); - LWLockRegisterTranche(LWTRANCHE_BUFFER_CONTENT, - &BufferContentLWLockTranche); + LWLockRegisterTranche(LWTRANCHE_BUFFER_IO_IN_PROGRESS, "buffer_io"); + LWLockRegisterTranche(LWTRANCHE_BUFFER_CONTENT, "buffer_content"); /* * The array used to sort to-be-checkpointed buffer ids is located in diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index bf38470f01d92204d93d9a9632f0df402b88461e..0f637556ccbc94c6fde256032145eb96b17bc351 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -106,9 +106,6 @@ static TransactionId *KnownAssignedXids; static bool *KnownAssignedXidsValid; static TransactionId latestObservedXid = InvalidTransactionId; -/* LWLock tranche for backend locks */ -static LWLockTranche ProcLWLockTranche; - /* * If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is * the highest xid that might still be running that we don't have in @@ -266,11 +263,7 @@ CreateSharedProcArray(void) } /* Register and initialize fields of ProcLWLockTranche */ - ProcLWLockTranche.name = "proc"; - ProcLWLockTranche.array_base = (char *) (ProcGlobal->allProcs) + - offsetof(PGPROC, backendLock); - ProcLWLockTranche.array_stride = sizeof(PGPROC); - LWLockRegisterTranche(LWTRANCHE_PROC, &ProcLWLockTranche); + LWLockRegisterTranche(LWTRANCHE_PROC, "proc"); } /* diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index 03c4c7825eb37c070bcee8f8ba03f0d564254b69..4b381e4e0cc7a73ab8995d3ca77d3abbd2a0c4d0 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -108,18 +108,14 @@ extern slock_t *ShmemLock; #define LW_SHARED_MASK ((uint32) ((1 << 24)-1)) /* - * This is indexed by tranche ID and stores metadata for all tranches known + * This is indexed by tranche ID and stores the names of all tranches known * to the current backend. */ -static LWLockTranche **LWLockTrancheArray = NULL; +static char **LWLockTrancheArray = NULL; static int LWLockTranchesAllocated = 0; #define T_NAME(lock) \ - (LWLockTrancheArray[(lock)->tranche]->name) -#define T_ID(lock) \ - ((int) ((((char *) lock) - \ - ((char *) LWLockTrancheArray[(lock)->tranche]->array_base)) / \ - LWLockTrancheArray[(lock)->tranche]->array_stride)) + (LWLockTrancheArray[(lock)->tranche]) /* * This points to the main array of LWLocks in shared memory. Backends inherit @@ -127,10 +123,6 @@ static int LWLockTranchesAllocated = 0; * where we have special measures to pass it down). */ LWLockPadded *MainLWLockArray = NULL; -static LWLockTranche MainLWLockTranche; -static LWLockTranche BufMappingLWLockTranche; -static LWLockTranche LockManagerLWLockTranche; -static LWLockTranche PredicateLockManagerLWLockTranche; /* * We use this structure to keep track of locked LWLocks for release @@ -175,7 +167,7 @@ static inline void LWLockReportWaitEnd(void); typedef struct lwlock_stats_key { int tranche; - int instance; + void *instance; } lwlock_stats_key; typedef struct lwlock_stats @@ -202,32 +194,18 @@ PRINT_LWDEBUG(const char *where, LWLock *lock, LWLockMode mode) if (Trace_lwlocks) { uint32 state = pg_atomic_read_u32(&lock->state); - int id = T_ID(lock); - - if (lock->tranche == 0 && id < NUM_INDIVIDUAL_LWLOCKS) - ereport(LOG, - (errhidestmt(true), - errhidecontext(true), - errmsg_internal("%d: %s(%s): excl %u shared %u haswaiters %u waiters %u rOK %d", - MyProcPid, - where, MainLWLockNames[id], - (state & LW_VAL_EXCLUSIVE) != 0, - state & LW_SHARED_MASK, - (state & LW_FLAG_HAS_WAITERS) != 0, - pg_atomic_read_u32(&lock->nwaiters), - (state & LW_FLAG_RELEASE_OK) != 0))); - else - ereport(LOG, - (errhidestmt(true), - errhidecontext(true), - errmsg_internal("%d: %s(%s %d): excl %u shared %u haswaiters %u waiters %u rOK %d", - MyProcPid, - where, T_NAME(lock), id, - (state & LW_VAL_EXCLUSIVE) != 0, - state & LW_SHARED_MASK, - (state & LW_FLAG_HAS_WAITERS) != 0, - pg_atomic_read_u32(&lock->nwaiters), - (state & LW_FLAG_RELEASE_OK) != 0))); + + ereport(LOG, + (errhidestmt(true), + errhidecontext(true), + errmsg_internal("%d: %s(%s %p): excl %u shared %u haswaiters %u waiters %u rOK %d", + MyProcPid, + where, T_NAME(lock), lock, + (state & LW_VAL_EXCLUSIVE) != 0, + state & LW_SHARED_MASK, + (state & LW_FLAG_HAS_WAITERS) != 0, + pg_atomic_read_u32(&lock->nwaiters), + (state & LW_FLAG_RELEASE_OK) != 0))); } } @@ -237,20 +215,11 @@ LOG_LWDEBUG(const char *where, LWLock *lock, const char *msg) /* hide statement & context here, otherwise the log is just too verbose */ if (Trace_lwlocks) { - int id = T_ID(lock); - - if (lock->tranche == 0 && id < NUM_INDIVIDUAL_LWLOCKS) - ereport(LOG, - (errhidestmt(true), - errhidecontext(true), - errmsg_internal("%s(%s): %s", where, - MainLWLockNames[id], msg))); - else - ereport(LOG, - (errhidestmt(true), - errhidecontext(true), - errmsg_internal("%s(%s %d): %s", where, - T_NAME(lock), id, msg))); + ereport(LOG, + (errhidestmt(true), + errhidecontext(true), + errmsg_internal("%s(%s %p): %s", where, + T_NAME(lock), lock, msg))); } } @@ -315,8 +284,8 @@ print_lwlock_stats(int code, Datum arg) while ((lwstats = (lwlock_stats *) hash_seq_search(&scan)) != NULL) { fprintf(stderr, - "PID %d lwlock %s %d: shacq %u exacq %u blk %u spindelay %u dequeue self %u\n", - MyProcPid, LWLockTrancheArray[lwstats->key.tranche]->name, + "PID %d lwlock %s %p: shacq %u exacq %u blk %u spindelay %u dequeue self %u\n", + MyProcPid, LWLockTrancheArray[lwstats->key.tranche], lwstats->key.instance, lwstats->sh_acquire_count, lwstats->ex_acquire_count, lwstats->block_count, lwstats->spin_delay_count, lwstats->dequeue_self_count); @@ -342,7 +311,7 @@ get_lwlock_stats_entry(LWLock *lock) /* Fetch or create the entry. */ key.tranche = lock->tranche; - key.instance = T_ID(lock); + key.instance = lock; lwstats = hash_search(lwlock_stats_htab, &key, HASH_ENTER, &found); if (!found) { @@ -464,7 +433,7 @@ InitializeLWLocks(void) /* Initialize all individual LWLocks in main array */ for (id = 0, lock = MainLWLockArray; id < NUM_INDIVIDUAL_LWLOCKS; id++, lock++) - LWLockInitialize(&lock->lock, LWTRANCHE_MAIN); + LWLockInitialize(&lock->lock, id); /* Initialize buffer mapping LWLocks in main array */ lock = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS; @@ -506,10 +475,8 @@ InitializeLWLocks(void) name = trancheNames; trancheNames += strlen(request->tranche_name) + 1; strcpy(name, request->tranche_name); - tranche->lwLockTranche.name = name; tranche->trancheId = LWLockNewTrancheId(); - tranche->lwLockTranche.array_base = lock; - tranche->lwLockTranche.array_stride = sizeof(LWLockPadded); + tranche->trancheName = name; for (j = 0; j < request->num_lwlocks; j++, lock++) LWLockInitialize(&lock->lock, tranche->trancheId); @@ -527,39 +494,25 @@ RegisterLWLockTranches(void) if (LWLockTrancheArray == NULL) { - LWLockTranchesAllocated = 32; - LWLockTrancheArray = (LWLockTranche **) + LWLockTranchesAllocated = 64; + LWLockTrancheArray = (char **) MemoryContextAllocZero(TopMemoryContext, - LWLockTranchesAllocated * sizeof(LWLockTranche *)); + LWLockTranchesAllocated * sizeof(char *)); Assert(LWLockTranchesAllocated >= LWTRANCHE_FIRST_USER_DEFINED); } - MainLWLockTranche.name = "main"; - MainLWLockTranche.array_base = MainLWLockArray; - MainLWLockTranche.array_stride = sizeof(LWLockPadded); - LWLockRegisterTranche(LWTRANCHE_MAIN, &MainLWLockTranche); + for (i = 0; i < NUM_INDIVIDUAL_LWLOCKS; ++i) + LWLockRegisterTranche(i, MainLWLockNames[i]); - BufMappingLWLockTranche.name = "buffer_mapping"; - BufMappingLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS; - BufMappingLWLockTranche.array_stride = sizeof(LWLockPadded); - LWLockRegisterTranche(LWTRANCHE_BUFFER_MAPPING, &BufMappingLWLockTranche); - - LockManagerLWLockTranche.name = "lock_manager"; - LockManagerLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS + - NUM_BUFFER_PARTITIONS; - LockManagerLWLockTranche.array_stride = sizeof(LWLockPadded); - LWLockRegisterTranche(LWTRANCHE_LOCK_MANAGER, &LockManagerLWLockTranche); - - PredicateLockManagerLWLockTranche.name = "predicate_lock_manager"; - PredicateLockManagerLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS + - NUM_BUFFER_PARTITIONS + NUM_LOCK_PARTITIONS; - PredicateLockManagerLWLockTranche.array_stride = sizeof(LWLockPadded); - LWLockRegisterTranche(LWTRANCHE_PREDICATE_LOCK_MANAGER, &PredicateLockManagerLWLockTranche); + LWLockRegisterTranche(LWTRANCHE_BUFFER_MAPPING, "buffer_mapping"); + LWLockRegisterTranche(LWTRANCHE_LOCK_MANAGER, "lock_manager"); + LWLockRegisterTranche(LWTRANCHE_PREDICATE_LOCK_MANAGER, + "predicate_lock_manager"); /* Register named tranches. */ for (i = 0; i < NamedLWLockTrancheRequests; i++) LWLockRegisterTranche(NamedLWLockTrancheArray[i].trancheId, - &NamedLWLockTrancheArray[i].lwLockTranche); + NamedLWLockTrancheArray[i].trancheName); } /* @@ -633,7 +586,7 @@ LWLockNewTrancheId(void) * (TopMemoryContext, static variable, or similar). */ void -LWLockRegisterTranche(int tranche_id, LWLockTranche *tranche) +LWLockRegisterTranche(int tranche_id, char *tranche_name) { Assert(LWLockTrancheArray != NULL); @@ -645,15 +598,14 @@ LWLockRegisterTranche(int tranche_id, LWLockTranche *tranche) while (i <= tranche_id) i *= 2; - LWLockTrancheArray = (LWLockTranche **) - repalloc(LWLockTrancheArray, - i * sizeof(LWLockTranche *)); + LWLockTrancheArray = (char **) + repalloc(LWLockTrancheArray, i * sizeof(char *)); LWLockTranchesAllocated = i; while (j < LWLockTranchesAllocated) LWLockTrancheArray[j++] = NULL; } - LWLockTrancheArray[tranche_id] = tranche; + LWLockTrancheArray[tranche_id] = tranche_name; } /* @@ -729,12 +681,7 @@ LWLockInitialize(LWLock *lock, int tranche_id) static inline void LWLockReportWaitStart(LWLock *lock) { - int lockId = T_ID(lock); - - if (lock->tranche == 0) - pgstat_report_wait_start(PG_WAIT_LWLOCK_NAMED | (uint16) lockId); - else - pgstat_report_wait_start(PG_WAIT_LWLOCK_TRANCHE | lock->tranche); + pgstat_report_wait_start(PG_WAIT_LWLOCK | lock->tranche); } /* @@ -752,10 +699,7 @@ LWLockReportWaitEnd(void) const char * GetLWLockIdentifier(uint32 classId, uint16 eventId) { - if (classId == PG_WAIT_LWLOCK_NAMED) - return MainLWLockNames[eventId]; - - Assert(classId == PG_WAIT_LWLOCK_TRANCHE); + Assert(classId == PG_WAIT_LWLOCK); /* * It is quite possible that user has registered tranche in one of the @@ -763,10 +707,10 @@ GetLWLockIdentifier(uint32 classId, uint16 eventId) * all of them, so we can't assume the tranche is registered here. */ if (eventId >= LWLockTranchesAllocated || - LWLockTrancheArray[eventId]->name == NULL) + LWLockTrancheArray[eventId] == NULL) return "extension"; - return LWLockTrancheArray[eventId]->name; + return LWLockTrancheArray[eventId]; } /* @@ -1279,7 +1223,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode) #endif LWLockReportWaitStart(lock); - TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock), mode); + TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode); for (;;) { @@ -1301,7 +1245,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode) } #endif - TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), T_ID(lock), mode); + TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode); LWLockReportWaitEnd(); LOG_LWDEBUG("LWLockAcquire", lock, "awakened"); @@ -1310,7 +1254,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode) result = false; } - TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), T_ID(lock), mode); + TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), mode); /* Add lock to list of locks held by this backend */ held_lwlocks[num_held_lwlocks].lock = lock; @@ -1361,14 +1305,14 @@ LWLockConditionalAcquire(LWLock *lock, LWLockMode mode) RESUME_INTERRUPTS(); LOG_LWDEBUG("LWLockConditionalAcquire", lock, "failed"); - TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), T_ID(lock), mode); + TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), mode); } else { /* Add lock to list of locks held by this backend */ held_lwlocks[num_held_lwlocks].lock = lock; held_lwlocks[num_held_lwlocks++].mode = mode; - TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), T_ID(lock), mode); + TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), mode); } return !mustwait; } @@ -1440,7 +1384,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode) #endif LWLockReportWaitStart(lock); - TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock), mode); + TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode); for (;;) { @@ -1458,7 +1402,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode) Assert(nwaiters < MAX_BACKENDS); } #endif - TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), T_ID(lock), mode); + TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode); LWLockReportWaitEnd(); LOG_LWDEBUG("LWLockAcquireOrWait", lock, "awakened"); @@ -1488,8 +1432,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode) /* Failed to get lock, so release interrupt holdoff */ RESUME_INTERRUPTS(); LOG_LWDEBUG("LWLockAcquireOrWait", lock, "failed"); - TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), T_ID(lock), - mode); + TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), mode); } else { @@ -1497,7 +1440,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode) /* Add lock to list of locks held by this backend */ held_lwlocks[num_held_lwlocks].lock = lock; held_lwlocks[num_held_lwlocks++].mode = mode; - TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), T_ID(lock), mode); + TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), mode); } return !mustwait; @@ -1657,8 +1600,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval) #endif LWLockReportWaitStart(lock); - TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock), - LW_EXCLUSIVE); + TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), LW_EXCLUSIVE); for (;;) { @@ -1677,8 +1619,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval) } #endif - TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), T_ID(lock), - LW_EXCLUSIVE); + TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), LW_EXCLUSIVE); LWLockReportWaitEnd(); LOG_LWDEBUG("LWLockWaitForVar", lock, "awakened"); @@ -1686,7 +1627,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval) /* Now loop back and check the status of the lock again. */ } - TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), T_ID(lock), LW_EXCLUSIVE); + TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), LW_EXCLUSIVE); /* * Fix the process wait semaphore's count for any absorbed wakeups. @@ -1784,7 +1725,7 @@ LWLockRelease(LWLock *lock) break; if (i < 0) - elog(ERROR, "lock %s %d is not held", T_NAME(lock), T_ID(lock)); + elog(ERROR, "lock %s is not held", T_NAME(lock)); mode = held_lwlocks[i].mode; @@ -1829,7 +1770,7 @@ LWLockRelease(LWLock *lock) LWLockWakeup(lock); } - TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock), T_ID(lock)); + TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock)); /* * Now okay to allow cancel/die interrupts. diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c index abe3f1a63d19729c3b15bd0dadc41e365080e1b1..988a2970b2d77121269c8ec7ddb3f5e91062ee76 100644 --- a/src/backend/utils/mmgr/dsa.c +++ b/src/backend/utils/mmgr/dsa.c @@ -362,9 +362,6 @@ struct dsa_area /* Pointer to the control object in shared memory. */ dsa_area_control *control; - /* The lock tranche for this process. */ - LWLockTranche lwlock_tranche; - /* Has the mapping been pinned? */ bool mapping_pinned; @@ -1207,10 +1204,8 @@ create_internal(void *place, size_t size, area->mapping_pinned = false; memset(area->segment_maps, 0, sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS); area->high_segment_index = 0; - area->lwlock_tranche.array_base = &area->control->pools[0]; - area->lwlock_tranche.array_stride = sizeof(dsa_area_pool); - area->lwlock_tranche.name = control->lwlock_tranche_name; - LWLockRegisterTranche(control->lwlock_tranche_id, &area->lwlock_tranche); + LWLockRegisterTranche(control->lwlock_tranche_id, + control->lwlock_tranche_name); LWLockInitialize(&control->lock, control->lwlock_tranche_id); for (i = 0; i < DSA_NUM_SIZE_CLASSES; ++i) LWLockInitialize(DSA_SCLASS_LOCK(area, i), @@ -1267,10 +1262,8 @@ attach_internal(void *place, dsm_segment *segment, dsa_handle handle) memset(&area->segment_maps[0], 0, sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS); area->high_segment_index = 0; - area->lwlock_tranche.array_base = &area->control->pools[0]; - area->lwlock_tranche.array_stride = sizeof(dsa_area_pool); - area->lwlock_tranche.name = control->lwlock_tranche_name; - LWLockRegisterTranche(control->lwlock_tranche_id, &area->lwlock_tranche); + LWLockRegisterTranche(control->lwlock_tranche_id, + control->lwlock_tranche_name); /* Set up the segment map for this process's mapping. */ segment_map = &area->segment_maps[0]; diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d index 2f92dfa9adb00e921bee1d4b32022b52bb36f8d5..adcebe2e055b24e4a5f4374c66496fae6861c560 100644 --- a/src/backend/utils/probes.d +++ b/src/backend/utils/probes.d @@ -28,14 +28,14 @@ provider postgresql { probe transaction__commit(LocalTransactionId); probe transaction__abort(LocalTransactionId); - probe lwlock__acquire(const char *, int, LWLockMode); - probe lwlock__release(const char *, int); - probe lwlock__wait__start(const char *, int, LWLockMode); - probe lwlock__wait__done(const char *, int, LWLockMode); - probe lwlock__condacquire(const char *, int, LWLockMode); - probe lwlock__condacquire__fail(const char *, int, LWLockMode); - probe lwlock__acquire__or__wait(const char *, int, LWLockMode); - probe lwlock__acquire__or__wait__fail(const char *, int, LWLockMode); + probe lwlock__acquire(const char *, LWLockMode); + probe lwlock__release(const char *); + probe lwlock__wait__start(const char *, LWLockMode); + probe lwlock__wait__done(const char *, LWLockMode); + probe lwlock__condacquire(const char *, LWLockMode); + probe lwlock__condacquire__fail(const char *, LWLockMode); + probe lwlock__acquire__or__wait(const char *, LWLockMode); + probe lwlock__acquire__or__wait__fail(const char *, LWLockMode); probe lock__wait__start(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE); probe lock__wait__done(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE); diff --git a/src/include/access/slru.h b/src/include/access/slru.h index 5fcebc52fba4a38e694798608cc3f4ccc4964235..ca8ab7ba5248d5aebaf32688f1ea1d144de2adcc 100644 --- a/src/include/access/slru.h +++ b/src/include/access/slru.h @@ -104,7 +104,6 @@ typedef struct SlruSharedData /* LWLocks */ int lwlock_tranche_id; - LWLockTranche lwlock_tranche; char lwlock_tranche_name[SLRU_MAX_NAME_LENGTH]; LWLockPadded *buffer_locks; } SlruSharedData; diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 152ff0620852133323edda179e17539893fbe539..282f8aeccd2ebaea771d813fbc0401903c891a78 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -715,8 +715,7 @@ typedef enum BackendState * Wait Classes * ---------- */ -#define PG_WAIT_LWLOCK_NAMED 0x01000000U -#define PG_WAIT_LWLOCK_TRANCHE 0x02000000U +#define PG_WAIT_LWLOCK 0x01000000U #define PG_WAIT_LOCK 0x03000000U #define PG_WAIT_BUFFER_PIN 0x04000000U #define PG_WAIT_ACTIVITY 0x05000000U diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index 9a2d86975cad72971c07764bd786fc893a11b07a..db1c687e21e8398bb201666b833c5eb6991d82e5 100644 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -24,32 +24,6 @@ struct PGPROC; -/* - * Prior to PostgreSQL 9.4, every lightweight lock in the system was stored - * in a single array. For convenience and for compatibility with past - * releases, we still have a main array, but it's now also permissible to - * store LWLocks elsewhere in the main shared memory segment or in a dynamic - * shared memory segment. Each array of lwlocks forms a separate "tranche". - * - * It's occasionally necessary to identify a particular LWLock "by name"; e.g. - * because we wish to report the lock to dtrace. We could store a name or - * other identifying information in the lock itself, but since it's common - * to have many nearly-identical locks (e.g. one per buffer) this would end - * up wasting significant amounts of memory. Instead, each lwlock stores a - * tranche ID which tells us which array it's part of. Based on that, we can - * figure out where the lwlock lies within the array using the data structure - * shown below; the lock is then identified based on the tranche name and - * computed array index. We need the array stride because the array might not - * be an array of lwlocks, but rather some larger data structure that includes - * one or more lwlocks per element. - */ -typedef struct LWLockTranche -{ - const char *name; - void *array_base; - Size array_stride; -} LWLockTranche; - /* * Code outside of lwlock.c should not manipulate the contents of this * structure directly, but we have to declare it here to allow LWLocks to be @@ -118,8 +92,8 @@ extern char *MainLWLockNames[]; /* struct for storing named tranche information */ typedef struct NamedLWLockTranche { - LWLockTranche lwLockTranche; int trancheId; + char *trancheName; } NamedLWLockTranche; extern PGDLLIMPORT NamedLWLockTranche *NamedLWLockTrancheArray; @@ -199,9 +173,9 @@ extern LWLockPadded *GetNamedLWLockTranche(const char *tranche_name); * There is another, more flexible method of obtaining lwlocks. First, call * LWLockNewTrancheId just once to obtain a tranche ID; this allocates from * a shared counter. Next, each individual process using the tranche should - * call LWLockRegisterTranche() to associate that tranche ID with appropriate - * metadata. Finally, LWLockInitialize should be called just once per lwlock, - * passing the tranche ID as an argument. + * call LWLockRegisterTranche() to associate that tranche ID with a name. + * Finally, LWLockInitialize should be called just once per lwlock, passing + * the tranche ID as an argument. * * It may seem strange that each process using the tranche must register it * separately, but dynamic shared memory segments aren't guaranteed to be @@ -209,17 +183,18 @@ extern LWLockPadded *GetNamedLWLockTranche(const char *tranche_name); * registration in the main shared memory segment wouldn't work for that case. */ extern int LWLockNewTrancheId(void); -extern void LWLockRegisterTranche(int tranche_id, LWLockTranche *tranche); +extern void LWLockRegisterTranche(int tranche_id, char *tranche_name); extern void LWLockInitialize(LWLock *lock, int tranche_id); /* - * We reserve a few predefined tranche IDs. A call to LWLockNewTrancheId - * will never return a value less than LWTRANCHE_FIRST_USER_DEFINED. + * Every tranche ID less than NUM_INDIVIDUAL_LWLOCKS is reserved; also, + * we reserve additional tranche IDs for builtin tranches not included in + * the set of individual LWLocks. A call to LWLockNewTrancheId will never + * return a value less than LWTRANCHE_FIRST_USER_DEFINED. */ typedef enum BuiltinTrancheIds { - LWTRANCHE_MAIN, - LWTRANCHE_CLOG_BUFFERS, + LWTRANCHE_CLOG_BUFFERS = NUM_INDIVIDUAL_LWLOCKS, LWTRANCHE_COMMITTS_BUFFERS, LWTRANCHE_SUBTRANS_BUFFERS, LWTRANCHE_MXACTOFFSET_BUFFERS,