性能模式记录语句执行。语句事件在事件层次结构的高级别中发生。在事件层次结构中,等待事件嵌套在阶段事件中,阶段事件嵌套在语句事件中,语句事件嵌套在事务事件中。
这些表存储语句事件:
-
events_statements_current
:每个线程的当前语句事件。 -
events_statements_history
:每个线程最近结束的语句事件。 -
events_statements_history_long
:所有线程最近结束的语句事件。 -
prepared_statements_instances
:预备语句实例和统计信息
以下部分描述语句事件表。还有汇总表,聚合语句事件信息;见 第 29.12.20.3 节,“语句汇总表”。
有关三个 events_statements_
事件表之间的关系的更多信息,请见 第 29.9 节,“性能模式当前和历史事件表”。xxx
配置语句事件收集
要控制是否收集语句事件,请设置相关仪器和消费者的状态:
-
The
setup_instruments
表包含以statement
开头的仪器名称。使用这些仪器来启用或禁用个别语句事件类的收集。 -
The
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 节,“性能模式运行时配置”。
语句监控
语句监控从服务器看到活动请求的那一刻开始,直到所有活动停止。通常,这意味着从服务器收到客户端的第一个数据包到服务器发送响应的那一刻。存储程序中的语句与其他语句一样被监控。
当性能模式仪器一个请求(服务器命令或 SQL 语句)时,它使用仪器名称,从一般(或“抽象”)到特定,直到到达最终仪器名称。
最终仪器名称对应服务器命令和 SQL 语句:
-
服务器命令对应于
COM_
,定义在xxx
代码mysql_com.h
头文件中,并在sql/sql_parse.cc
中处理。例如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
账户服务器收到的出带消息。它可以用于检测客户端发送的命令,服务器不理解。这可能有助于检测客户端的misconfigured 或使用的 MySQL 版本比服务器版本新,或者客户端尝试攻击服务器。 -
statement/sql/error
账户 SQL 语句解析失败。它可以用于检测客户端发送的畸形查询。一个解析失败的查询与一个解析成功但执行失败的查询不同。例如,SELECT * FROM
是畸形的,statement/sql/error
仪器被使用。相比之下,SELECT *
解析成功但执行失败,出现“No tables used”错误。在这种情况下,statement/sql/select
仪器被使用,并且语句事件包含错误信息。
请求可以来自以下任何来源:
-
作为客户端的命令或语句请求,发送请求作为数据包
-
作为从副本的中继日志中读取的语句字符串
-
作为事件调度器的事件
请求的详细信息最初不知道,性能模式从抽象到特定的仪器名称序列,取决于请求的来源。
对于从客户端接收的请求:
-
当服务器在套接字级别检测到新的数据包时,一个新的语句以抽象仪器名称
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
,这是最终名称。
前面的描述仅适用于基于语句的复制。对于基于行的复制,副本上处理行更改时的表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
,不聚合统计信息,因为没有语句是使用抽象仪器作为最终语句名称的。