mysql进程列表中“正在发送数据”是什么意思?

fli*_*fly 3 mysql mariadb performance query-performance

我发现一个查询长时间卡在进程列表中,状态为“正在发送数据”。这个状态是什么意思?

fli*_*fly 5

如果有人知道更多,请填补空白。


TL;DR “发送数据”似乎意味着我们正在将有关查询的数据发送到将这些信息收集在一起的函数。它不会将数据发送到 MySQL 或 MariaDB 客户端。这可能与 JOIN 命令的汇编有关。


在互联网上找不到很好的说明,我开始浏览 MariaDB 10.2 的“发送数据”代码(是的,开源)。请谨慎对待这一切,因为我不是 C++ 黑客。

您可以在sql/mysqld.cc 的第 10155 行中找到它与stage_sending_data. 这可以在sql_select.cc 第 3561 行中找到,位于 JOIN::exec_inner 函数的末尾。该函数由函数 JOIN::exec() 调用。JOIN::exec 是从函数 mysql_select() 中调用的。这是从handle_select()调用的。看来“发送数据”应该只显示在带有 JOIN 的查询上。

我想我看到 mysql_select() 设置状态“Init”或 stage_init。然后在 JOIN::exec_inner() 中“执行”或 stage_executing,同时它对我认为中断 JOIN 或需要特别注意的各种事情进行一些检查。

然后它将该状态设置为“正在发送数据”或 stage_sending_data。在设置此状态后的接下来几行中,它将运行do_select(this, procedure);。此时,它似乎实际上开始收集提供查询答案所需的信息。与我的期望相反,很明显“发送数据”不是将数据发送到客户端(通过网络或其他方式),而是发送到另一个函数。目前尚未准备好做出回应。do_select()继续执行一些操作,例如对临时表进行排序、评估 HAVING、WHERE 等条件。它还可以删除锁。所有这些都是在“正在发送数据”状态设置之后。

它可能是实际返回数据之前的最后一个状态设置。我还没有足够的挖掘来清楚地说明这一点。do_select() 中发生了很多事情,所以我预计状态可能会在某个地方发生变化,但这可能取决于各种因素。在 mysql_select 结束时,它确实将状态设置为“end”或 stage_end。