性能模式检测语句执行。语句事件发生在事件层次结构的较高层级。在事件层次结构中,等待事件嵌套在阶段事件中,阶段事件嵌套在语句事件中,而语句事件又嵌套在事务事件中。
以下表存储语句事件:
events_statements_current
:每个线程的当前语句事件。events_statements_history
:每个线程已结束的最新语句事件。events_statements_history_long
:全局(所有线程)已结束的最新语句事件。prepared_statements_instances
:预处理语句实例和统计信息。
以下部分介绍语句事件表。还有一些汇总表汇总了有关语句事件的信息;请参阅 第 29.12.20.3 节,“语句汇总表”。
有关三个 events_statements_
事件表之间关系的更多信息,请参阅 第 29.9 节,“用于当前和历史事件的性能模式表”。xxx
配置语句事件收集
要控制是否收集语句事件,请设置相关检测点和消费者的状态。
setup_instruments
表包含名称以statement
开头的检测点。使用这些检测点可以启用或禁用单个语句事件类的收集。setup_consumers
表包含名称与当前和历史语句事件表名称以及语句摘要消费者相对应的消费者值。使用这些消费者可以过滤语句事件和语句摘要的收集。
默认情况下启用语句检测点,并且默认情况下启用 events_statements_current
、events_statements_history
和 statements_digest
语句消费者。
mysql> SELECT NAME, ENABLED, TIMED
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
文件中使用如下所示的行:
启用
[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
禁用
[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_instruments
和 setup_consumers
表。
启用
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%';
禁用
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%';
要仅收集特定的语句事件,请仅启用相应的语句检测点。要仅为特定的语句事件表收集语句事件,请启用语句检测点,但仅启用与所需表相对应的语句消费者。
有关配置事件收集的其他信息,请参阅 第 29.3 节,“性能模式启动配置” 和 第 29.4 节,“性能模式运行时配置”。
语句监控
语句监控从服务器发现线程上请求了活动的那一刻开始,到所有活动停止的那一刻结束。通常,这意味着从服务器获取客户端的第一个数据包到服务器完成发送响应的时间。存储程序中的语句像其他语句一样受到监控。
当 Performance Schema 检测请求(服务器命令或 SQL 语句)时,它使用的检测名称会分阶段进行,从更通用(或 “抽象”)到更具体,直到到达最终的检测名称。
最终的检测名称对应于服务器命令和 SQL 语句
服务器命令对应于在
mysql_com.h
头文件中定义并在sql/sql_parse.cc
中处理的COM_
代码。例如xxx
COM_PING
和COM_QUIT
。命令的检测名称以statement/com
开头,例如statement/com/Ping
和statement/com/Quit
。SQL 语句以文本形式表示,例如
DELETE FROM t1
或SELECT * FROM t2
。SQL 语句的检测名称以statement/sql
开头,例如statement/sql/delete
和statement/sql/select
。
一些最终的检测名称特定于错误处理
statement/com/Error
用于记录服务器接收到的带外消息。它可以用来检测客户端发送的服务器无法理解的命令。这可能有助于识别配置错误或使用比服务器更新版本的 MySQL 的客户端,或者试图攻击服务器的客户端。statement/sql/error
用于记录无法解析的 SQL 语句。它可以用来检测客户端发送的格式错误的查询。无法解析的查询与解析成功但在执行过程中出错的查询不同。例如,SELECT * FROM
格式错误,将使用statement/sql/error
检测。相比之下,SELECT *
可以解析,但会失败并返回No tables used
错误。在这种情况下,将使用statement/sql/select
,并且语句事件包含指示错误性质的信息。
可以从以下任何来源获取请求
作为来自客户端的命令或语句请求,客户端以数据包的形式发送请求
作为从副本上的中继日志读取的语句字符串
作为事件调度器中的事件
请求的详细信息最初是未知的,Performance Schema 会根据请求的来源,按照从抽象到具体的检测名称序列进行处理。
对于从客户端接收的请求
当服务器在套接字级别检测到新数据包时,将使用抽象检测名称
statement/abstract/new_packet
启动新语句。当服务器读取数据包编号时,它会了解更多关于接收到的请求类型的信息,Performance Schema 会细化检测名称。例如,如果请求是
COM_PING
数据包,则检测名称将变为statement/com/Ping
,这就是最终名称。如果请求是COM_QUERY
数据包,则已知它对应于 SQL 语句,但不知道是哪种特定类型的语句。在这种情况下,检测会从一个抽象名称更改为更具体但仍然抽象的名称,即statement/abstract/Query
,并且请求需要进一步分类。如果请求是一个语句,则读取语句文本并将其交给解析器。解析之后,确切的语句类型就知道了。例如,如果请求是一个
INSERT
语句,Performance Schema 会将检测名称从statement/abstract/Query
细化为statement/sql/insert
,这就是最终名称。
对于作为语句从副本上的中继日志读取的请求
中继日志中的语句以文本形式存储,并按文本形式读取。没有网络协议,因此不使用
statement/abstract/new_packet
检测。相反,初始检测是statement/abstract/relay_log
。当语句被解析时,确切的语句类型就知道了。例如,如果请求是一个
INSERT
语句,Performance Schema 会将检测名称从statement/abstract/Query
细化为statement/sql/insert
,这就是最终名称。
上述描述仅适用于基于语句的复制。对于基于行的复制,可以检测副本在处理行更改时执行的表 I/O,但中继日志中的行事件不会显示为离散的语句。
对于从事件调度器接收的请求
使用名称 statement/scheduler/event
对事件执行进行检测。这就是最终名称。
事件体中执行的语句使用 statement/sql/*
名称进行检测,而不使用任何前面的抽象检测。事件是一个存储程序,存储程序在执行前会在内存中预编译。因此,在运行时没有解析,并且每个语句的类型在执行时就已经知道了。
在事件体中执行的语句是子语句。例如,如果一个事件执行了一个 INSERT
语句,则事件本身的执行是父语句,使用 statement/scheduler/event
进行检测,而 INSERT
是子语句,使用 statement/sql/insert
进行检测。父子关系存在于单独的检测操作之间。这与在单个检测操作内部发生的从抽象到最终检测名称的细化顺序不同。
要收集语句的统计信息,仅启用用于单个语句类型的最终 statement/sql/*
检测是不够的。还必须启用抽象的 statement/abstract/*
检测。这通常不是问题,因为默认情况下所有语句检测都是启用的。但是,有选择地启用或禁用语句检测的应用程序必须考虑到,禁用抽象检测也会禁用对单个语句检测的统计信息收集。例如,要收集 INSERT
语句的统计信息,必须启用 statement/sql/insert
,但也必须启用 statement/abstract/new_packet
和 statement/abstract/Query
。类似地,要对复制的语句进行检测,必须启用 statement/abstract/relay_log
。
不会为抽象检测(如 statement/abstract/Query
)汇总统计信息,因为没有任何语句会被分类为最终语句名称为抽象检测的语句。