LWLock:lock_manager (LWLock:lockmanager) - Amazon Relational Database Service

LWLock:lock_manager (LWLock:lockmanager)

当 RDS for PostgreSQL 引擎维护共享锁的内存区域以便在无法使用快速路径锁时分配、检查和取消分配锁时,会发生此事件。

支持的引擎版本

此等待事件信息与 RDS for PostgreSQL 版本 9.6 及更高版本相关。对于早于版本 13 的 RDS for PostgreSQL 发行版,此等待事件的名称为 LWLock:lock_manager。对于 RDS for PostgreSQL 版本 13 及更高版本,此等待事件的名称为 LWLock:lockmanager

上下文

发布 SQL 语句时,RDS for PostgreSQL 会记录锁,以在并发操作期间保护数据库的结构、数据和完整性。引擎可以使用快速路径锁或不快的路径锁来实现这个目标。不快的路径锁定更昂贵,并且比快速路径锁定造成的开销更大。

快速路径锁定

为了减少频繁获取和释放但很少发生冲突的锁的开销,后端进程可以使用快速路径锁定。数据库对满足以下条件的锁定使用此机制:

  • 他们使用 DEFAULT 锁定方法。

  • 它们代表数据库关系的锁,而不是共享关系。

  • 它们是不太可能发生冲突的弱锁。

  • 引擎可以快速确认不可能存在发生冲突的锁。

在以下任一条件为真时,引擎无法使用快速路径锁定:

  • 锁不满足上述标准。

  • 没有更多的插槽可用于后端进程。

要优化查询以实现快速路径锁,可以使用以下查询。

SELECT count(*), pid, mode, fastpath FROM pg_locks WHERE fastpath IS NOT NULL GROUP BY 4,3,2 ORDER BY pid, mode; count | pid | mode | fastpath -------+------+-----------------+---------- 16 | 9185 | AccessShareLock | t 336 | 9185 | AccessShareLock | f 1 | 9185 | ExclusiveLock | t

以下查询仅显示数据库中的总数。

SELECT count(*), mode, fastpath FROM pg_locks WHERE fastpath IS NOT NULL GROUP BY 3,2 ORDER BY mode,1; count | mode | fastpath -------+-----------------+---------- 16 | AccessShareLock | t 337 | AccessShareLock | f 1 | ExclusiveLock | t (3 rows)

有关快速路径锁定的更多信息,请参阅 PostgreSQL 锁管理器 README 中的快速路径和 PostgreSQL 文档中的 pg-locks

锁管理器的扩缩问题示例

在此示例中,名为 purchases 的表存储五年的数据,按天进行分区。每个分区有两个索引。将发生以下一系列事件:

  1. 您查询了许多天的数据,这需要数据库读取许多分区。

  2. 数据库为每个分区创建一个锁条目。如果分区索引是优化程序访问路径的一部分,则数据库也会为它们创建一个锁条目。

  3. 当同一后端进程请求的锁条目数大于 16 时(这是 FP_LOCK_SLOTS_PER_BACKEND 的值),锁管理器会使用非快速路径锁定方法。

现代应用程序可能有数百个会话。如果并发会话在没有适当的分区修剪的情况下查询父级数据库,则数据库可能会创建数百甚至数千个非快速路径锁。通常,当此并发性高于 vCPU 的数量时,会出现 LWLock:lock_manager 等待事件。

注意

LWLock:lock_manager 等待事件与数据库架构中的分区或索引数量无关。相反,它与数据库必须控制的非快速路径锁的数量有关。

等待次数增加的可能原因

LWLock:lock_manager 等待事件发生率超出正常(可能表明性能问题)时,突增的最可能原因如下:

  • 并发活动会话正在运行不使用快速路径锁的查询。这些会话还超出了最大 vCPU。

  • 大量并发活动会话正在访问严重分区的表。每个分区都有多个索引。

  • 数据库正在经历连接风暴。预设情况下,当数据库缓慢时,某些应用程序和连接池软件会创建更多连接。这种做法使问题变得更糟。优化连接池软件,以免发生连接风暴。

  • 大量会话在不修剪分区的情况下查询父级表。

  • 数据定义语言 (DDL)、数据操作语言 (DML) 或维护命令专门锁定经常访问或修改的繁忙关系或元组。

操作

如果 CPU 等待事件发生,它不一定表示性能问题。仅当性能下降并且此等待事件主导了数据库负载时才响应此事件。

使用分区修剪

分区修剪是一种适用于声明性分区表的查询优化策略,它从表扫描中排除不需要的分区,从而提高性能。预设情况下,分区修剪处于开启状态。如果它已关闭,请按如下方式将其打开。

SET enable_partition_pruning = on;

查询可以在其 WHERE 子句包含用于分区的列时利用分区修建。有关更多信息,请参阅 PostgreSQL 文档中的分区修建

删除不必要的索引

数据库可能包含未使用或很少使用的索引。如果是,请考虑删除它们。请执行以下任一操作:

  • 通过阅读 PostgreSQL wiki 中的未使用索引了解如何查找不必要的索引。

  • 运行 PG 收集器。此 SQL 脚本会收集数据库信息并将其显示在整合的 HTML 报告中。检查“未使用的索引”部分。有关更多信息,请参阅 AWS Labs GitHub 存储库中的 pg-collector

优化查询以实现快速路径锁定

要了解您的查询是否使用快速路径锁定,请查询 pg_locks 表中的 fastpath 列。如果您的查询没有使用快速路径锁定,请尝试将每个查询的关系数减少到 16 个以下。

优化其他等待事件

如果 LWLock:lock_manager 排在主要等待列表中的第一个或第二个,请检查列表中是否也显示了以下等待事件:

  • Lock:Relation

  • Lock:transactionid

  • Lock:tuple

如果前面的事件显示在列表的前面,请考虑首先优化这些等待事件。这些事件可以是 LWLock:lock_manager 的驱动因素。

减少硬件瓶颈

您可能存在硬件瓶颈,例如 CPU 匮乏或 Amazon EBS 带宽的最大使用率。在这样的情况下,需考虑减少硬件瓶颈。请考虑以下操作:

  • 纵向扩展您的实例类。

  • 优化占用大量 CPU 和内存的查询。

  • 更改应用程序逻辑。

  • 将您的数据存档。

有关 CPU、内存和 EBS 网络带宽的更多信息,请参阅 Amazon RDS 实例类型

使用连接池程序。

如果您的活动连接总数超过最大 vCPU,则需要 CPU 的操作系统进程超过实例类型所能支持的数量。在这种情况下,需考虑使用或优化连接池。有关您的实例类型 vCPU 数量的更多信息,请参阅 Amazon RDS 实例类型

有关为连接池的更多信息,请参阅以下资源:

升级您的 RDS for PostgreSQL 版本

如果您当前的 RDS for PostgreSQL 版本低于 12,请升级到版本 12 或更高版本。PostgreSQL 版本 12 及更高版本具有改进的分区机制。有关版本 12 的更多信息,请参阅 PostgreSQL 12.0 发布说明。有关升级 RDS for PostgreSQL 的更多信息,请参阅升级 RDS for PostgreSQL 数据库引擎