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

auto_explain原理探究

原创 NickYoung 2024-12-03
291

前言

auto_explain是一个自动记录“慢sql”执行计划到数据库日志的插件,这样就不需要手动去执行explain分析sql的执行计划了。特别是对于大型应用未优化的sql的追踪,以及一些历史sql性能问题的溯源是很有帮助的。

顾名思义,就是自动执行explain,我们可以推测下它的原理:插件的hook函数去调用explain对应的逻辑,然后打印执行计划到数据库日志。

如下示例,开启相关参数,执行sql时执行计划自动记录到了日志中。
image.png

image.png

原理

启用auto_explain,需要将其配置到shared_preload_libraries参数,这样在主进程启动时就会加载插件对应的so文件,初始化自定参数和hook函数。

生成执行计划是在planner里进行的,auto_explain只是在Execute阶段将计划打印出来,显式explain也是同理,只是打印计划。

当开启插件后,在sql执行阶段,ExecutorEnd函数中判断如果已经注册了hook函数,则进入explain_ExecutorEnd
如果sql执行时间msec >= auto_explain.log_min_duration参数,则进入后续打印执行计划逻辑。

进入关键函数ExplainPrintPlan调用ExplainNode,调用InstrEndLoop(planstate->instrument)计算当前plan node运行的starttime totaltime等信息。如果auto_explain.log_analyze参数为on,则计算当前plan node对应的startup_ms,total_ms,rows,nloops然后调用appendStringInfo(es->str)来传参拼接“actual time”信息。

从计划树自上而下每个node进行上述打印处理,将所有node处理结果放到一个字符数组,最终调用ereport()将整个字符数组也就是完整的执计划打印到数据库日志中。

image.png

debug关键过程:
explain_ExecutorEnd函数中:判断msec >= auto_explain.log_min_duration,且auto_explain.log_analyze为on
企业微信截图_3230cc5feeb443c48d3f6e562e31b222.png

ExplainNode函数中:根据planstate->instrument计算出当前node运行的startup_ms,total_ms,rows,nloops,并且调用appendStringInfo(es->str)来传参拼接“actual time”
企业微信截图_96cf0f4a4ea84ce1a83e99ad6fce8541.png

企业微信截图_68e6cabc40b0473db965ffbe9aa2d65f.png

所有node处理完后,通过ereport()打印到日志。
企业微信截图_10ac97d071c24948a70b1910d1554734.png

小结

简单总结下auto_explain的原理:sql执行时插件的hook函数去调用explain对应的逻辑,然后打印执行计划到数据库日志。
不过,值得注意的是使用该插件会带来一些性能开销,详情可参考《auto_explain 的开销有多大》

最后修改时间:2024-12-04 10:06:09
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论