等待事件概述
在任意时间点,每一个数据库服务端进程,要么正忙于处理一个请求,要么正在等待一个特定的事件发生。我们说它处于忙的状态,意味着这个进程当时是需要使用CPU的。举例来说,一个会话进程在执行一个SQL过程时,可能正在进行一个算术计算,我们说它处于忙的状态,而不是等待状态。与此同时,另一个会话进程可能在提交事务,它在等待操作系统的响应,告诉它刷写日志时使用的fsync系统调用已经完成,这时我们说它处于等待状态。
下面的例子展示了如何查看正在发生的等待事件:
SELECT pid, wait_event_type, wait_event
FROM pg_stat_activity
WHERE wait_event is NOT NULL;
执行下面的查询,可以查看系统中收集和汇总的等待事件统计信息:
SELECT * FROM pg_stat_wait_event
ORDER BY total_time DESC;
执行下面的查询,可以查看单个会话发生的等待事件统计信息:
SELECT pg_stat_reset_wait_event(pg_backend_pid());
-- 在当前会话中,执行一系列SQL命令
SELECT * FROM pg_stat_get_wait_event(pg_backend_pid()) AS we
ORDER BY total_time DESC;
表 1. 等待事件类型
等待事件类型 | 描述 |
---|---|
Activity |
服务器进程空闲。此事件类型表示在其主处理循环中等待活动的进程。wait_event 将识别特定的等待点;参见 表 2。 |
BufferPin |
服务器进程正在等待对数据缓冲的独占访问。 如果另一个进程持有一个打开的游标,该游标最后一次从相关缓冲区读取数据,则缓冲区销等待可能是漫长的。参见 表 3。 |
Client |
服务器进程正在等待连接到用户应用程序的套接字上的活动。 因此,服务器预计发生一些独立于其内部进程的事情。wait_event 将识别特定的等待点;参见 表 4。 |
CPU |
服务器进程在 CPU 中处于活动状态或正在等待 CPU。参见 表 5。 |
Extension |
服务器进程正在等待扩展模块定义的某个条件。参见 表 6。 |
IO |
服务器进程正在等待一个I/O操作完成。wait_event 将识别特定的等待点;参见 表 7。 |
IPC |
服务器进程正在等待与另一个服务器进程进行交互。wait_event 将识别特定的等待点;参见 表 8。 |
Lock |
服务器进程正在等待一个重量级锁。重量级锁,也称为锁管理器锁或简单锁,主要保护表等SQL可见对象。 然而,它们也用于确保某些内部操作的互斥,例如关系扩展。wait_event 将识别等待的锁的类型;参见 表 9。 |
LWLock |
服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。wait_event 将包含标识轻量级锁用途的名称。 (有些锁有特定的名称;有些锁表示的是具有相同用途的一组锁。)参见 表 10。 |
SpinLock |
服务器进程正在等待一个自旋锁。大多数这样的锁保护共享内存中的特定数据结构。wait_event 将包含标识自旋锁用途的名称。 (有些锁有特定的名称;有些锁表示的是具有相同用途的一组锁。)参见 表 11。 |
Timeout |
服务器进程正在等待超时过期。wait_event 将识别特定的等待点;参见 表 12。 |
表 2. Activity
类型的等待事件
Activity 等待事件 |
描述 |
---|---|
ArchiverMain |
在归档进程的主循环中等待。 |
AnalyzeLauncherMain |
在自动分析启动过程的主循环中等待。 |
BgWriterHibernate |
在后台写进程中等待,休眠状态。 |
BgWriterMain |
在后台写进程主循环中等待。 |
CheckpointerMain |
在校验指针进程的主循环中等待。 |
LogicalApplyMain |
在逻辑复制应用进程的主循环中等待。 |
LogicalLauncherMain |
在逻辑复制启动器进程的主循环中等待。 |
PgStatMain |
在统计收集器进程的主循环中等待。 |
RecoveryWalStream |
流恢复期间,在启动进程主循环等待WAL到达。 |
SysLoggerMain |
在后台日志进程的主循环中等待。 |
UndoLauncherMain |
在回滚段维护启动器进程的主循环中等待。 |
WalReceiverMain |
在WAL接收器进程的主循环中等待。 |
WalSenderMain |
在WAL发送者进程的主循环中等待。 |
WalWriterMain |
在WAL写入进程的主循环中等待。 |
表 3. BufferPin
类型的等待事件
BufferPin 等待事件 |
描述 |
---|---|
BufferPin |
等待获得缓冲区上的独占销。 |
表 4. Client
类型的等待事件
Client 等待事件 |
描述 |
---|---|
ClientRead |
等待从客户端读取数据。 |
ClientWrite |
等待写入数据到客户端。 |
GSSOpenServer |
在建立GSSAPI会话时等待从客户端读取数据。 |
LibPQWalReceiverConnect |
在WAL接收器等待与远程服务器建立连接。 |
LibPQWalReceiverReceive |
在WAL接收器中等待从远程服务器接收数据。 |
LibPQStorageConnect |
在计算服务器等待与远程存储服务器建立连接。 |
LibPQStorageReceive |
在计算服务器等待从远程存储服务器接收数据。 |
SSLOpenServer |
在尝试连接时等待SSL。 |
WalReceiverWaitStart |
等待启动进程发送用于流复制的初始数据。 |
WalSenderWaitForWAL |
在WAL发送器进程中等待WAL被刷新。 |
WalSenderWriteData |
在WAL发送器进程中处理WAL接收器的回复时,等待任何活动。 |
表 5. CPU
类型的等待事件
CPU 等待事件 |
描述 |
---|---|
CPU |
在 CPU 中处于活动状态或正在等待 CPU。 |
表 6. Extension
类型的等待事件
Extension 等待事件 |
描述 |
---|---|
Extension |
在扩展中等待。 |
表 7. IO
类型的等待事件
IO 等待事件 |
描述 |
---|---|
BufFileRead |
等待从缓冲文件中读取。 |
BufFileWrite |
等待对缓冲文件的写入。 |
ControlFileRead |
等待读取pg_control 文件。 |
ControlFileSync |
等待pg_control 文件到达持久存储。 |
ControlFileSyncUpdate |
等待更新pg_control 文件以达到持久存储。 |
ControlFileWrite |
等待写入pg_control 文件。 |
ControlFileWriteUpdate |
等待写入更新pg_control 文件。 |
CopyFileRead |
在文件复制操作期间等待读取。 |
CopyFileWrite |
在文件拷贝操作期间等待写入。 |
DSMFillZeroWrite |
等待用零填充动态共享内存备份文件。 |
DataFileExtend |
等待关系数据文件被扩展。 |
DataFileFlush |
等待关系数据文件达到持久存储。 |
DataFileImmediateSync |
等待关系数据文件到持久存储的立即同步。 |
DataFilePrefetch |
等待关系数据文件的异步预取。 |
DataFileRead |
等待对关系数据文件的读取。 |
DataFileSync |
等待对关系数据文件的更改达到持久存储。 |
DataFileTruncate |
等待关系数据文件被截断。 |
DataFileWrite |
等待对关系数据文件的写入。 |
LockFileAddToDataDirRead |
在向数据目录锁文件中添加一行时等待读取。 |
LockFileAddToDataDirSync |
等待数据到达持久存储,同时向数据目录锁文件添加一行。 |
LockFileAddToDataDirWrite |
在向数据目录锁文件中添加一行时等待写操作。 |
LockFileCreateRead |
创建数据目录锁文件时等待读取。 |
LockFileCreateSync |
在创建数据目录锁文件时等待数据到达持久存储。 |
LockFileCreateWrite |
在创建数据目录锁文件时等待写操作。 |
LockFileReCheckDataDirRead |
在重新检查数据目录锁文件期间等待读取。 |
LogicalRewriteCheckpointSync |
等待逻辑重写映射到在检查点到达持久存储。 |
LogicalRewriteMappingSync |
在逻辑重写期间等待映射数据到达持久存储 |
LogicalRewriteMappingWrite |
在逻辑重写期间等待映射数据的写入。 |
LogicalRewriteSync |
等待逻辑重写映射到达持久存储。 |
LogicalRewriteTruncate |
等待在逻辑重写期间截断映射数据。 |
LogicalRewriteWrite |
等待逻辑重写映射的写入。 |
RelationMapRead |
等待关系映射文件的读取。 |
RelationMapSync |
等待关系映射文件到达持久存储。 |
RelationMapWrite |
等待对关系映射文件的写入。 |
ReorderBufferRead |
在重新排序缓冲区管理期间等待读取。 |
ReorderBufferWrite |
在重新排序缓冲区管理期间等待写操作。 |
ReorderLogicalMappingRead |
在重新排序缓冲区管理期间等待读取逻辑映射。 |
ReplicationSlotRead |
等待从复制槽位控制文件读取。 |
ReplicationSlotRestoreSync |
等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 |
ReplicationSlotSync |
等待复制槽控制文件到达持久存储。 |
ReplicationSlotWrite |
等待对复制槽控制文件的写入。 |
SLRUFlushSync |
在检查点或数据库关闭期间等待SLRU数据到达持久存储。 |
SLRURead |
等待读取SLRU页面。 |
SLRUSync |
在写页面后等待SLRU数据到达持久存储。 |
SLRUWrite |
等待SLRU页面的写入。 |
SnapbuildRead |
等待读取序列化的历史目录快照。 |
SnapbuildSync |
等待序列化历史目录快照到达持久存储。 |
SnapbuildWrite |
等待串行历史目录快照的写入。 |
TimelineHistoryFileSync |
等待通过流复制接收的时间线历史文件到达持久存储。 |
TimelineHistoryFileWrite |
等待通过流复制接收的时间线历史文件的写入。 |
TimelineHistoryRead |
等待读取时间线历史文件。 |
TimelineHistorySync |
等待新创建的时间线历史文件到达持久存储。 |
TimelineHistoryWrite |
等待写入新创建的时间线历史文件。 |
WALBootstrapSync |
在引导过程中等待WAL达到持久存储。 |
WALBootstrapWrite |
在引导过程中等待WAL页面的写入。 |
WALCopyRead |
通过复制一个已有WAL段来创建一个新的WAL段时等待读取。 |
WALCopySync |
等待通过复制一个已有WAL段到持久存储来创建一个新的WAL段。 |
WALCopyWrite |
通过复制一个已有WAL段来创建一个新的WAL段时等待写入。 |
WALInitSync |
等待一个新初始化的WAL文件到持久存储。 |
WALInitWrite |
在初始化一个新的WAL文件时等待写入。 |
WALRead |
等待WAL文件的读取。 |
WALSenderTimelineHistoryRead |
在walsender时间线命令期间等待从时间线历史文件读取。 |
WALSync |
等待WAL文件到达持久存储。 |
WALSyncMethodAssign |
等待数据到达持久存储,同时分配一个新的WAL同步方法。 |
WALWrite |
等待写入WAL文件。 |
表 8. IPC
类型的等待事件
IPC 等待事件 |
描述 |
---|---|
BackupWaitWalArchive |
等待备份所需的WAL文件成功存档。 |
BgWorkerShutdown |
等待后台工作者关闭。 |
BgWorkerStartup |
等待后台工作者启动。 |
BtreePage |
正等待继续并行B-树扫描所需的页号变得可用。 |
CheckpointDone |
等待检查点完成。 |
CheckpointStart |
等待检查点开始。 |
ExecuteGather |
在执行Gather 计划节点时,等待子进程的活动。 |
LogicalSyncData |
等待逻辑复制远程服务器发送用于初始表同步的数据。 |
LogicalSyncStateChange |
等待逻辑复制远程服务器更改状态。 |
MessageQueueInternal |
等待另一个进程附加到共享消息队列。 |
MessageQueuePutMessage |
等待将协议消息写入共享消息队列。 |
MessageQueueReceive |
等待从共享消息队列接收字节。 |
MessageQueueSend |
等待将字节发送到共享消息队列。 |
ParallelBitmapScan |
等待并行位图扫描被初始化。 |
ParallelCreateIndexScan |
等待并行CREATE INDEX 工作者完成堆扫描。 |
ParallelFinish |
等待并行工作人员完成计算。 |
ProcArrayGroupUpdate |
等待组领导在并行操作结束时清除事务ID。 |
ProcSignalBarrier |
等待屏障事件被所有后端处理。 |
Promote |
等待备用系统提升。 |
RecoveryPause |
等待恢复继续进行。 |
ReplicationOriginDrop |
等待复制源变为非活动状态,以便可以删除它。 |
ReplicationSlotDrop |
等待复制槽变为非活动状态,以便可以删除它。 |
SafeSnapshot |
等待获取READ ONLY DEFERRABLE 事务的有效快照。 |
SyncRep |
在同步复制期间等待远程服务器的确认。 |
WalReceiverExit |
等待 WAL 接收器退出。 |
WalReceiverWaitStart |
等待启动过程发送用于流式复制的初始数据。 |
XactGroupUpdate |
等待分组组长在并行操作结束时更新事务状态。 |
表 9. Lock
类型的等待事件
Lock 等待事件 |
描述 |
---|---|
advisory |
等待获得一个建议用户锁。 |
extend |
等待扩展一个关系。 |
object |
等待获取非关系数据库对象上的锁。 |
page |
等待获取一个关系页面上的锁。 |
relation |
等待获得一个关系的锁。 |
transactionid |
等待事务完成。 |
tuple |
等待获取元组上的锁。 |
userlock |
等待获取用户锁。 |
virtualxid |
等待获取虚拟事务ID锁。 |
表 10. LWLock
类型的等待事件
LWLock 等待事件 |
描述 |
---|---|
AddinShmemInitLock |
等待管理共享内存中的扩展空间分配。 |
AutoFileLock |
等待更新postgresql.auto.conf 文件。 |
AutoanalyzeLock |
等待读取或更新自动分析工作者的当前状态。 |
AutoanalyzeScheduleLock |
等待确保选择为自动分析的表仍然需要清理。 |
BackgroundWorkerLock |
等待读取或更新后台工作者状态。 |
buffer_content |
等待访问内存中的数据页。 |
buffer_io |
等待数据页上的I/O。 |
buffer_mapping |
等待将数据块与缓冲池中的缓冲区关联。 |
CheckpointLock |
等待开始一个检查点。 |
CheckpointerCommLock |
等待管理fsync请求。 |
ControlFileLock |
等待读取或更新pg_control 文件或创建一个新的WAL文件。 |
DatabaseStateLock |
等待更新数据库的状态。 |
DynamicSharedMemoryControlLock |
等待读取或更新动态共享内存分配信息。 |
lock_manager |
等待读取或更新重量级锁的信息。 |
LogicalRepWorkerLock |
等待读取或更新逻辑复制工作器的状态。 |
OidGenLock |
等待分配一个新的OID。 |
OldSerXidLock |
正等待读取或者记录冲突的可序列化事务。 |
PLogSpaceLock |
等待更新网络表空间的状态。 |
PLogWriteLock |
等待PLOG缓冲区写入磁盘。 |
predicate_lock_manager |
等待访问可序列化事务使用的谓词锁信息。 |
ProcArrayLock |
等待访问每个进程共享的数据结构。主要发生在连接建立和释放,或者报告会话的事务ID的时候。 |
RelCacheInitLock |
等待读取或更新pg_internal.init 关系缓存初始化文件。 |
ReplicationOriginLock |
等待创建、删除或使用复制源。 |
ReplicationSlotAllocationLock |
等待分配或释放复制槽。 |
ReplicationSlotControlLock |
等待读取或更新复制槽状态。 |
replication_origin |
正等待读取或者更新复制进度。 |
replication_slot_io |
在复制槽位上等待I/O。 |
SerializableFinishedListLock |
等待访问已完成的可序列化事务列表。 |
SerializablePredicateListLock |
等待访问可序列化事务持有的谓词锁列表。 |
SerializableXactHashLock |
等待读取或更新关于可序列化事务的信息。 |
ShmemIndexLock |
等待在共享内存中找到或分配空间。 |
SInvalReadLock |
等待从共享目录失效队列中检索消息。 |
SInvalWriteLock |
等待向共享编目失效队列添加消息。 |
SyncRepLock |
等待读取或更新有关同步复制状态的信息。 |
SyncScanLock |
等待选择同步表扫描的起始位置。 |
TablespaceMapLock |
等待读取或更新表空间的存储位置配置文件。 |
TwoPhaseStateLock |
等待读取或更新已准备事务的状态。 |
WALBufMappingLock |
等待在WAL缓冲区中替换一个页面。 |
wal_insert |
等待将WAL数据插入内存缓冲区。 |
WALWriteLock |
等待WAL缓冲区写入磁盘。 |
扩展可以将LWLock
类型添加到 表 9 所示的列表中。 在某些情况下,扩展名分配的名称不能在所有服务器进程中使用;因此LWLock
等待事件可能只被报告为“extension
”,而不是扩展名分配的名称。
表 11. SpinLock
类型的等待事件
SpinLock 等待事件 |
描述 |
---|---|
BufferHeader |
等待访问缓冲区中的数据页状态信息。 |
BufferStrategyControl |
等待管理缓冲区中的页面分配和淘汰的状态信息,维护空闲页面列表以及基于时钟淘汰算法的状态信息。 |
CheckpointerShmem |
等待访问实例的检查点状态信息。 |
ConditionVariable |
等待访问条件变量的等待队列。 |
FastPathStrongLock |
等待读取或更新进程的快速路径锁信息。 |
HashFreelist |
等待访问分区共享哈希表中的空闲列表。 |
InvalMessageNumber |
等待获取失效消息计数器。 |
LogicalTableSync |
逻辑复制中等待访问表数据初始同步的状态信息。 |
LWLockWaitList |
等待访问LWLock 的等待队列。 |
ParallelBitmapHeapScan |
等待访问并行位图扫描的状态信息。 |
ParallelBtreeScan |
等待访问并行B树索引扫描的状态信息。 |
ParallelFixedState |
等待访问并行查询基础的状态信息。主要用来更新并行工作进程的最新日志序列号。 |
ParallelHeapScan |
等待访问并行堆表扫描的状态信息。 |
PGProcFreeList |
等待分配或释放数据库进程的数据结构。通常发生在数据库连接的建立和释放时期。 |
PLogControl |
等待访问PLOG缓冲区的控制信息。 |
ReplicationSlot |
等待管理复制槽的状态信息。 |
ShmemAlloc |
等待分配新的共享内存。 |
ShmemMessageQueue |
等待访问共享内存区中的消息队列。 |
ShmemSegmentTable |
等待访问共享内存区中的内存段目录。 |
StorageServerControl |
等待访问存储服务器的控制信息。 |
UnloggedLSN |
等待获取类似LSN的系统级日志序列号。 |
VFDHeader |
等待读取或更新虚拟文件描述符的状态信息。 |
VSDHeader |
等待读取或更新虚拟存储描述符的状态信息。 |
WALReceiverData |
等待访问WAL接收器进程的控制信息。 |
WALSenderControl |
等待访问WAL发送器进程的控制信息。 |
XLogControl |
等待访问WAL缓冲区的控制信息。 |
表 12. Timeout
类型的等待事件
Timeout 等待事件 |
描述 |
---|---|
BaseBackupThrottle |
当有限流活动时在基础备份期间等待。 |
PgSleep |
由于调用pg_sleep 或同类函数而等待。 |
RecoveryApplyDelay |
由于延迟设置,在恢复期间等待应用WAL。 |