PostgreSQL定位函数中最耗时的SQL_Hehuyi_In的博客-CSDN博客
前篇中介绍了一些常用的定位方法,最近又学到一个新方法——使用 plProfiler插件。由于安装和排错流程较复杂,将其单开一篇记录。
plProfiler插件使用C和python语言共同开发,可以收集PL/pgSQL语言(不支持SQL语言)的函数和存储过程的profile信息,并生成html报表。报表以火焰图形式展示函数调用堆栈、耗时占比,还可以查看函数中每个SQL的位置、执行次数、最长执行时间、总时间,清晰明了。
由于依赖于python环境,安装、排错较复杂,对python小白不友好。同时,它也并非旁路监控,必须要手动执行对应函数。
python环境准备
通常Linux环境默认都自带python,不过要注意版本,python 3.2版本以下会在后面踩坑。如果没有的话网上搜索一下怎么安装即可。
wget https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz
yum install python-setuptools
pip install configparser
pip install html # python 3.2及以上版本
pip install cgi # python 3.2以下版本
cd contrib/plprofiler
make install
cd python-plprofiler
python ./setup.py install
pip install psycopg2-binary
plprofiler --help
create extension plprofiler;
安装包中有一个自带的案例
cd /root/postgresql-14.0/contrib/plprofiler/examples/
vi prepdb.sh
# 修改db名,其他不用动
PGDATABASE=postgres
执行该脚本
./prepdb.sh
出于安全考虑,plprofiler命令行不提供 --password参数,如果有用户密码,需要配置~/.pgpass文件,或者在pg_hba.conf中配置信任本ip(因为plprofiler只能如果--host ip方式访问,不能通过local方式访问)。
注意应该加在md5那行前面,因为 pg_hba.conf 是匹配到就停止的。
plprofiler run --host=192.168.1.108 --port=5432 --user=postgres --dbname=postgres --command "SELECT tpcb(1, 2, 3, -42)" --output tmp.html
执行完会弹出以下报表配置内容,可以不改,直接保存退出
[current]
title = PL Profiler Report for current
tabstop = 8
svg_width = 1200
table_width = 80%
desc =PL Profiler Report for current
打开生成的tmp.html文件,以火焰图的形式展示
点击show可以查看函数内部执行情况
总的来说格式是最清晰的,适合复杂函数的分析。
安装和排错过程很坎坷,记录一下...
-bash-4.2$ make install
Makefile:26: ../../src/Makefile.global: No such file or directory
Makefile:27: /contrib/contrib-global.mk: No such file or directory
make: *** No rule to make target `/contrib/contrib-global.mk'. Stop.
解决方法:plprofiler 解压到 源码/contrib 目录下
报错1
[root@linux01 python-plprofiler]# python ./setup.py install
Traceback (most recent call last):
File "./setup.py", line 1, in
from setuptools import setup
ImportError: No module named setuptools
解决方法:yum install python-setuptools
报错2
[root@linux01 python-plprofiler]# python ./setup.py install
Couldn't find index page for 'configparser' (maybe misspelled?)
Scanning index of all packages (this may take a while)
Reading https://pypi.python.org/simple/
No local packages or download links found for configparser
error: Could not find suitable distribution for Requirement.parse('configparser')
解决方法:pip install configparser
[root@linux01 python-plprofiler]# plprofiler --help
Traceback (most recent call last):
...
File "/usr/lib/python2.7/site-packages/plprofiler_client-4.2-py2.7.egg/plprofiler/plprofiler_report.py", line 4, in
import html
ImportError: No module named html
解决方法:pip install html
-bash-4.2$ plprofiler run --command="select test_f();" --output=test_f.html
could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
解决方法:加上连接信息
plprofiler run --host=192.168.1.108 --port=5432 --user=postgres --dbname=postgres --command="select test_f();" --output=test_f.html
plprofiler run --host=192.168.1.108 --port=5432 --user=postgres --dbname=postgres --command="select test_f();" --output=test_f.html
fe_sendauth: no password supplied
解决方法:配置~/.pgpass文件,或者在pg_hba.conf中配置信任本ip(参考前面)
报错1
plprofiler run --host=192.168.1.108 --port=5432 --user=postgres --dbname=postgres --command="select test_f();" --output=test_f.html
Traceback (most recent call last):
File "/usr/bin/plprofiler", line 9, in
...
File "/usr/lib/python2.7/site-packages/plprofiler_client-4.2-py2.7.egg/plprofiler/plprofiler.py", line 403, in get_local_report_data
raise Exception("No profiling data found")
Exception: No profiling data found
原因:test_f 函数为sql语言编写(language sql)
解决方法:plprofiler 仅支持 plpgsql语言(LANGUAGE plpgsql)
报错2
plprofiler run --host=192.168.1.108 --port=5432 --user=postgres --dbname=postgres --command "SELECT tpcb(1, 2, 3, -42)" --output tmp.html
"/tmp/tmpGWSbI3.tmp.conf" 10L, 182C written
Traceback (most recent call last):
...
File "/usr/lib/python2.7/site-packages/plprofiler_client-4.2-py2.7.egg/plprofiler/plprofiler_report.py", line 21, in generate
self.out("%s " %(html.escape(config['title']), ))
AttributeError: 'module' object has no attribute 'escape'
原因:python版本过低(测试的版本为python 2.7),3.2及以上版本才可使用html.escape,旧版本使用cgi.escape
解决方法:修改报错的 /usr/lib/python2.7/site-packages/plprofiler_client-4.2-py2.7.egg/plprofiler/plprofiler_report.py 脚本,加入import cgi,并将html.escape替换为cgi.escape(共两处)
历经这么多报错,终于测试成功了,感人...
参考
PostgreSQL定位函数中最耗时的SQL_Hehuyi_In的博客-CSDN博客
在linux中安装pip_linux安装pip_黄瓜炒肉的博客-CSDN博客
plprofiler/installation.md at master · bigsql/plprofiler · GitHub
使用plprofiler分析PostgreSQL函数各语句的执行情况 - 墨天轮
PgSQL · 插件分析 · plProfiler