29.12.6 性能模式语句事件表
性能模式用于监控语句执行。语句事件发生在事件层次结构的高级别。在事件层次结构中,等待事件嵌套在阶段事件中,阶段事件嵌套在语句事件中,语句事件嵌套在事务事件中。
这些表格存储语句事件:
-
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节,“性能_schema启动配置”,以及第29.4节,“性能_schema运行时配置”。
语句监控从服务器开始看到活动请求到所有活动停止为止。通常,这意味着从客户端发送第一包数据到服务器响应完成的时间。存储程序中的语句被监控得像其他语句一样。
当性能_schema对请求进行指标(服务器命令或SQL语句)时,它使用以更通用的(或称为“抽象”)开始,以更具体的名称结束,直到达到最终指标名称。
最终指标名称对应于服务器命令和SQL语句:
-
服务器命令对应于在mysql_com.h头文件中定义的COM_xxx代码,并在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
用于接收服务器的消息,这些消息是出站的。它可以用来检测客户端发送给服务器但服务器不理解的命令。这可能对识别配置不当或使用与服务器更高版本的客户端、或者尝试攻击服务器的客户端有所帮助。 -
statement/sql/error
用于接收无法解析的SQL语句。它可以用来检测由客户端发送的错误查询。一个查询如果无法解析,则与在执行过程中由于错误失败的查询不同。例如,SELECT * FROM是无效的,并使用statement/sql/error指标。相比之下,SELECT *能够解析但因“No tables used”错误失败。在这种情况下,使用statement/sql/select并且语句事件包含信息来指示错误的性质。
对于请求的详细信息最初不明确,性能_schema会按照请求来源的顺序,从抽象到具体的指标名称进行转换。
-
当服务器检测到新的包在套接字级别时,一个新的语句开始,并使用一个抽象指标名称statement/abstract/new_packet。
-
当服务器读取包号码时,它知道了更多关于请求类型的信息,性能_schema会精化指标名称。例如,如果请求是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可以被监控,但是在复制日志中的行事件不会以独立的声明语句形式出现。
对于来自Event Scheduler的请求:
事件执行会使用名称 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
,不会聚合任何统计信息,因为没有声明语句会以抽象仪表作为最终的声明名称进行分类。