背景
相信我们不止一次遇到过一个等待事件:LWLock lock_manager。下面我们聊聊这个等待事件的含义,产生原因,以及解决方法。
等待事件含义
当数据库维护共享锁的内存区域以在无法实现fastpath lock 时分配、检查和解除分配锁时,会发生此事件。
发出SQL语句时,数据库会记录有关锁,以在并发操作期间保护数据库的内存结构、数据和完整性。数据库可以使用快速路径锁定或非快速路径锁定方式来实现这一目标。非快速路径锁比快速路径锁更昂贵,产生更多的开销。
快速路径锁定:为了减少频繁获取和释放锁,减少很少发生冲突的锁的开销,后端进程可以使用快速路径锁定方式。数据库将此机制用于满足以下条件的锁:
“快速路径”锁定机制是后端进程可以用来记录具有特定特征的有限数量的锁,必须符合条件:VXID 锁 ;它们必须是“弱”锁,不应该是(AccessShareLock、RowShareLoc或RowExclusiveLock);
lock manager 问题示例:
在本例中,一个表存储多年的数据,按天进行分区。每个分区有两个索引。当查询许多天的数据,这需要数据库读取许多分区。数据库为每个分区创建一个锁。如果分区索引是优化器访问路径的一部分,数据库也会为它们创建一个锁。
应用程序可能有数百个会话。如果并发会话在没有分区修剪的情况下查询父表,数据库可能会创建数百甚至数千个非快速路径锁。通常,当此并发性高于CPU的数量时,会出现LWLock:lock_manager等待事件。
注意:LWLock:lock_manager等待事件与数据库中的分区或索引数无关。相反,它与数据库必须控制的非快速路径锁的数量有关。
等待事件LWLock:lock_manager增加的可能原因
当LWLock:lock_manager等待事件发生的频繁时,表明存在性能问题,导致出现峰值的最可能原因如下:
- 并发活动会话正在运行但没有使用快速路径锁的查询。
- 大量并发活动会话正在访问很多分区的表。每个分区都有多个索引。
- 数据库遇到连接风暴。默认情况下,某些应用程序或连接池软件会在数据库速度较慢时仍然创建更多连接。这种做法使问题更严重。调整连接池软件,使连接风暴不会发生。
- 大量会话查询父表而没使用分区修剪。
- 数据定义语言(DDL)、数据操作语言(DML)命令频繁访问或修改的热表或元组。
等待事件LWLock:lock_manager解决方法:
-
使用分区修剪
SET enable_partition_pruning=on;
当查询的WHERE子句包含用于分区的列时,查询可以利用分区修剪。 -
删除不必要的索引
删除数据库未使用或很少使用的索引。 -
调整查询以实现快速路径锁定
要查询是否使用快速路径锁定,请查询pg_locks表中的fastpath列。如果查询没有使用快速路径锁定,请将每个查询的表数减少到16个以下。
fastpath列的含义是,如果锁通过快速路径获得则为真,通过主锁表获得则为假. -
调整其他等待事件
如果LWLock:lock_manager在top等待列表中排名第一或第二,请检查等待事件中是否也同时出现以下等待事件:
Lock:Relation
Lock:transactionid
Lock:tuple
如果前面的事件在等待事件中占比很高,请首先想办法降低这些等待事件。这些事件可能导致更多的LWLock:lock_manager。 -
减少硬件瓶颈
CPU不足或网络带宽的最大使用率触发瓶颈。在这些情况下,考虑以下措施:
优化消耗大量CPU和内存的sql。
更改应用程序逻辑。
冷热数据物理分离。 -
使用连接池
如果数据库时常有大量session,请考虑使用或优化连接池。避免连接风暴。 -
升级数据库版本
建议升级至KingbaseES最新发布版本