禁用top下推后执行计划cop task数量和trace数量不一致

个人拆分上述为 4 个问题:

1.在禁用 topn_push_down 后, 为什么执行计划显示 1 个 cop task 而 trace 里却有15个?
2.在禁用 topn_push_down 后, 其余 14 个 cop task 是否真正的执行了?
3. tablereader 算子返回 32 行是依据什么算来的?
4. 在禁用 topn_push_down 后,调整 tidb_distsql_scan_concurrency=1, trace 等同于 1 的原因?

  • First ASK: 为什么执行计划显示 1 个 cop task 而 trace 里却有15个?
    First Answer: 因为真的构造了 15 个发向 tikv 的请求。 cop task 的数量的计算的是 ResultSubset 的数量,在代码中 ResultSubset 注释为 一个存储单元的结果集,也就是说 cop task 与 Region 一一对应。在 TiDB 测看来,组件 tidb 接收一个 Region 的结果集就可以完成上层处理。因此,cop task num 是 1。至于 trace 到 15 个 Region Request,是因为在构造请求阶段会开启 tidb_dist_scan_concurrency 数量的协程向 tikv 并发发起处理请求,concurrency 代码位置
    image

  • Second ASK: 14 个 cop task 是否真正的执行了?
    Second Answer: 真的执行了。 从如下 2 张 TiKV Ops Details 手动加了基于 {{instance}} 区分的图像可以看出,IP194 和 IP155 分别扫了 RocksDB write 列簇 100.5K 和 36.5K 个 key。也就是说这些请求,真实的发送到了 TiKV 处理,而且从 Handle Duration 100% 看,运行了相同的时间。随后被 cancel 掉,至于为什么被 cancel,后文解释。


  • Third ASK: tablereader 算子返回 32 行是依据什么算来的?
    Third Answer:依据 tidb 侧接收并处理的, chunk 中的数据行数总和计算得出。 tidb 在构造并发起 tikv 请求后,使用 chunk(一块内存空间) 接收并处理 tikv 返回的结果。在 Executor 每次调用 Next()时,记录下处理的 chunk 中的行数因此也代表 ActRows 的真实意义,即:TiDB 真实处理的行数,从 tikv 获取返回结果的行数。

  • Fourth ASK: 调整 tidb_distsql_scan_concurrency=1, trace 等同于 1 的原因?
    Fourth Answer: 因为构造请求时(func Open)会基于 tidb_distsql_scan_concurrency 构造 worker。如果 tidb_distsql_scan_concurrency 置为 1 恰好与该语句需要数据量的 region 相等,出现了该现象。 其实,也不完全是基于 tidb_distsql_scan_concurrency 构造,tidb 会基于执行计划的 task 计算并合理构造 request worker。如下图所示,build task 计算出 task 数量,如果 tidb_distsql_scan_concurrency > task 数量则取 task 数量 worker。如果 tidb_distsql_scan_concurrency < 1 则 worker 数量置为 1,保证至少有一个 worker 去 tikv 请求数据,代码位置
    image

其实,思考上述问题过程中,我必须回答下述几个问题。或,顺带发现几个以前所不知道的问题,总结如下。

  1. trace 到的数据是否都是真实执行的?
    只要 trace 到便是真实执行的,tidb 的 trace 引入了 opentracing,在执行步骤的各个阶段埋点记录。即只要 trace 到,那么一定执行了该代码模块,包含 “执行失败” 或 “手动取消”


  2. 其余 14 个 task 是否全部执行完了?
    没有全部执行完,禁用 topn_push_down 后,将 tidb 的日志级别改为 DEBUG 后,执行 trace select * from sbtest1 limit 1; 会发现有 14 条 cancel cop request 日志打出。也就说明,tidb 取消了其余 14 个 Region 的处理请求。


  3. explain analyze 中 loop 代表什么意思?
    正如代码注释的那样,TiDB 计算框架采用向量模型(变异的火山模型),也就是说 loop 代表 “向量模型中执行器的 Next 方法的调用次数”代码位置

  4. 为什么不禁用 topn_push_down tidb 就可以只 request 1 个 region?
    如问题 4 中最后阐述部分,request worker 除参考 tidb_distsql_scan_concurrency 外,还要参考优化器评估的 cop task 的数量。也就是说,在 topn_push_down 非禁用状态下,优化器可以直接评估出 cop task 数量为 1 即可,也就是 region 为 1 即可。至于优化器优化细节,需要大量前置知识,不再继续深追研究🧐!!

3 个赞