Mysql show profiles 实现探秘

Mysql性能分析时我们常常会用show profiles工具去查看sql执行的时间,资源消耗等数据。那它到底是怎么实现的呢?如下图是一张某个sql的性能分析图。

show profiles显示了执行时长,CPU使用,环境切换,io操作以及每步的代码文件行。一般我们会比较关注Duration字段,分析mysql内部各步执行时长。那这个时长是怎么记录下来的呢。以Mysql 5.7.4为例(不同版本的代码可能会有出入)

以Sending data步骤为例, 可以看出代码执行是从sql_executor.cc的195行开始的,我们可以定位到改行代码。

可以看出,此处记录了一个stage_sending_data的状态。调用了THD_STAGE_INFO函数。接着我们继续查看这个函数定义。

可以看出来THD_STAGE_INFO是宏定义。我们继续追代码enter_stage函数。

此时我们终于看到了跟主题相关的性能分析对象profiling。接着进入status_change函数查看代码。

接着跟入到new_status函数中。

此处是C++的一个重载函数,根据不同的流程,传入不同的参数。接着跟入代码。

此处我们看到了collect()函数调用。接着看下去代码。

collect函数中调用了系统函数getrusage()函数去获取当前线程的运行时间,内存,CPU等信息。getrusage的定义可以参考linux中的定义http://man7.org/linux/man-pages/man2/getrusage.2.html

从此处可以看出,Sending data这步时打印了当时的系统中线程执行时间等信息。貌似并没有这一步的执行时长。据此推测呢,有了当前的时间点,根据前一个时间点,就可以推导出每一步的执行时长。我们进一步查看show profile执行的代码。

从代码中我们可以看出这里有文字描述。详细介绍了duration是计算出来的。由T(n) – T(n-1) 就得出了前一个状态的执行时长。依次遍历。就显示出了每一步的时长。

通过源代码的阅读,我们可以看出来show profiles是怎么实现的了。在开启性能分析后,SQL执行的每一步流程中都会将当前步骤标记,并记录出当前的执行时长,资源调用等信息。然后在性能分析查询时,根据每一步记录的信息。最终计算出每个阶段的执行时长Duration。

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>