

# LWLock:lock\$1manager
<a name="apg-waits.lw-lock-manager"></a>

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

**Topics**
+ [支持的引擎版本](#apg-waits.lw-lock-manager.context.supported)
+ [上下文](#apg-waits.lw-lock-manager.context)
+ [等待次数增加的可能原因](#apg-waits.lw-lock-manager.causes)
+ [操作](#apg-waits.lw-lock-manager.actions)

## 支持的引擎版本
<a name="apg-waits.lw-lock-manager.context.supported"></a>

此等待时间信息与 Aurora PostgreSQL 版本 9.6 及更高版本相关。

## 上下文
<a name="apg-waits.lw-lock-manager.context"></a>

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

### 快速路径锁定
<a name="apg-waits.lw-lock-manager.context.fast-path"></a>

为了减少频繁获取和释放但很少发生冲突的锁的开销，后端进程可以使用快速路径锁定。数据库对满足以下条件的锁定使用此机制：
+ 他们使用 DEFAULT 锁定方法。
+ 它们代表数据库关系的锁，而不是共享关系。
+ 它们是不太可能发生冲突的弱锁。
+ 引擎可以快速确认不可能存在发生冲突的锁。

在以下任一条件为真时，引擎无法使用快速路径锁定：
+ 锁不满足上述标准。
+ 没有更多的插槽可用于后端进程。

有关快速路径锁定的更多信息，请参阅 PostgreSQL 锁管理器 README 中的[快速路径](https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/README#L70-L76)和 PostgreSQL 文档中的 [pg-locks](https://www.postgresql.org/docs/15/view-pg-locks.html)。

### 锁管理器的扩缩问题示例
<a name="apg-waits.lw-lock-manager.context.lock-manager"></a>

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

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

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

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

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

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

## 等待次数增加的可能原因
<a name="apg-waits.lw-lock-manager.causes"></a>

当 `LWLock:lock_manager` 等待事件发生率超出正常（可能表明性能问题）时，突增的最可能原因如下：
+ 并发活动会话正在运行不使用快速路径锁的查询。这些会话还超出了最大 vCPU。
+ 大量并发活动会话正在访问严重分区的表。每个分区都有多个索引。
+ 数据库正在经历连接风暴。预设情况下，当数据库缓慢时，某些应用程序和连接池软件会创建更多连接。这种做法使问题变得更糟。优化连接池软件，以免发生连接风暴。
+ 大量会话在不修剪分区的情况下查询父级表。
+ 数据定义语言 (DDL)、数据操作语言 (DML) 或维护命令专门锁定经常访问或修改的繁忙关系或元组。

## 操作
<a name="apg-waits.lw-lock-manager.actions"></a>

根据等待事件的原因，我们建议采取不同的操作。

**Topics**
+ [使用分区修剪](#apg-waits.lw-lock-manager.actions.pruning)
+ [删除不必要的索引](#apg-waits.lw-lock-manager.actions.indexes)
+ [优化查询以实现快速路径锁定](#apg-waits.lw-lock-manager.actions.tuning)
+ [优化其他等待事件](#apg-waits.lw-lock-manager.actions.other-waits)
+ [减少硬件瓶颈](#apg-waits.lw-lock-manager.actions.hw-bottlenecks)
+ [使用连接池程序。](#apg-waits.lw-lock-manager.actions.pooler)
+ [升级您的 Aurora PostgreSQL 版本](#apg-waits.lw-lock-manager.actions.pg-version)

### 使用分区修剪
<a name="apg-waits.lw-lock-manager.actions.pruning"></a>

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

```
SET enable_partition_pruning = on;
```

查询可以在其 `WHERE` 子句包含用于分区的列时利用分区修建。有关更多信息，请参阅 PostgreSQL 文档中的[分区修建](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITION-PRUNING)。

### 删除不必要的索引
<a name="apg-waits.lw-lock-manager.actions.indexes"></a>

数据库可能包含未使用或很少使用的索引。如果是，请考虑删除它们。请执行以下任一操作：
+ 通过阅读 PostgreSQL wiki 中的[未使用索引](https://wiki.postgresql.org/wiki/Index_Maintenance#Unused_Indexes)了解如何查找不必要的索引。
+ 运行 PG 收集器。此 SQL 脚本会收集数据库信息并将其显示在整合的 HTML 报告中。检查“未使用的索引”部分。有关更多信息，请参阅 Amazon Labs GitHub 存储库中的 [pg-collector](https://github.com/awslabs/pg-collector)。

### 优化查询以实现快速路径锁定
<a name="apg-waits.lw-lock-manager.actions.tuning"></a>

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

### 优化其他等待事件
<a name="apg-waits.lw-lock-manager.actions.other-waits"></a>

如果 `LWLock:lock_manager` 排在主要等待列表中的第一个或第二个，请检查列表中是否也显示了以下等待事件：
+ `Lock:Relation`
+ `Lock:transactionid`
+ `Lock:tuple`

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

### 减少硬件瓶颈
<a name="apg-waits.lw-lock-manager.actions.hw-bottlenecks"></a>

您可能存在硬件瓶颈，例如 CPU 匮乏或 Amazon EBS 带宽的最大使用率。在这样的情况下，需考虑减少硬件瓶颈。请考虑以下操作：
+ 纵向扩展您的实例类。
+ 优化占用大量 CPU 和内存的查询。
+ 更改应用程序逻辑。
+ 将您的数据存档。

有关 CPU、内存和 EBS 网络带宽的更多信息，请参阅 [Amazon RDS 实例类型](https://www.amazonaws.cn/rds/instance-types/)。

### 使用连接池程序。
<a name="apg-waits.lw-lock-manager.actions.pooler"></a>

如果您的活动连接总数超过最大 vCPU，则需要 CPU 的操作系统进程超过实例类型所能支持的数量。在这种情况下，需考虑使用或优化连接池。有关您的实例类型 vCPU 数量的更多信息，请参阅 [Amazon RDS 实例类型](https://www.amazonaws.cn/rds/instance-types/)。

有关为连接池的更多信息，请参阅以下资源：
+ [适用于 Aurora 的Amazon RDS 代理](rds-proxy.md)
+ [pgbouncer](http://www.pgbouncer.org/usage.html)
+ *PostgreSQL 文档*中的[连接池和数据源](https://www.postgresql.org/docs/7.4/jdbc-datasource.html)

### 升级您的 Aurora PostgreSQL 版本
<a name="apg-waits.lw-lock-manager.actions.pg-version"></a>

如果您当前的 Aurora PostgreSQL 版本低于 12，请升级到版本 12 或更高版本。PostgreSQL 版本 12 和 13 具有改进的分区机制。有关版本 12 的更多信息，请参阅 [PostgreSQL 12.0 发布说明]( https://www.postgresql.org/docs/release/12.0/)。有关升级 Aurora PostgreSQL 的更多信息，请参阅 [Amazon Aurora PostgreSQL 的数据库引擎更新](AuroraPostgreSQL.Updates.md)。