25.12.6 性能架构语句事件 table

Performance Schema 检测语句执行。语句事件发生在事件层次结构的较高级别。在事件层次结构中,await 事件嵌套在阶段事件内,嵌套在语句事件内,嵌套在事务事件内。

这些 table 存储语句事件:

以下各节描述了语句事件 table。也有汇总 table,汇总有关语句事件的信息。参见第 25.12.15.3 节,“语句摘要 table”

有关三个events_statements_xxx事件 table 之间的关系的更多信息,请参见第 25.9 节“当前和历史事件的性能架构 table”

配置语句事件整理

要控制是否收集语句事件,请设置相关工具和使用者的状态:

  • setup_instrumentstable 包含名称以statement开头的乐器。使用这些工具可以启用或禁用单个语句事件类的收集。

  • setup_consumerstable 包含名称与当前和历史语句事件 table 名称相对应的使用者值,以及语句摘要使用者。使用这些使用者来过滤语句事件和语句摘要的集合。

默认情况下启用语句工具,并且默认情况下启用events_statements_currentevents_statements_historystatements_digest语句使用者:

mysql> SELECT *
       FROM performance_schema.setup_instruments
       WHERE NAME LIKE 'statement/%';
+---------------------------------------------+---------+-------+
| NAME                                        | ENABLED | TIMED |
+---------------------------------------------+---------+-------+
| statement/sql/select                        | YES     | YES   |
| statement/sql/create_table                  | YES     | YES   |
| statement/sql/create_index                  | YES     | YES   |
...
| statement/sp/stmt                           | YES     | YES   |
| statement/sp/set                            | YES     | YES   |
| statement/sp/set_trigger_field              | YES     | YES   |
| statement/scheduler/event                   | YES     | YES   |
| statement/com/Sleep                         | YES     | YES   |
| statement/com/Quit                          | YES     | YES   |
| statement/com/Init DB                       | YES     | YES   |
...
| statement/abstract/Query                    | YES     | YES   |
| statement/abstract/new_packet               | YES     | YES   |
| statement/abstract/relay_log                | YES     | YES   |
+---------------------------------------------+---------+-------+
mysql> SELECT *
       FROM performance_schema.setup_consumers
       WHERE NAME LIKE '%statements%';
+--------------------------------+---------+
| NAME                           | ENABLED |
+--------------------------------+---------+
| events_statements_current      | YES     |
| events_statements_history      | YES     |
| events_statements_history_long | NO      |
| statements_digest              | YES     |
+--------------------------------+---------+

要在服务器启动时控制语句事件的收集,请在my.cnf文件中使用以下行:

  • Enable:
[mysqld]
performance-schema-instrument='statement/%=ON'
performance-schema-consumer-events-statements-current=ON
performance-schema-consumer-events-statements-history=ON
performance-schema-consumer-events-statements-history-long=ON
performance-schema-consumer-statements-digest=ON
  • Disable:
[mysqld]
performance-schema-instrument='statement/%=OFF'
performance-schema-consumer-events-statements-current=OFF
performance-schema-consumer-events-statements-history=OFF
performance-schema-consumer-events-statements-history-long=OFF
performance-schema-consumer-statements-digest=OFF

要在运行时控制语句事件收集,请更新setup_instrumentssetup_consumerstable:

  • Enable:
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME LIKE 'statement/%';

UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME LIKE '%statements%';
  • Disable:
UPDATE performance_schema.setup_instruments
SET ENABLED = 'NO', TIMED = 'NO'
WHERE NAME LIKE 'statement/%';

UPDATE performance_schema.setup_consumers
SET ENABLED = 'NO'
WHERE NAME LIKE '%statements%';

要仅收集特定的语句事件,请仅启用相应的语句工具。要仅为特定的语句事件 table 收集语句事件,请启用语句工具,但仅启用与所需 table 相对应的语句使用者。

setup_timerstable 包含NAME值为statement的行,该行指示语句事件计时的单位。默认单位是NANOSECOND

mysql> SELECT *
       FROM performance_schema.setup_timers
       WHERE NAME = 'statement';
+-----------+------------+
| NAME      | TIMER_NAME |
+-----------+------------+
| statement | NANOSECOND |
+-----------+------------+

要更改计时单位,请修改TIMER_NAME值:

UPDATE performance_schema.setup_timers
SET TIMER_NAME = 'MICROSECOND'
WHERE NAME = 'statement';

有关配置事件收集的其他信息,请参阅第 25.3 节“性能架构启动配置”第 25.4 节“性能架构运行时配置”

Statement Monitoring

语句监视从服务器看到线程上请求活动的那一刻开始,到所有活动都停止的那一刻开始。通常,这意味着从服务器从 Client 端获取第一个数据包到服务器完成发送响应的时间。像其他语句一样,对存储程序中的语句进行监视。

