postgresql/src/backend/utils/activity/wait_event.c

765 lines
19 KiB
C

/* ----------
* wait_event.c
* Wait event reporting infrastructure.
*
* Copyright (c) 2001-2023, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* src/backend/utils/activity/wait_event.c
*
* NOTES
*
* To make pgstat_report_wait_start() and pgstat_report_wait_end() as
* lightweight as possible, they do not check if shared memory (MyProc
* specifically, where the wait event is stored) is already available. Instead
* we initially set my_wait_event_info to a process local variable, which then
* is redirected to shared memory using pgstat_set_wait_event_storage(). For
* the same reason pgstat_track_activities is not checked - the check adds
* more work than it saves.
*
* ----------
*/
#include "postgres.h"
#include "storage/lmgr.h" /* for GetLockNameFromTagType */
#include "storage/lwlock.h" /* for GetLWLockIdentifier */
#include "utils/wait_event.h"
static const char *pgstat_get_wait_activity(WaitEventActivity w);
static const char *pgstat_get_wait_client(WaitEventClient w);
static const char *pgstat_get_wait_ipc(WaitEventIPC w);
static const char *pgstat_get_wait_timeout(WaitEventTimeout w);
static const char *pgstat_get_wait_io(WaitEventIO w);
static uint32 local_my_wait_event_info;
uint32 *my_wait_event_info = &local_my_wait_event_info;
/*
* Configure wait event reporting to report wait events to *wait_event_info.
* *wait_event_info needs to be valid until pgstat_reset_wait_event_storage()
* is called.
*
* Expected to be called during backend startup, to point my_wait_event_info
* into shared memory.
*/
void
pgstat_set_wait_event_storage(uint32 *wait_event_info)
{
my_wait_event_info = wait_event_info;
}
/*
* Reset wait event storage location.
*
* Expected to be called during backend shutdown, before the location set up
* pgstat_set_wait_event_storage() becomes invalid.
*/
void
pgstat_reset_wait_event_storage(void)
{
my_wait_event_info = &local_my_wait_event_info;
}
/* ----------
* pgstat_get_wait_event_type() -
*
* Return a string representing the current wait event type, backend is
* waiting on.
*/
const char *
pgstat_get_wait_event_type(uint32 wait_event_info)
{
uint32 classId;
const char *event_type;
/* report process as not waiting. */
if (wait_event_info == 0)
return NULL;
classId = wait_event_info & 0xFF000000;
switch (classId)
{
case PG_WAIT_LWLOCK:
event_type = "LWLock";
break;
case PG_WAIT_LOCK:
event_type = "Lock";
break;
case PG_WAIT_BUFFER_PIN:
event_type = "BufferPin";
break;
case PG_WAIT_ACTIVITY:
event_type = "Activity";
break;
case PG_WAIT_CLIENT:
event_type = "Client";
break;
case PG_WAIT_EXTENSION:
event_type = "Extension";
break;
case PG_WAIT_IPC:
event_type = "IPC";
break;
case PG_WAIT_TIMEOUT:
event_type = "Timeout";
break;
case PG_WAIT_IO:
event_type = "IO";
break;
default:
event_type = "???";
break;
}
return event_type;
}
/* ----------
* pgstat_get_wait_event() -
*
* Return a string representing the current wait event, backend is
* waiting on.
*/
const char *
pgstat_get_wait_event(uint32 wait_event_info)
{
uint32 classId;
uint16 eventId;
const char *event_name;
/* report process as not waiting. */
if (wait_event_info == 0)
return NULL;
classId = wait_event_info & 0xFF000000;
eventId = wait_event_info & 0x0000FFFF;
switch (classId)
{
case PG_WAIT_LWLOCK:
event_name = GetLWLockIdentifier(classId, eventId);
break;
case PG_WAIT_LOCK:
event_name = GetLockNameFromTagType(eventId);
break;
case PG_WAIT_BUFFER_PIN:
event_name = "BufferPin";
break;
case PG_WAIT_ACTIVITY:
{
WaitEventActivity w = (WaitEventActivity) wait_event_info;
event_name = pgstat_get_wait_activity(w);
break;
}
case PG_WAIT_CLIENT:
{
WaitEventClient w = (WaitEventClient) wait_event_info;
event_name = pgstat_get_wait_client(w);
break;
}
case PG_WAIT_EXTENSION:
event_name = "Extension";
break;
case PG_WAIT_IPC:
{
WaitEventIPC w = (WaitEventIPC) wait_event_info;
event_name = pgstat_get_wait_ipc(w);
break;
}
case PG_WAIT_TIMEOUT:
{
WaitEventTimeout w = (WaitEventTimeout) wait_event_info;
event_name = pgstat_get_wait_timeout(w);
break;
}
case PG_WAIT_IO:
{
WaitEventIO w = (WaitEventIO) wait_event_info;
event_name = pgstat_get_wait_io(w);
break;
}
default:
event_name = "unknown wait event";
break;
}
return event_name;
}
/* ----------
* pgstat_get_wait_activity() -
*
* Convert WaitEventActivity to string.
* ----------
*/
static const char *
pgstat_get_wait_activity(WaitEventActivity w)
{
const char *event_name = "unknown wait event";
switch (w)
{
case WAIT_EVENT_ARCHIVER_MAIN:
event_name = "ArchiverMain";
break;
case WAIT_EVENT_AUTOVACUUM_MAIN:
event_name = "AutoVacuumMain";
break;
case WAIT_EVENT_BGWRITER_HIBERNATE:
event_name = "BgWriterHibernate";
break;
case WAIT_EVENT_BGWRITER_MAIN:
event_name = "BgWriterMain";
break;
case WAIT_EVENT_CHECKPOINTER_MAIN:
event_name = "CheckpointerMain";
break;
case WAIT_EVENT_LOGICAL_APPLY_MAIN:
event_name = "LogicalApplyMain";
break;
case WAIT_EVENT_LOGICAL_LAUNCHER_MAIN:
event_name = "LogicalLauncherMain";
break;
case WAIT_EVENT_LOGICAL_PARALLEL_APPLY_MAIN:
event_name = "LogicalParallelApplyMain";
break;
case WAIT_EVENT_RECOVERY_WAL_STREAM:
event_name = "RecoveryWalStream";
break;
case WAIT_EVENT_SYSLOGGER_MAIN:
event_name = "SysLoggerMain";
break;
case WAIT_EVENT_WAL_RECEIVER_MAIN:
event_name = "WalReceiverMain";
break;
case WAIT_EVENT_WAL_SENDER_MAIN:
event_name = "WalSenderMain";
break;
case WAIT_EVENT_WAL_WRITER_MAIN:
event_name = "WalWriterMain";
break;
/* no default case, so that compiler will warn */
}
return event_name;
}
/* ----------
* pgstat_get_wait_client() -
*
* Convert WaitEventClient to string.
* ----------
*/
static const char *
pgstat_get_wait_client(WaitEventClient w)
{
const char *event_name = "unknown wait event";
switch (w)
{
case WAIT_EVENT_CLIENT_READ:
event_name = "ClientRead";
break;
case WAIT_EVENT_CLIENT_WRITE:
event_name = "ClientWrite";
break;
case WAIT_EVENT_GSS_OPEN_SERVER:
event_name = "GSSOpenServer";
break;
case WAIT_EVENT_LIBPQWALRECEIVER_CONNECT:
event_name = "LibPQWalReceiverConnect";
break;
case WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE:
event_name = "LibPQWalReceiverReceive";
break;
case WAIT_EVENT_SSL_OPEN_SERVER:
event_name = "SSLOpenServer";
break;
case WAIT_EVENT_WAL_SENDER_WAIT_WAL:
event_name = "WalSenderWaitForWAL";
break;
case WAIT_EVENT_WAL_SENDER_WRITE_DATA:
event_name = "WalSenderWriteData";
break;
/* no default case, so that compiler will warn */
}
return event_name;
}
/* ----------
* pgstat_get_wait_ipc() -
*
* Convert WaitEventIPC to string.
* ----------
*/
static const char *
pgstat_get_wait_ipc(WaitEventIPC w)
{
const char *event_name = "unknown wait event";
switch (w)
{
case WAIT_EVENT_APPEND_READY:
event_name = "AppendReady";
break;
case WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND:
event_name = "ArchiveCleanupCommand";
break;
case WAIT_EVENT_ARCHIVE_COMMAND:
event_name = "ArchiveCommand";
break;
case WAIT_EVENT_BACKEND_TERMINATION:
event_name = "BackendTermination";
break;
case WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE:
event_name = "BackupWaitWalArchive";
break;
case WAIT_EVENT_BGWORKER_SHUTDOWN:
event_name = "BgWorkerShutdown";
break;
case WAIT_EVENT_BGWORKER_STARTUP:
event_name = "BgWorkerStartup";
break;
case WAIT_EVENT_BTREE_PAGE:
event_name = "BtreePage";
break;
case WAIT_EVENT_BUFFER_IO:
event_name = "BufferIO";
break;
case WAIT_EVENT_CHECKPOINT_DONE:
event_name = "CheckpointDone";
break;
case WAIT_EVENT_CHECKPOINT_START:
event_name = "CheckpointStart";
break;
case WAIT_EVENT_EXECUTE_GATHER:
event_name = "ExecuteGather";
break;
case WAIT_EVENT_HASH_BATCH_ALLOCATE:
event_name = "HashBatchAllocate";
break;
case WAIT_EVENT_HASH_BATCH_ELECT:
event_name = "HashBatchElect";
break;
case WAIT_EVENT_HASH_BATCH_LOAD:
event_name = "HashBatchLoad";
break;
case WAIT_EVENT_HASH_BUILD_ALLOCATE:
event_name = "HashBuildAllocate";
break;
case WAIT_EVENT_HASH_BUILD_ELECT:
event_name = "HashBuildElect";
break;
case WAIT_EVENT_HASH_BUILD_HASH_INNER:
event_name = "HashBuildHashInner";
break;
case WAIT_EVENT_HASH_BUILD_HASH_OUTER:
event_name = "HashBuildHashOuter";
break;
case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE:
event_name = "HashGrowBatchesDecide";
break;
case WAIT_EVENT_HASH_GROW_BATCHES_ELECT:
event_name = "HashGrowBatchesElect";
break;
case WAIT_EVENT_HASH_GROW_BATCHES_FINISH:
event_name = "HashGrowBatchesFinish";
break;
case WAIT_EVENT_HASH_GROW_BATCHES_REALLOCATE:
event_name = "HashGrowBatchesReallocate";
break;
case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION:
event_name = "HashGrowBatchesRepartition";
break;
case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT:
event_name = "HashGrowBucketsElect";
break;
case WAIT_EVENT_HASH_GROW_BUCKETS_REALLOCATE:
event_name = "HashGrowBucketsReallocate";
break;
case WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT:
event_name = "HashGrowBucketsReinsert";
break;
case WAIT_EVENT_LOGICAL_APPLY_SEND_DATA:
event_name = "LogicalApplySendData";
break;
case WAIT_EVENT_LOGICAL_PARALLEL_APPLY_STATE_CHANGE:
event_name = "LogicalParallelApplyStateChange";
break;
case WAIT_EVENT_LOGICAL_SYNC_DATA:
event_name = "LogicalSyncData";
break;
case WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE:
event_name = "LogicalSyncStateChange";
break;
case WAIT_EVENT_MQ_INTERNAL:
event_name = "MessageQueueInternal";
break;
case WAIT_EVENT_MQ_PUT_MESSAGE:
event_name = "MessageQueuePutMessage";
break;
case WAIT_EVENT_MQ_RECEIVE:
event_name = "MessageQueueReceive";
break;
case WAIT_EVENT_MQ_SEND:
event_name = "MessageQueueSend";
break;
case WAIT_EVENT_PARALLEL_BITMAP_SCAN:
event_name = "ParallelBitmapScan";
break;
case WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN:
event_name = "ParallelCreateIndexScan";
break;
case WAIT_EVENT_PARALLEL_FINISH:
event_name = "ParallelFinish";
break;
case WAIT_EVENT_PROCARRAY_GROUP_UPDATE:
event_name = "ProcArrayGroupUpdate";
break;
case WAIT_EVENT_PROC_SIGNAL_BARRIER:
event_name = "ProcSignalBarrier";
break;
case WAIT_EVENT_PROMOTE:
event_name = "Promote";
break;
case WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT:
event_name = "RecoveryConflictSnapshot";
break;
case WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE:
event_name = "RecoveryConflictTablespace";
break;
case WAIT_EVENT_RECOVERY_END_COMMAND:
event_name = "RecoveryEndCommand";
break;
case WAIT_EVENT_RECOVERY_PAUSE:
event_name = "RecoveryPause";
break;
case WAIT_EVENT_REPLICATION_ORIGIN_DROP:
event_name = "ReplicationOriginDrop";
break;
case WAIT_EVENT_REPLICATION_SLOT_DROP:
event_name = "ReplicationSlotDrop";
break;
case WAIT_EVENT_RESTORE_COMMAND:
event_name = "RestoreCommand";
break;
case WAIT_EVENT_SAFE_SNAPSHOT:
event_name = "SafeSnapshot";
break;
case WAIT_EVENT_SYNC_REP:
event_name = "SyncRep";
break;
case WAIT_EVENT_WAL_RECEIVER_EXIT:
event_name = "WalReceiverExit";
break;
case WAIT_EVENT_WAL_RECEIVER_WAIT_START:
event_name = "WalReceiverWaitStart";
break;
case WAIT_EVENT_XACT_GROUP_UPDATE:
event_name = "XactGroupUpdate";
break;
/* no default case, so that compiler will warn */
}
return event_name;
}
/* ----------
* pgstat_get_wait_timeout() -
*
* Convert WaitEventTimeout to string.
* ----------
*/
static const char *
pgstat_get_wait_timeout(WaitEventTimeout w)
{
const char *event_name = "unknown wait event";
switch (w)
{
case WAIT_EVENT_BASE_BACKUP_THROTTLE:
event_name = "BaseBackupThrottle";
break;
case WAIT_EVENT_CHECKPOINT_WRITE_DELAY:
event_name = "CheckpointWriteDelay";
break;
case WAIT_EVENT_PG_SLEEP:
event_name = "PgSleep";
break;
case WAIT_EVENT_RECOVERY_APPLY_DELAY:
event_name = "RecoveryApplyDelay";
break;
case WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL:
event_name = "RecoveryRetrieveRetryInterval";
break;
case WAIT_EVENT_REGISTER_SYNC_REQUEST:
event_name = "RegisterSyncRequest";
break;
case WAIT_EVENT_SPIN_DELAY:
event_name = "SpinDelay";
break;
case WAIT_EVENT_VACUUM_DELAY:
event_name = "VacuumDelay";
break;
case WAIT_EVENT_VACUUM_TRUNCATE:
event_name = "VacuumTruncate";
break;
/* no default case, so that compiler will warn */
}
return event_name;
}
/* ----------
* pgstat_get_wait_io() -
*
* Convert WaitEventIO to string.
* ----------
*/
static const char *
pgstat_get_wait_io(WaitEventIO w)
{
const char *event_name = "unknown wait event";
switch (w)
{
case WAIT_EVENT_BASEBACKUP_READ:
event_name = "BaseBackupRead";
break;
case WAIT_EVENT_BASEBACKUP_SYNC:
event_name = "BaseBackupSync";
break;
case WAIT_EVENT_BASEBACKUP_WRITE:
event_name = "BaseBackupWrite";
break;
case WAIT_EVENT_BUFFILE_READ:
event_name = "BufFileRead";
break;
case WAIT_EVENT_BUFFILE_WRITE:
event_name = "BufFileWrite";
break;
case WAIT_EVENT_BUFFILE_TRUNCATE:
event_name = "BufFileTruncate";
break;
case WAIT_EVENT_CONTROL_FILE_READ:
event_name = "ControlFileRead";
break;
case WAIT_EVENT_CONTROL_FILE_SYNC:
event_name = "ControlFileSync";
break;
case WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE:
event_name = "ControlFileSyncUpdate";
break;
case WAIT_EVENT_CONTROL_FILE_WRITE:
event_name = "ControlFileWrite";
break;
case WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE:
event_name = "ControlFileWriteUpdate";
break;
case WAIT_EVENT_COPY_FILE_READ:
event_name = "CopyFileRead";
break;
case WAIT_EVENT_COPY_FILE_WRITE:
event_name = "CopyFileWrite";
break;
case WAIT_EVENT_DATA_FILE_EXTEND:
event_name = "DataFileExtend";
break;
case WAIT_EVENT_DATA_FILE_FLUSH:
event_name = "DataFileFlush";
break;
case WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC:
event_name = "DataFileImmediateSync";
break;
case WAIT_EVENT_DATA_FILE_PREFETCH:
event_name = "DataFilePrefetch";
break;
case WAIT_EVENT_DATA_FILE_READ:
event_name = "DataFileRead";
break;
case WAIT_EVENT_DATA_FILE_SYNC:
event_name = "DataFileSync";
break;
case WAIT_EVENT_DATA_FILE_TRUNCATE:
event_name = "DataFileTruncate";
break;
case WAIT_EVENT_DATA_FILE_WRITE:
event_name = "DataFileWrite";
break;
case WAIT_EVENT_DSM_ALLOCATE:
event_name = "DSMAllocate";
break;
case WAIT_EVENT_DSM_FILL_ZERO_WRITE:
event_name = "DSMFillZeroWrite";
break;
case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ:
event_name = "LockFileAddToDataDirRead";
break;
case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC:
event_name = "LockFileAddToDataDirSync";
break;
case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE:
event_name = "LockFileAddToDataDirWrite";
break;
case WAIT_EVENT_LOCK_FILE_CREATE_READ:
event_name = "LockFileCreateRead";
break;
case WAIT_EVENT_LOCK_FILE_CREATE_SYNC:
event_name = "LockFileCreateSync";
break;
case WAIT_EVENT_LOCK_FILE_CREATE_WRITE:
event_name = "LockFileCreateWrite";
break;
case WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ:
event_name = "LockFileReCheckDataDirRead";
break;
case WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC:
event_name = "LogicalRewriteCheckpointSync";
break;
case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC:
event_name = "LogicalRewriteMappingSync";
break;
case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE:
event_name = "LogicalRewriteMappingWrite";
break;
case WAIT_EVENT_LOGICAL_REWRITE_SYNC:
event_name = "LogicalRewriteSync";
break;
case WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE:
event_name = "LogicalRewriteTruncate";
break;
case WAIT_EVENT_LOGICAL_REWRITE_WRITE:
event_name = "LogicalRewriteWrite";
break;
case WAIT_EVENT_RELATION_MAP_READ:
event_name = "RelationMapRead";
break;
case WAIT_EVENT_RELATION_MAP_REPLACE:
event_name = "RelationMapReplace";
break;
case WAIT_EVENT_RELATION_MAP_WRITE:
event_name = "RelationMapWrite";
break;
case WAIT_EVENT_REORDER_BUFFER_READ:
event_name = "ReorderBufferRead";
break;
case WAIT_EVENT_REORDER_BUFFER_WRITE:
event_name = "ReorderBufferWrite";
break;
case WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ:
event_name = "ReorderLogicalMappingRead";
break;
case WAIT_EVENT_REPLICATION_SLOT_READ:
event_name = "ReplicationSlotRead";
break;
case WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC:
event_name = "ReplicationSlotRestoreSync";
break;
case WAIT_EVENT_REPLICATION_SLOT_SYNC:
event_name = "ReplicationSlotSync";
break;
case WAIT_EVENT_REPLICATION_SLOT_WRITE:
event_name = "ReplicationSlotWrite";
break;
case WAIT_EVENT_SLRU_FLUSH_SYNC:
event_name = "SLRUFlushSync";
break;
case WAIT_EVENT_SLRU_READ:
event_name = "SLRURead";
break;
case WAIT_EVENT_SLRU_SYNC:
event_name = "SLRUSync";
break;
case WAIT_EVENT_SLRU_WRITE:
event_name = "SLRUWrite";
break;
case WAIT_EVENT_SNAPBUILD_READ:
event_name = "SnapbuildRead";
break;
case WAIT_EVENT_SNAPBUILD_SYNC:
event_name = "SnapbuildSync";
break;
case WAIT_EVENT_SNAPBUILD_WRITE:
event_name = "SnapbuildWrite";
break;
case WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC:
event_name = "TimelineHistoryFileSync";
break;
case WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE:
event_name = "TimelineHistoryFileWrite";
break;
case WAIT_EVENT_TIMELINE_HISTORY_READ:
event_name = "TimelineHistoryRead";
break;
case WAIT_EVENT_TIMELINE_HISTORY_SYNC:
event_name = "TimelineHistorySync";
break;
case WAIT_EVENT_TIMELINE_HISTORY_WRITE:
event_name = "TimelineHistoryWrite";
break;
case WAIT_EVENT_TWOPHASE_FILE_READ:
event_name = "TwophaseFileRead";
break;
case WAIT_EVENT_TWOPHASE_FILE_SYNC:
event_name = "TwophaseFileSync";
break;
case WAIT_EVENT_TWOPHASE_FILE_WRITE:
event_name = "TwophaseFileWrite";
break;
case WAIT_EVENT_VERSION_FILE_WRITE:
event_name = "VersionFileWrite";
break;
case WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ:
event_name = "WALSenderTimelineHistoryRead";
break;
case WAIT_EVENT_WAL_BOOTSTRAP_SYNC:
event_name = "WALBootstrapSync";
break;
case WAIT_EVENT_WAL_BOOTSTRAP_WRITE:
event_name = "WALBootstrapWrite";
break;
case WAIT_EVENT_WAL_COPY_READ:
event_name = "WALCopyRead";
break;
case WAIT_EVENT_WAL_COPY_SYNC:
event_name = "WALCopySync";
break;
case WAIT_EVENT_WAL_COPY_WRITE:
event_name = "WALCopyWrite";
break;
case WAIT_EVENT_WAL_INIT_SYNC:
event_name = "WALInitSync";
break;
case WAIT_EVENT_WAL_INIT_WRITE:
event_name = "WALInitWrite";
break;
case WAIT_EVENT_WAL_READ:
event_name = "WALRead";
break;
case WAIT_EVENT_WAL_SYNC:
event_name = "WALSync";
break;
case WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN:
event_name = "WALSyncMethodAssign";
break;
case WAIT_EVENT_WAL_WRITE:
event_name = "WALWrite";
break;
/* no default case, so that compiler will warn */
}
return event_name;
}