

# LWLock:BufferIO (IPC:BufferIO)
<a name="apg-waits.lwlockbufferio"></a>

当 Aurora PostgreSQL 或 RDS for PostgreSQL 正在等待其他进程在同时尝试访问页面时完成输入/输出 (I/O) 操作时，会发生 `LWLock:BufferIO` 事件。它的目的是将同一个分页读入共享缓冲区中。

**Topics**
+ [相关引擎版本](#apg-waits.lwlockbufferio.context.supported)
+ [上下文](#apg-waits.lwlockbufferio.context)
+ [原因](#apg-waits.lwlockbufferio.causes)
+ [操作](#apg-waits.lwlockbufferio.actions)

## 相关引擎版本
<a name="apg-waits.lwlockbufferio.context.supported"></a>

此等待事件信息与所有的 Aurora PostgreSQL 版本相关。对于 Aurora PostgreSQL 12 及更早版本，此等待事件命名为 lwlock:buffer\_io，而在 Aurora PostgreSQL 13 版本中，则命名为 lwlock:bufferio。从 Aurora PostgreSQL 14 版本开始，BufferIO 等待事件从 `LWLock` 移到 `IPC` 等待事件类型（IPC:BufferIO）。

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

每个共享缓冲区都有一个与 `LWLock:BufferIO` 等待事件相关的输入/输出锁，每次必须在共享缓冲池外检索数据块（或分页）。

此锁定用于处理多个会话，而这些会话都需要访问同一个数据块。必须从共享缓冲池外部读取此数据库块，该缓冲池由 `shared_buffers` 参数定义。

一旦在共享缓冲池内读取分页，`LWLock:BufferIO` 锁即被释放。

**注意**  
`LWLock:BufferIO` 等待事件发生在 [IO:DataFileRead](apg-waits.iodatafileread.md) 等待事件之前。`IO:DataFileRead` 事件在从存储中读取数据时发生。

有关轻量级锁定的更多信息，请参阅[锁定概览](https://github.com/postgres/postgres/blob/65dc30ced64cd17f3800ff1b73ab1d358e92efd8/src/backend/storage/lmgr/README#L20)。

## 原因
<a name="apg-waits.lwlockbufferio.causes"></a>

`LWLock:BufferIO` 显示在主要等待中的常见原因包括以下各项：
+ 多个后端或连接试图访问同样在等待输入/输出操作的同一页面
+ 共享缓冲池大小之间的比率（由 `shared_buffers` 参数定义）以及当前工作负载所需的缓冲区数量
+ 共享缓冲池的大小与其他操作移出的分页数量没有很好地平衡
+ 需要引擎在共享缓冲池中读取更多页面的臃肿的大索引
+ 缺乏强制数据库引擎从表中读取更多页面的索引
+ 试图在同一页面上执行操作的数据库连接突增

## 操作
<a name="apg-waits.lwlockbufferio.actions"></a>

根据等待事件的原因，我们建议采取不同的操作：
+ 观察 Amazon CloudWatch 指标，了解 `BufferCacheHitRatio` 突然减少和 `LWLock:BufferIO` 等待事件之间的关系。此影响可能意味着您有一个较小的共享缓冲区设置。您可能需要增加数据库实例类或对其进行纵向扩展。您可以将工作负载拆分为更多的读取器节点。
+ 验证是否有未使用的索引，然后将其删除。
+ 使用分区表（也具有分区索引）。这样做有助于保持较低的指数重新排序并降低其影响。
+ 避免对列进行不必要的索引编制。
+ 使用连接池防止数据库连接突增。
+ 作为最佳实践，限制与数据库的最大连接数。