暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL · 最佳实践 · 今天你并行了吗?---洞察PolarDB 8.0之并行查询(三)

ZzzMickey 2024-07-27
146

查看并行算子的运行时信息

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;

image.png

其中就是一个并行算子,它会执行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:级别的层数。
    image.png

在本例中

  • 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*/

image.png

其中:

  • 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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论