WAIT EVENT · LWLOCK轻量级锁
LWLockWALInsert
等待将WAL数据插入内存缓冲区。
Waiting to insert WAL data into a memory buffer
轻量级锁 引入 9.6(机制起点) 现存至 20 devel 2 次变动 动态触发图谱档案
版本轨迹
相对 PostgreSQL 17 无变化。
各版本描述
相邻版本里类型、名称与英文描述都相同的合并成一段,旧的在前。中文取自图谱或本站手册译文,没有译文的只给英文原文。
-
9.6
LWLockTranchewal_insert曾用名等待将 WAL 插入内存缓冲区。
Waiting to insert WAL into a memory buffer.
-
1012
LWLockwal_insert曾用名等待将 WAL 插入内存缓冲区。
Waiting to insert WAL into a memory buffer.
-
1320
LWLockWALInsert等待将WAL数据插入内存缓冲区。
Waiting to insert WAL data into a memory buffer.
触发机制
后端在共享 WAL 缓冲区中预留空间并复制 WAL 记录时,必须持有一个 WAL insertion lock。并发 WAL 生产者很多、插入临界区变长时,会在此排队。
A backend must hold one of the WAL insertion locks while reserving and copying a WAL record into shared WAL buffers. High concurrent WAL producers can queue when insertion critical sections lengthen.
通常正常
并发写入与提交突发期间的瞬时等待很正常。
Transient waits are normal during concurrent writes and commit bursts.
值得警惕
前台会话反复堆积说明 WAL 插入已成为串行点,常伴随极高写并发、全页镜像或缓冲区换页过慢。
A recurring foreground pile-up indicates WAL insertion has become a serialization point, often with very high write concurrency, full-page images, or slow buffer turnover.
典型事故模式
扇出任务在检查点后立即发起大量单行提交,全页镜像与写并发共同让 WAL 插入成为瓶颈。
A fan-out job issues many single-row commits immediately after a checkpoint; full-page images and writer concurrency turn WAL insertion into the bottleneck.
诊断 SQL
直接在 psql 里跑;标注的是语句里用到的视图与列所要求的最低版本。
正在等待 LWLock/WALInsert 的会话Sessions waiting on LWLock/WALInsert
PG ≥ 13SELECT pid, backend_type, usename, datname, application_name,
state, now() - query_start AS query_age,
now() - xact_start AS xact_age,
wait_event_type, wait_event,
pg_blocking_pids(pid) AS blocking_pids,
left(query, 160) AS query
FROM pg_stat_activity
WHERE wait_event_type = 'LWLock'
AND wait_event = 'WALInsert'
ORDER BY query_age DESC NULLS LAST;
当前 LWLock 等待分布Current LWLock cohort
PG ≥ 13SELECT wait_event, count(*) AS waiting_sessions,
count(*) FILTER (WHERE state = 'active') AS active_waiters,
max(now() - query_start) AS oldest_query
FROM pg_stat_activity
WHERE wait_event_type = 'LWLock'
GROUP BY wait_event
ORDER BY waiting_sessions DESC, wait_event;
这些会话的锁与关系上下文Lock and relation context for these sessions
PG ≥ 13SELECT a.pid, l.locktype, l.mode, l.granted, l.fastpath,
d.datname, n.nspname, c.relname,
l.page, l.tuple, l.virtualxid, l.transactionid,
l.classid, l.objid, l.objsubid
FROM pg_stat_activity AS a
LEFT JOIN pg_locks AS l ON l.pid = a.pid
LEFT JOIN pg_database AS d ON d.oid = l.database
LEFT JOIN pg_class AS c
ON c.oid = l.relation
AND l.database = (
SELECT oid FROM pg_database WHERE datname = current_database()
)
LEFT JOIN pg_namespace AS n ON n.oid = c.relnamespace
WHERE a.wait_event_type = 'LWLock'
AND a.wait_event = 'WALInsert'
ORDER BY a.pid, l.granted, l.locktype, l.mode;
处置步骤
- 按 WAL 生成量与调用频率排序语句。
- 检查检查点/全页镜像时机与并发写会话数量。
- 批量合并微小写入、减少无效索引抖动,并处理 WAL 写延迟。
英文原文
- Rank statements by WAL generation and call rate.
- Check checkpoint/full-page-image timing and concurrent writer count.
- Batch tiny writes, reduce needless index churn, and address WAL write latency.
相关参数与指标
wal_buffersfull_page_writescheckpoint_timeout
waiting_sessionswait_event_sharewal_byteswal_fpistatement_wal_bytes
源码证据
图谱在各版本源码树里核对到的位置,新的在前。「触发点」是真正上报等待事件的调用处,「目录定义」只说明这个名字在枚举里存在。
PostgreSQL 18REL_18_6
-
src/backend/access/transam/xlog.c:1399WALInsert资源定义动态触发immed = LWLockAcquire(&WALInsertLocks[MyLockNo].l.lock, LW_EXCLUSIVE); -
src/backend/storage/lmgr/lwlock.c:739pgstat_report_wait_start通用上报动态触发pgstat_report_wait_start(PG_WAIT_LWLOCK | lock->tranche); -
src/backend/utils/activity/wait_event_names.txt:372WALInsert目录定义动态触发WALInsert "Waiting to insert WAL data into a memory buffer."
演化历史
相邻两个大版本之间的差异,新的在前。版本号链到该版的变动清单。
-
PostgreSQL 13 ← 12 更名
更名
wal_insertWALInsert描述措辞更新等待将WAL数据插入内存缓冲区。
描述前后对照
Waiting to insert WAL into a memory buffer. Waiting to insert WAL data into a memory buffer. -
PostgreSQL 10 ← 9.6 类型变动
类型
LWLockTrancheLWLock等待将 WAL 插入内存缓冲区。
-
PostgreSQL 9.6 新增此事件
9.6 引入等待事件机制,此为本事件的首个版本
等待将 WAL 插入内存缓冲区。
同类事件
| 事件 | 引入 | 版本变动 | 最近变动 |
|---|---|---|---|
AddinShmemInit档案
|
9.6起点 | 132 次 | |
等待管理扩展在共享内存中的空间分配。曾用名 AddinShmemInitLock |
现存 | ||
AioUringCompletion档案
|
18 | — | |
| 等待另一个进程通过 io_uring 完成 I/O。 | 现存 | ||
AioWorkerControl
|
19 | — | |
| 等待更新 AIO 工作进程信息。 | 现存 | ||
AioWorkerSubmissionQueue档案
|
18 | — | |
| 等待访问 AIO worker 提交队列。 | 现存 | ||
AutoFile档案
|
9.6起点 | 132 次 | |
等待更新 postgresql.auto.conf 文件。曾用名 AutoFileLock |
现存 | ||
Autovacuum档案
|
9.6起点 | 132 次 | |
等待读取或更新 autovacuum worker 的当前状态。曾用名 AutovacuumLock |
现存 | ||
AutovacuumSchedule档案
|
9.6起点 | 132 次 | |
等待确认被选中进行 autovacuum 的表仍需要 vacuum。曾用名 AutovacuumScheduleLock |
现存 | ||
BackendRandomLock
|
10 | — | |
| 等待生成随机数。 | 于 12 移除 | ||
BackgroundWorker档案
|
9.6起点 | 132 次 | |
等待读取或更新后台 worker 的状态。曾用名 BackgroundWorkerLock |
现存 | ||
BtreeVacuum档案
|
9.6起点 | 132 次 | |
等待读取或更新 B-tree 索引中与 vacuum 相关的信息。曾用名 BtreeVacuumLock |
现存 | ||
BufferContent档案
|
9.6起点 | 132 次 | |
等待访问内存中的数据页。曾用名 buffer_content |
于 19 移除 | ||
BufferMapping档案
|
9.6起点 | 132 次 | |
等待将数据块关联到 buffer pool 中的 buffer。曾用名 buffer_mapping |
现存 | ||
Checkpoint档案
|
9.6起点 | 132 次 | |
等待开始执行检查点。曾用名 CheckpointLock |
于 14 移除 | ||
CheckpointerComm档案
|
9.6起点 | 132 次 | |
等待管理 fsync 请求。曾用名 CheckpointerCommLock |
现存 | ||
CommitTs档案
|
9.6起点 | 132 次 | |
等待读取或更新事务提交时间戳的最近设定值。曾用名 CommitTsLock |
现存 | ||
CommitTsBuffer档案
|
9.6起点 | 132 次 | |
等待事务提交时间戳 SLRU buffer 上的 I/O。曾用名 commit_timestamp |
现存 | ||
CommitTsSLRU档案
|
9.6起点 | 132 次 | |
等待访问事务提交时间戳 SLRU 缓存。曾用名 CommitTsControlLock |
现存 | ||
ControlFile档案
|
9.6起点 | 132 次 | |
等待读取或更新 pg_control 文件,或创建新的 WAL 文件。曾用名 ControlFileLock |
现存 | ||
DataChecksumsWorker
|
19 | — | |
| 等待数据校验和工作进程。 | 现存 | ||
DSMRegistry档案
|
17 | — | |
| 等待读取或更新动态共享内存注册表。 | 现存 | ||
DSMRegistryDSA档案
|
17 | — | |
| 等待访问动态共享内存注册表的动态共享内存分配器。 | 现存 | ||
DSMRegistryHash档案
|
17 | — | |
| 等待访问动态共享内存注册表的共享哈希表。 | 现存 | ||
DynamicSharedMemoryControl档案
|
9.6起点 | 132 次 | |
等待读取或更新动态共享内存分配信息。曾用名 DynamicSharedMemoryControlLock |
现存 | ||
InjectionPoint档案
|
17 | — | |
| 等待读取或更新与注入点相关的信息。 | 现存 | ||
LockFastPath档案
|
9.6起点 | 132 次 | |
等待读取或更新进程的快速路径锁信息。曾用名 proc |
现存 | ||
LockManager档案
|
9.6起点 | 194 次 | |
等待读取或更新“重量级”锁的信息。曾用名 lock_manager |
现存 | ||
LogicalDecodingControl
|
19 | — | |
| 等待读取或更新逻辑解码状态信息。 | 现存 | ||
LogicalRepLauncherDSA档案
|
16 | — | |
| 等待访问逻辑复制 launcher 的动态共享内存分配器。 | 现存 | ||
LogicalRepLauncherHash档案
|
16 | — | |
| 等待访问逻辑复制 launcher 的共享哈希表。 | 现存 | ||
LogicalRepWorker档案
|
10 | 131 次 | |
等待读取或更新逻辑复制 worker 的状态。曾用名 LogicalRepWorkerLock |
现存 | ||
MultiXactGen档案
|
9.6起点 | 132 次 | |
等待读取或更新共享 multixact 状态。曾用名 MultiXactGenLock |
现存 | ||
MultiXactMemberBuffer档案
|
9.6起点 | 132 次 | |
等待 multixact member SLRU buffer 上的 I/O。曾用名 multixact_member |
现存 | ||
MultiXactMemberSLRU档案
|
9.6起点 | 132 次 | |
等待访问 multixact member SLRU 缓存。曾用名 MultiXactMemberControlLock |
现存 | ||
MultiXactOffsetBuffer档案
|
9.6起点 | 132 次 | |
等待 multixact offset SLRU buffer 上的 I/O。曾用名 multixact_offset |
现存 | ||
MultiXactOffsetSLRU档案
|
9.6起点 | 132 次 | |
等待访问 multixact offset SLRU 缓存。曾用名 MultiXactOffsetControlLock |
现存 | ||
MultiXactTruncation档案
|
9.6起点 | 132 次 | |
等待读取或截断 multixact 信息。曾用名 MultiXactTruncationLock |
现存 | ||
NotifyBuffer档案
|
9.6起点 | 132 次 | |
等待 NOTIFY 消息 SLRU buffer 上的 I/O。曾用名 async |
现存 | ||
NotifyChannelHash
|
19 | — | |
| 等待访问 NOTIFY 通道哈希表。 | 现存 | ||
NotifyQueue档案
|
9.6起点 | 132 次 | |
等待读取或更新 NOTIFY 消息。曾用名 AsyncQueueLock |
现存 | ||
NotifyQueueTail档案
|
9.6起点 | 132 次 | |
等待更新 NOTIFY 消息的存储上限。曾用名 NotifyQueueTailLock |
现存 | ||
NotifySLRU档案
|
9.6起点 | 132 次 | |
等待访问 NOTIFY 消息 SLRU 缓存。曾用名 AsyncCtlLock |
现存 | ||
OidGen档案
|
9.6起点 | 132 次 | |
等待分配新的 OID。曾用名 OidGenLock |
现存 | ||
OldSnapshotTimeMap档案
|
9.6起点 | 132 次 | |
等待读取或更新旧快照控制信息。曾用名 OldSnapshotTimeMapLock |
于 17 移除 | ||
ParallelAppend档案
|
11 | 131 次 | |
执行 Parallel Append 计划期间,等待选择下一个子计划。曾用名 parallel_append |
现存 | ||
ParallelBtreeScan档案
|
18 | — | |
| 执行 Parallel B-tree Scan 计划期间,等待同步 worker。 | 现存 | ||
ParallelHashJoin档案
|
11 | 131 次 | |
执行 Parallel Hash Join 计划期间,等待同步 worker。曾用名 parallel_hash_join |
现存 | ||
ParallelQueryDSA档案
|
10 | 131 次 | |
等待并行查询的动态共享内存分配。曾用名 parallel_query_dsa |
现存 | ||
ParallelVacuumDSA档案
|
17 | — | |
| 等待并行 vacuum 的动态共享内存分配。 | 现存 | ||
PerSessionDSA档案
|
13 | — | |
| 等待并行查询的动态共享内存分配。 | 现存 | ||
PerSessionRecordType档案
|
13 | — | |
| 等待访问并行查询的复合类型信息。 | 现存 | ||
PerSessionRecordTypmod档案
|
13 | — | |
| 等待访问并行查询中用于标识匿名 record 类型的类型修饰符信息。 | 现存 | ||
PerXactPredicateList档案
|
12 | 131 次 | |
并行查询期间,等待访问当前可串行化事务所持有的谓词锁列表。曾用名 serializable_xact |
现存 | ||
PgStatsData档案
|
15 | — | |
| 等待访问共享内存中的统计数据。 | 现存 | ||
PgStatsDSA档案
|
15 | — | |
| 等待访问统计信息的动态共享内存分配器。 | 现存 | ||
PgStatsHash档案
|
15 | — | |
| 等待访问统计信息的共享内存哈希表。 | 现存 | ||
PredicateLockManager档案
|
9.6起点 | 132 次 | |
等待访问可串行化事务使用的谓词锁信息。曾用名 predicate_lock_manager |
现存 | ||
ProcArray档案
|
9.6起点 | 132 次 | |
等待访问共享的进程级数据结构(通常用于获取快照或报告会话的事务 ID)。曾用名 ProcArrayLock |
现存 | ||
RelationMapping档案
|
9.6起点 | 132 次 | |
等待读取或更新 pg_filenode.map 文件(用于跟踪某些系统目录的 filenode 分配)。曾用名 RelationMappingLock |
现存 | ||
RelCacheInit档案
|
9.6起点 | 132 次 | |
等待读取或更新 pg_internal.init relation cache 初始化文件。曾用名 RelCacheInitLock |
现存 | ||
ReplicationOrigin档案
|
9.6起点 | 132 次 | |
等待创建、删除或使用复制源。曾用名 ReplicationOriginLock |
现存 | ||
ReplicationOriginState档案
|
9.6起点 | 132 次 | |
等待读取或更新一个复制源的进度。曾用名 replication_origin |
现存 | ||
ReplicationSlotAllocation档案
|
9.6起点 | 132 次 | |
等待分配或释放复制槽。曾用名 ReplicationSlotAllocationLock |
现存 | ||
ReplicationSlotControl档案
|
9.6起点 | 132 次 | |
等待读取或更新复制槽状态。曾用名 ReplicationSlotControlLock |
现存 | ||
ReplicationSlotIO档案
|
9.6起点 | 132 次 | |
等待复制槽上的 I/O。曾用名 replication_slot_io |
现存 | ||
SerialBuffer档案
|
9.6起点 | 133 次 | |
等待可串行化事务冲突 SLRU buffer 上的 I/O。曾用名 oldserxid |
现存 | ||
SerialControl档案
|
17 | — | |
| 等待读取或更新共享的 pg_serial 状态。 | 现存 | ||
SerializableFinishedList档案
|
9.6起点 | 132 次 | |
等待访问已结束的可串行化事务列表。曾用名 SerializableFinishedListLock |
现存 | ||
SerializablePredicateList档案
|
9.6起点 | 132 次 | |
等待访问可串行化事务所持有的谓词锁列表。曾用名 SerializablePredicateLockListLock |
现存 | ||
SerializableXactHash档案
|
9.6起点 | 132 次 | |
等待读取或更新可串行化事务的信息。曾用名 SerializableXactHashLock |
现存 | ||
SerialSLRU档案
|
9.6起点 | 132 次 | |
等待访问可串行化事务冲突 SLRU 缓存。曾用名 OldSerXidLock |
现存 | ||
SharedTidBitmap档案
|
10 | 131 次 | |
并行 bitmap index scan 期间,等待访问共享 TID bitmap。曾用名 tbm |
现存 | ||
SharedTupleStore档案
|
13 | — | |
| 并行查询期间,等待访问共享 tuple store。 | 现存 | ||
ShmemIndex档案
|
9.6起点 | 132 次 | |
等待在共享内存中查找或分配空间。曾用名 ShmemIndexLock |
现存 | ||
SInvalRead档案
|
9.6起点 | 132 次 | |
等待从共享系统目录失效队列中取出消息。曾用名 SInvalReadLock |
现存 | ||
SInvalWrite档案
|
9.6起点 | 132 次 | |
等待向共享系统目录失效队列中添加消息。曾用名 SInvalWriteLock |
现存 | ||
SubtransBuffer档案
|
9.6起点 | 132 次 | |
等待子事务 SLRU buffer 上的 I/O。曾用名 subtrans |
现存 | ||
SubtransSLRU档案
|
9.6起点 | 132 次 | |
等待访问子事务 SLRU 缓存。曾用名 SubtransControlLock |
现存 | ||
SyncRep档案
|
9.6起点 | 132 次 | |
等待读取或更新同步复制状态信息。曾用名 SyncRepLock |
现存 | ||
SyncScan档案
|
9.6起点 | 132 次 | |
等待选择同步表扫描的起始位置。曾用名 SyncScanLock |
现存 | ||
TablespaceCreate档案
|
9.6起点 | 132 次 | |
等待创建或删除表空间。曾用名 TablespaceCreateLock |
现存 | ||
TwoPhaseState档案
|
9.6起点 | 132 次 | |
等待读取或更新预备事务的状态。曾用名 TwoPhaseStateLock |
现存 | ||
WaitEventCustom档案
|
17 | — | |
| 等待读取或更新自定义等待事件信息。 | 现存 | ||
WaitLSN
|
19 | — | |
| 等待读取或更新共享的 LSN 等待状态。 | 现存 | ||
WALBufMapping档案
|
9.6起点 | 132 次 | |
等待替换 WAL buffer 中的页面。曾用名 WALBufMappingLock |
现存 | ||
WALInsert档案
|
9.6起点 | 132 次 | |
等待将 WAL 数据插入内存 buffer。曾用名 wal_insert |
现存 | ||
WALSummarizer档案
|
17 | — | |
| 等待读取或更新 WAL 汇总状态。 | 现存 | ||
WALWrite档案
|
9.6起点 | 132 次 | |
等待将 WAL buffer 写入磁盘。曾用名 WALWriteLock |
现存 | ||
WrapLimitsVacuum档案
|
9.6起点 | 132 次 | |
等待更新事务 ID 和 multixact 的消耗上限。曾用名 WrapLimitsVacuumLock |
现存 | ||
XactBuffer档案
|
9.6起点 | 132 次 | |
等待事务状态 SLRU buffer 上的 I/O。曾用名 clog |
现存 | ||
XactSLRU档案
|
9.6起点 | 132 次 | |
等待访问事务状态 SLRU 缓存。曾用名 CLogControlLock |
现存 | ||
XactTruncation档案
|
10 | 131 次 | |
等待执行 pg_xact_status,或更新当前进程可用的最旧事务 ID。曾用名 CLogTruncationLock |
现存 | ||
XidGen档案
|
9.6起点 | 132 次 | |
等待分配新的事务 ID。曾用名 XidGenLock |
现存 | ||