

# io/table/sql/handler
<a name="ams-waits.waitio"></a>

当工作被委派给存储引擎时，会发生 `io/table/sql/handler` 事件。

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

## 支持的引擎版本
<a name="ams-waits.waitio.context.supported"></a>

以下引擎版本支持此等待事件信息：
+ Aurora MySQL 版本 2 和 3

## 上下文
<a name="ams-waits.waitio.context"></a>

事件 `io/table` 表示等待访问表。无论数据是缓存在缓冲池中还是可在磁盘上访问，都会发生此事件。`io/table/sql/handler` 事件表示工作负载活动增加。

*处理程序*是专门处理某种类型的数据或专注于某些特殊任务的例程。例如，事件处理程序接收和提取来自操作系统或用户界面的事件和信号。内存处理程序执行与内存相关的任务。文件输入处理程序是接收文件输入并根据上下文对数据执行特殊任务的函数。

`performance_schema.events_waits_current` 之类的视图在实际的等待是嵌套的等待事件（例如锁定）时经常显示 `io/table/sql/handler`。当实际的等待不是 `io/table/sql/handler` 时，性能详情将报告嵌套的等待事件。当性能详情报告 `io/table/sql/handler` 时，它表示 I/O 请求的 InnoDB 处理，而不是隐藏的嵌套等待事件。有关更多信息，请参阅 *MySQL 参考手册*中的 [Performance Schema“原子”和“分子”事件](https://dev.mysql.com/doc/refman/5.7/en/performance-schema-atom-molecule-events.html)。

`io/table/sql/handler` 事件通常显示在具有 `io/aurora_redo_log_flush` 之类的输入/输出等待的主要等待事件中。

## 等待次数增加的可能原因
<a name="ams-waits.waitio.causes"></a>

在性能详情中，`io/table/sql/handler` 事件突然激增表示工作负载活动增加。活动增加意味着输入/输出增加。

当底层嵌套事件为锁定等待时，性能详情会筛选嵌套事件 ID，但不会报告 `io/table/sql/handler` 等待。例如，如果根本原因事件是 [synch/mutex/innodb/aurora\$1lock\$1thread\$1slot\$1futex](ams-waits.waitsynch.md)，性能详情会将此等待显示在主要等待事件中而不是 `io/table/sql/handler` 中。

在 `performance_schema.events_waits_current` 之类的视图中，当实际的等待是嵌套的等待事件（例如锁定）时经常显示 `io/table/sql/handler` 的等待。当实际等待与 `io/table/sql/handler` 不同时，性能详情会查找嵌套等待并报告实际等待而不是 `io/table/sql/handler`。当性能详情报告 `io/table/sql/handler` 时，实际的等待为 `io/table/sql/handler`，而不是隐藏的嵌套等待事件。有关更多信息，请参阅 *MySQL 5.7 参考手册*中的 [Performance Schema“原子”和“分子”事件](https://dev.mysql.com/doc/refman/5.7/en/performance-schema-atom-molecule-events.html)。

## 操作
<a name="ams-waits.waitio.actions"></a>

如果此等待事件主导着数据库活动，它不一定表示性能问题。当数据库处于活动状态时，等待事件始终显示在最前面。您只需要在性能下降时采取行动。

根据您看到的其他等待事件，我们建议采取不同的操作。

**Topics**
+ [确定导致事件的会话和查询](#ams-waits.waitio.actions.identify)
+ [检查与性能详情计数器指标的关联性](#ams-waits.waitio.actions.filters)
+ [检查其他相关的等待事件](#ams-waits.waitio.actions.maintenance)

### 确定导致事件的会话和查询
<a name="ams-waits.waitio.actions.identify"></a>

通常，具有中等到大量负载的数据库都会有等待事件。如果性能最佳，等待事件可能是可以接受的。如果性能不佳，请检查数据库花费最多时间的位置。查看导致最高负载的等待事件，并了解是否可以优化数据库和应用程序以减少这些事件。

**查找负责高负载的 SQL 查询**

1. 登录 AWS 管理控制台 并通过以下网址打开 Amazon RDS 控制台：[https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)。

1. 在导航窗格中，选择**性能详情**。

1. 选择一个数据库实例。将为该数据库实例显示性能详情控制面板。

1. 在 **Database load**（数据库负载）图表中，选择 **Slice by wait**（按等待切片）。

1. 在页面底部，选择 **Top SQL**（热门 SQL）。

   该图表列出了负责加载的 SQL 查询。排在列表前面的负载负有最大的责任。为了解决瓶颈，请关注这些语句。

有关使用性能详情进行故障排除的有用概览，请参阅博客文章[利用性能详情分析 Amazon Aurora MySQL 工作负载](https://aws.amazon.com/blogs/database/analyze-amazon-aurora-mysql-workloads-with-performance-insights/)。

### 检查与性能详情计数器指标的关联性
<a name="ams-waits.waitio.actions.filters"></a>

检查性能详情计数器指标，如 `Innodb_rows_changed`。如果计数器指标与 `io/table/sql/handler` 相关，请按照以下步骤操作：

1. 在性能详情中，查找负责 `io/table/sql/handler` 主要等待事件的 SQL 语句。如果可能，请优化此语句，使其返回的行更少。

1. 从 `schema_table_statistics` 和 `x$schema_table_statistics` 视图中查看主要的表。这些视图显示了每个表花费的时间。有关更多信息，请参阅 *MySQL 参考手册*中的 [schema\$1table\$1statistics 和 x\$1schema\$1table\$1statistics 视图](https://dev.mysql.com/doc/refman/5.7/en/sys-schema-table-statistics.html)。

   预设情况下，行按总等待时间降序排序。争用最多的表首先显示。输出表明时间是花在读取、写入、获取、插入、更新还是删除上。

   ```
   mysql> select * from sys.schema_table_statistics limit 1\G
   
   *************************** 1. row ***************************
        table_schema: read_only_db
          table_name: sbtest41
       total_latency: 54.11 m
        rows_fetched: 6001557
       fetch_latency: 39.14 m
       rows_inserted: 14833
      insert_latency: 5.78 m
        rows_updated: 30470
      update_latency: 5.39 m
        rows_deleted: 14833
      delete_latency: 3.81 m
    io_read_requests: NULL
             io_read: NULL
     io_read_latency: NULL
   io_write_requests: NULL
            io_write: NULL
    io_write_latency: NULL
    io_misc_requests: NULL
     io_misc_latency: NULL
   1 row in set (0.11 sec)
   ```

### 检查其他相关的等待事件
<a name="ams-waits.waitio.actions.maintenance"></a>

如果 `synch/sxlock/innodb/btr_search_latch` 和 `io/table/sql/handler` 是造成数据库加载异常的最大因素，检查 `innodb_adaptive_hash_index` 变量是否已开启。如果是，请考虑增加 `innodb_adaptive_hash_index_parts` 参数值。

如果自适应哈希索引已关闭，请考虑将其开启。要了解有关 MySQL 自适应哈希索引的更多信息，请参阅以下资源：
+ Percona 网站上的文章 [InnoDB 中的自适应哈希索引是否适合我的工作负载？](https://www.percona.com/blog/2016/04/12/is-adaptive-hash-index-in-innodb-right-for-my-workload)
+ *MySQL 参考手册*中的[自适应哈希索引](https://dev.mysql.com/doc/refman/5.7/en/innodb-adaptive-hash.html)
+ Percona 网站上的文章 [MySQL InnoDB 中的争用：信号灯部分的有用信息](https://www.percona.com/blog/2019/12/20/contention-in-mysql-innodb-useful-info-from-the-semaphores-section/)

**注意**  
Aurora 读取器数据库实例不支持自适应哈希索引。  
在某些情况下，当 `synch/sxlock/innodb/btr_search_latch` 和 `io/table/sql/handler` 起主导作用时，读取器实例的性能可能较差。如果是这样，请考虑临时将工作负载重新导向到写入器数据库实例并开启自适应哈希索引。