当性能模式对请求(服务器命令或 SQL 语句)进行检测时,它将使用从更一般(或称为“抽象”)到更具体的阶段逐步进行的设备名称,直到获得最终的设备名称。

最终的仪器名称对应于服务器命令和 SQL 语句:

  • 服务器命令与在mysql_com.h头文件中定义并在sql/sql_parse.cc中处理的COM_xxx codes相对应。示例是COM_PINGCOM_QUIT。命令工具的名称以statement/com开头,例如statement/com/Pingstatement/com/Quit

  • SQL 语句 table 示为文本,例如DELETE FROM t1SELECT * FROM t2。用于 SQL 语句的工具的名称以statement/sql开头,例如statement/sql/deletestatement/sql/select

一些最终的仪器名称特定于错误处理:

  • statement/com/Error负责服务器接收的带外消息。它可用于检测服务器不理解的 Client 端发送的命令。这对于以下目的可能是有帮助的,例如识别配置错误的 Client 端或使用比服务器版本更新的 MySQL 版本,或尝试攻击服务器的 Client 端。

  • statement/sql/error用于解析失败的 SQL 语句。它可用于检测 Client 端发送的格式错误的查询。解析失败的查询与解析但由于执行期间的错误而失败的查询不同。例如,SELECT * FROM格式不正确,而使用了statement/sql/error工具。相比之下,SELECT *解析但由于No tables used错误而失败。在这种情况下,将使用statement/sql/select,并且语句事件包含指示错误性质的信息。

可以从以下任何来源获得请求:

  • 作为来自 Client 端的命令或语句请求,Client 端将请求作为数据包发送

  • 作为语句字符串从副本上的中继日志中读取

  • 作为事件计划程序中的事件

最初不知道请求的详细信息,并且性能模式会根据请求的源 Sequences 从抽象到特定的仪器名称。

对于来自 Client 的请求:

  • 当服务器在套接字级别检测到新数据包时,将以抽象工具名称statement/abstract/new_packet开始新语句。

  • 当服务器读取数据包编号时,它会更多地了解收到的请求的类型,并且“性能模式”会优化工具名称。例如,如果请求是COM_PING数据包,则仪器名称将变为statement/com/Ping,即最终名称。如果请求是COM_QUERY数据包,则已知它对应于 SQL 语句,而不是特定类型的语句。在这种情况下,工具从一个抽象名称更改为一个更具体但仍抽象的名称statement/abstract/Query,并且请求需要进一步分类。

  • 如果请求是语句,则读取语句文本并将其提供给解析器。解析后,确切的语句类型是已知的。例如,如果请求是INSERT语句,则性能模式会将仪器名称从statement/abstract/Query精简为statement/sql/insert,这是最终名称。

对于请求,从副本上的中继日志中读取为语句:

  • 中继日志中的语句以文本形式存储并按原样读取。没有网络协议,因此未使用statement/abstract/new_packet仪器。相反,初始工具为statement/abstract/relay_log

  • 解析该语句时,确切的语句类型是已知的。例如,如果请求是INSERT语句,则性能模式会将仪器名称从statement/abstract/Query精简为statement/sql/insert,这是最终名称。

前面的描述仅适用于基于语句的复制。对于基于行的复制,可以检测副本在处理行更改时在其上完成的 tableI/O,但中继日志中的行事件不会显示为离散语句。

对于从事件计划程序收到的请求:

使用名称statement/scheduler/event检测事件执行。这是最终名称。

在事件主体中执行的语句使用statement/sql/*名称进行检测,而无需使用任何先前的抽象工具。事件是存储的程序,并且存储的程序在执行之前已预先在内存中编译。因此,在运行时不会进行解析,并且每个语句的类型在执行时都是已知的。

在事件主体中执行的语句是子语句。例如,如果事件执行INSERT语句,则事件本身的执行是使用statement/scheduler/event进行检测的父级,而INSERT是使用statement/sql/insert进行检测的子级。父/子关系在单独的检测操作之间保持。这不同于在*一个仪器操作中发生的细化 Sequences,从抽象到最终仪器名称。

对于要为语句收集的统计信息,仅启用用于单个语句类型的最终statement/sql/*工具是不够的。还必须启用抽象的statement/abstract/*工具。这通常不会成为问题,因为默认情况下所有语句工具都是启用的。但是,有选择地启用或禁用语句工具的应用程序必须考虑到禁用抽象工具也将禁用单个语句工具的统计信息收集。例如,要收集INSERT语句的统计信息,必须启用statement/sql/insert,还必须启用statement/abstract/new_packetstatement/abstract/Query。同样,要检测复制语句,必须启用statement/abstract/relay_log

对于诸如statement/abstract/Query之类的抽象工具,不会汇总任何统计信息,因为没有任何语句使用抽象工具作为最终语句名称进行分类。