查看并行算子的运行时信息
events_parallel_operator_xxx表中提供并行查询中并行算子的相关信息,所谓并行算子,指可以由多个线程并行执行完成的任务,比如gather,gather会创建一组worker线程,由一组worker线程共同来完成扫描任务。
events_parallel_operator_current表中保存session中最近一次执行的并行查询相关的并行算子的执行信息。
events_parallel_operator_history表中保存session中最近执行的并行查询相关的并行算子的历史信息,默认是每个session最近10条并行查询的并行算子信息。
并行算子在执行计划中也可以查看到,如下所示:
explain select sum(c3), c4 from test.t1 where c3 > 5000 group by c4;

其中就是一个并行算子,它会执行Parallel scan,计划由32workers来完成。当然受限于资源的限制,实际上worker的数量可能会少于计划的32个workers.
当查询执行计划过程中或完成后,可以通过events_parallel_operator_current查看最近执行语句的并行算子相关信息。
select *
from performance_schema.events_parallel_operator_history
where thread_id= xxx /* 替换为前面查询的thread_id*/
表events_parallel_operator_xxx中包含以下内容:
- THREAD_ID:指当前线程ID
- EVENT_ID: 指当前事件ID,在每个线程中事件ID单调递增。
- END_EVENT_ID: 指当前事件完成时的最大事件ID,当为NULL时表示当前事务尚在进行中。
- EVENT_NAME:指当前正在进行中的事件,并行相关的事件以parallel_query开始,operator表示并行算子,最后是具体的算子名称,目前只有一种gather类型。
- OPERATOR_ID:并行算子ID,每个并行查询可能有1个或多个并行算子,ID单调递增。
- OPERATOR_TYPE:并行算子类型,目前只有一种类型gather。
- STATE:执行状态,COMPLETED表示已完成,STARTED表示正在运行中。
- SOURCE:表示此事件嵌入代码的位置;
- TIMER_START:表示此事件开始时刻,单位是皮秒picoseconds (trillionths of a second).
- TIMER_END:事件结束的时刻
- TIMER_WAIT:事件持续的时间
- PLANNED_DOP:并行计划的并行度,即计划最多可以有多少worker线程
- ACTUAL_DOP:实际执行时的并行度,即实际执行时的worker线程数
- PARTITIONED_OBJECT:并行执行的目标对象
- NUMBER_OF_PARTITIONS:目标对象的内部分片数,与表的分区不同,不分区的表也可以内部分片,每个分片由一个worker来执行扫描,分片越多,并行度也越高,分片越少,并行度越低。
- MYSQL_ERRNO:执行出错时输出错误码
- RETURNED_SQLSTATE:执行出错时输出错误状态
- MESSAGE_TEXT:执行出错时输出错误消息
- ERRORS:是否正确执行的标志,出错时输出为1,否则为0
- WARNINGS:警告消息的个数
- ROWS_SENT:返回的行数
- ROWS_EXAMINED:检查的行数,不包含worker扫描的行数,通常等于所有worker返回的行数总和
- CREATED_TMP_DISK_TABLES:在磁盘上创建的临时表个数
- CREATED_TMP_TABLES:在内存中创建的临时表个数
- NESTING_EVENT_ID:关联的上级事件的ID,可以通过此ID查询父事件即并行查询事件
- NESTING_EVENT_TYPE:关联的上级事件的类型
- NESTING_EVENT_LEVEL:级别的层数。

在本例中
- Event_name是parallel_query/operator/gather,表示是并行算子gather类型的事件
- OPERATOR_ID=0,表示是本并行查询中的第1个并行算子
- OPERATOR_TYPE = GATHER,表示是GATHER
- STATE= COMPLETED表示此并行算子的执行已经完成
- TIMER_WAIT= 50229944318000,是此算子的执行时间,单位是皮秒,转成秒应该是50229944318000/1000000000000= 50.2299s
- PLANNED_DOP=32,表示计划的并行度为32
- ACTUAL_DOP=32,表示实际执行时的并行度为32,此值有时会小于计划的并行度 – 注意此处真实情况下是否
- PARTITIONED_OBJECT=lineitem:表示此gather执行并行扫描的表是lineitem表。
- NUMBER_OF_PARTITIONS=2760,表示表lineitem内部有2760个分片,这些分片会依次分配到不同的worker上执行扫描,worker当一个分片扫描完成后,会自动申请下一个分片,直到所有分片全部处理完毕。
- ROWS_SENT= 1,表示gather算子执行完成后,会产生1行数据。
- ROWS_EXAMINED = 128,表示gather算子共检查了128行数据,这些数据由worker返回,因为每个worker上会优先执行已经下推的where条件。
- CREATED_TMP_DISK_TABLES=0,表示没有在磁盘上产生临时表。
- CREATED_TMP_TABLES=1,表示产生1个内存临时表。
- NESTING_EVENT_ID=72,表示与此并行算子事件关联的父事件ID是72,这个ID可用于指定查询并行执行的主事件信息;
- NESTING_EVENT_TYPE= PARALLEL_QUERY,表示与此并行牌子事件关联的父事件类型是PARALLEL_QUERY,即并行查询事件;
- NESTING_EVENT_LEVEL=2,表示嵌套事件层级为2
查看worker的运行时信息
每个并行算子可以有多个worker,每个worker独立完成部分子任务,如扫描某个表的若干个分片。每个worker也都有自己的运行时信息,这些信息也是保存在events_parallel_query_xxx中,只是角色是worker而已。
因为worker是关联到并行算子的,所以可以通过并行算子的event_id和thread_id来过滤查询,
select *
from performance_schema.events_parallel_query_current
where parent_thread_id= xxx /*前面查询的thread_id*/
UNION
select *
from performance_schema.events_parallel_query_history
where parent_thread_id= xxx \G; /*前面查询的thread_id*/

其中:
- EVENT_NAME= parallel_query/role/worker,表示是worker事件
- PARENT_THREAD_ID= 100927,表示其父线程ID是100927
- OPERATOR_ID= 0,表示此worker所属并行算子ID为0
- WORKER_ID= 1,表示此worker的worker ID为1
- TIMER_WAIT= 49935536065000,此worker的运行时间为49935536065000/1000000000000=49.94s
- ROWS_SENT= 4,表示此worker返回4条数据
- ROWS_EXAMINED= 18413405,表示此worker共扫描了18413405行数据;
- CREATED_TMP_TABLES= 1,表示此worker创建了1个内存临时表
- NESTING_EVENT_ID= 73,表示此worker的父事件ID为73,即其关联的并行算子的event_id为73
- NESTING_EVENT_TYPE= PARALLEL_OPERATOR,表示worker的父事件类型是并行算子
- NESTING_EVENT_LEVEL= 3,表示级联事件层级为3。
文章转载自ZzzMickey,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




