在做性能调优的过程中,除了各语言相关的 profiling 工具,perf 也是一个好帮手,能从系统级别观察程序运行性能,配合火焰图能更直观地展示 c 级别函数调用在时间上的占比情况,本文将会介绍这两个工具的基本使用。实验对象为 mysql,观察执行 sql 时内部发生了什么。当然,perf 和火焰图能应用在任何其他软件调优上。
注意,不要在生产环境搞事情
安装
perf 建议用系统自带的包管理工具安装
# debian系
sudo apt install linux-tools-generic
# redhat系
sudo yum install perf
火焰图工具直接 clone,注意将 FlameGraph 目录加到 path 中
git clone https://github.com/brendangregg/FlameGraph
采样
我们需要通过 perf 采集性能相关数据样本,以生成火焰图。有几种方法可供选择
采固定时长,这里是 10 秒
sudo perf record -a -F 99 -g -p $(pgrep -x mysqld) -- sleep 10
一直采,直到 ctrl+c
sudo perf record -a -F 99 -g -p $(pgrep -x mysqld)
采集整个进程生命周期,直到退出
sudo perf record -a -F 99 -g -- sbin/mysqld \
--defaults-file=/etc/percona-server.conf.d/mysqld.cnf --user=mysql
执行一条 sql,观察这条 sql 产生的 perf 事件
sudo perf record -a -F 99 -g -p $(pgrep -x mysqld) -- mysql -e "SELECT * FROM db.table"
样本处理
采样完成后,默认会在当前目录生成 perf.data 文件,以二进制格式存储了采样数据,我们需要将他转成火焰图工具能处理的文本格式
perf script > perf.script
可以观察 perf.script,里面是调用栈的文本格式
生成火焰图
stackcollapse-perf.pl perf.script | flamegraph.pl > flame.svg
如果报命令不存在的话,注意火焰图文件夹在 path 中
通过浏览器可以打开 svg 图,鼠标悬停能看到各区块大小

上图是执行select count(*) from t where data < 1000000
产生的火焰图,data 没有索引,总数据量 2800w。横向各区块为在采样时,被采集到正好在执行的样本数,区块越宽代表执行停留时间越长,越可能是性能瓶颈点。
比如图中的row_search_mvcc
函数,被采集到 242 个样本,占总样本数的 37.4%。点击之后可以看到被该函数调用的函数火焰图子图

结论
通过火焰图我们可以观察到 mysql 在内部到底在执行什么操作,以及各操作的耗时占比,形成直观感受,有助于开发者性能调优或者问题排查
参考:https://www.percona.com/blog/2019/11/20/profiling-software-using-perf-and-flame-graphs/




