PostgreSQL 函數調試、診斷、優化 auto_explain

PostgreSQL 函數調試 & auto_explain

作者

digoal

日期

2016-11-21

標簽

PostgreSQL , pldebugger , 函數調試 , auto_explain


背景

PostgreSQL的服務端編程能力比較強,不僅支持像java, R, python這種流行的編程語言,另外還內置了一個與Oracle plsql功能幾乎一致的plpgsql語言。

對于開發人員來說,有了語言還不夠的,調試是非常常見的需求。

所以PostgreSQL的函數語言怎么調試呢,使用pldebugger即可。

pldebugger的安裝

https://git.postgresql.org/gitweb/?p=pldebugger.git;a=summary

plpgsql調試方法

https://www.pgadmin.org/docs/1.22/debugger.html

除了函數的調試,還有函數內SQL的執行計劃如何觀測。

auto_explain

auto_explain 一個比較給力的模塊.

用于向日志輸出超出定義閾值執行時間的SQL的執行計劃。更強大的是可以選擇是否輸出內嵌SQL的執行計劃(如函數中的SQL).

auto_explain的輸出更詳細的解釋可以參考EXPLAIN的解釋。或者man EXPLAIN.

SYNOPSIS  EXPLAIN [ ( option [, ...] ) ] statement  EXPLAIN [ ANALYZE ] [ VERBOSE ] statement  where option can be one of:  ANALYZE [ boolean ]  VERBOSE [ boolean ]  COSTS [ boolean ]  BUFFERS [ boolean ]  FORMAT { TEXT | XML | JSON | YAML }  

開啟方式有兩種 :

1. 通過配置文件postgresql.conf

需要重啟數據庫。

2. 通過LOAD 'auto_explain';

這個只在當前SESSION生效,不需要重啟數據庫, 需要超級用戶權限。

其實還可以設置local_preload_libraries,session_preload_libraries參數來啟用。

例子

1. 修改配置文件:

shared_preload_libraries = 'auto_explain'  

新增如下配置:

auto_explain.log_min_duration = 0  # 為了方便查看,這里把時間設置為0,所有SQL都會被auto_explain捕獲輸出.實際使用的時候適當調大。如 100ms  
auto_explain.log_analyze = true  # 以下可選  
auto_explain.log_verbose = true  
auto_explain.log_buffers = true  
auto_explain.log_nested_statements = true  

然后重啟數據庫.重啟時會輸出一個LOG

postgres@db5-> LOG:  loaded library "$libdir/auto_explain.so"  

下面來執行幾條SQL

postgres@db5-> psql -h 127.0.0.1 digoal digoal  
psql (9.1beta1)  
Type "help" for help.  digoal=> select * from tbl_user_info limit 2;  id | firstname | lastname |   corp     
----+-----------+----------+----------  1 | zhou1     | digoal1  | sky-mobi  2 | zhou2     | digoal2  | sky-mobi  
(2 rows)  digoal=> select count(*) from tbl_test;  count    
---------  1000100  
(1 row)  

日志輸出

2011-06-08 15:19:14.390 CST,"digoal","digoal",13789,"127.0.0.1:59549",4def2270.35dd,1,"SELECT",2011-06-08 15:19:12 CST,2/18,0,LOG,00  
000,"duration: 0.040 ms  plan:  
Query Text: select * from tbl_user_info limit 2;  
Limit  (cost=0.00..0.04 rows=2 width=31) (actual time=0.020..0.023 rows=2 loops=1)  Output: id, firstname, lastname, corp  Buffers: shared hit=1  ->  Seq Scan on public.tbl_user_info  (cost=0.00..183.00 rows=10000 width=31) (actual time=0.014..0.015 rows=2 loops=1)  Output: id, firstname, lastname, corp  Buffers: shared hit=1",,,,,,,,,"psql"  
2011-06-08 15:19:17.902 CST,"digoal","digoal",13789,"127.0.0.1:59549",4def2270.35dd,2,"SELECT",2011-06-08 15:19:12 CST,2/19,0,LOG,00  
000,"duration: 1232.064 ms  plan:  
Query Text: select count(*) from tbl_test;  
Aggregate  (cost=16927.25..16927.26 rows=1 width=0) (actual time=1232.044..1232.045 rows=1 loops=1)  Output: count(*)  Buffers: shared hit=4426  ->  Seq Scan on public.tbl_test  (cost=0.00..14427.00 rows=1000100 width=0) (actual time=0.015..626.872 rows=1000100 loops=1)  Output: id  Buffers: shared hit=4426",,,,,,,,,"psql"  

2. 通過LOAD 'auto_explain' ;

這個只在當前SESSION生效,不需要重啟數據庫, 需要超級用戶權限。

首先先恢復postgresql.conf的配置,去除前面的配置.然后重啟數據庫.

普通用戶不允許加載auto_explain模塊.(普通用戶只允許加載$libdir/plugins目錄下的模塊,但是auto_explain即使拷貝到這個目錄也不行)

digoal=> load 'auto_explain';  
ERROR:  access to library "auto_explain" is not allowed  
digoal=> \c digoal postgres  
You are now connected to database "digoal" as user "postgres".  
digoal=# load 'auto_explain';  
LOAD  
digoal=# set auto_explain.log_min_duration=0;  
SET  
digoal=# select * from tbl_user_info limit 2;  id | firstname | lastname |   corp     
----+-----------+----------+----------  1 | zhou1     | digoal1  | sky-mobi  2 | zhou2     | digoal2  | sky-mobi  
(2 rows)  

查看日志

2011-06-08 15:25:33.361 CST,"postgres","digoal",13968,"127.0.0.1:15445",4def23d5.3690,1,"SELECT",2011-06-08 15:25:09 CST,2/9,0,LOG,0  
0000,"duration: 0.048 ms  plan:  
Query Text: select * from tbl_user_info limit 2;  
Limit  (cost=0.00..0.04 rows=2 width=31)  ->  Seq Scan on tbl_user_info  (cost=0.00..183.00 rows=10000 width=31)",,,,,,,,,"psql"  

連接到digoal用戶,這個LOAD的模塊消失(后面會有解釋).

digoal=# load 'auto_explain';  
LOAD  
digoal=# set session auto_explain.log_min_duration=0;  
SET  
digoal=# \c digoal digoal  
You are now connected to database "digoal" as user "digoal".  
digoal=> select * from tbl_user_info limit 3;  id | firstname | lastname |   corp     
----+-----------+----------+----------  1 | zhou1     | digoal1  | sky-mobi  2 | zhou2     | digoal2  | sky-mobi  3 | zhou3     | digoal3  | sky-mobi  
(3 rows)  

查看日志,沒有auto_explain的輸出.即使這里使用了session來定義這個參數的有效范圍。

原因是session重新分配了,因為\c digoal digoal 相當于重新連接,backend也重新生成,如下.

digoal=> select * from pg_stat_activity;  datid | datname | procpid | usesysid | usename | application_name | client_addr | client_hostname | client_port |         backend_s  
tart         |          xact_start           |          query_start          | waiting |          current_query            
-------+---------+---------+----------+---------+------------------+-------------+-----------------+-------------+------------------  
-------------+-------------------------------+-------------------------------+---------+---------------------------------  16430 | digoal  |   14155 |    16423 | digoal  | psql             | 127.0.0.1   |                 |        5959 | 2011-06-08 15:31:  
32.794906+08 | 2011-06-08 15:31:40.616346+08 | 2011-06-08 15:31:40.616346+08 | f       | select * from pg_stat_activity;  
(1 row)  digoal=> \c digoal postgres  
You are now connected to database "digoal" as user "postgres".  
digoal=# select * from pg_stat_activity;  datid | datname | procpid | usesysid | usename  | application_name | client_addr | client_hostname | client_port |         backend_  
start         |          xact_start           |          query_start          | waiting |          current_query            
-------+---------+---------+----------+----------+------------------+-------------+-----------------+-------------+-----------------  
--------------+-------------------------------+-------------------------------+---------+---------------------------------  16430 | digoal  |   14161 |       10 | postgres | psql             | 127.0.0.1   |                 |        5961 | 2011-06-08 15:31  
:43.937297+08 | 2011-06-08 15:31:45.178005+08 | 2011-06-08 15:31:45.178005+08 | f       | select * from pg_stat_activity;  
(1 row)  

那么如何避免這樣的情況發生呢? 答案是使用set role .

digoal=# load 'auto_explain';  
LOAD  
digoal=# set session auto_explain.log_min_duration=0;  
SET  
digoal=# set role digoal;  
SET  
digoal=> select * from tbl_user_info limit 3;  id | firstname | lastname |   corp     
----+-----------+----------+----------  1 | zhou1     | digoal1  | sky-mobi  2 | zhou2     | digoal2  | sky-mobi  3 | zhou3     | digoal3  | sky-mobi  
(3 rows) 

再看日志,已經有了 :

2011-06-08 15:29:30.011 CST,"postgres","digoal",14062,"127.0.0.1:5939",4def24bc.36ee,1,"SELECT",2011-06-08 15:29:00 CST,2/29,0,LOG,0  
0000,"duration: 0.031 ms  plan:  
Query Text: select * from tbl_user_info limit 3;  
Limit  (cost=0.00..0.05 rows=3 width=31)  ->  Seq Scan on tbl_user_info  (cost=0.00..183.00 rows=10000 width=31)",,,,,,,,,"psql"  

如果你不想看日志這么麻煩,想在client直接顯示,也很方便,設置client_min_messages='log'就可以看到auto explain的輸出了。

set client_min_messages='log';
set auto_explain.log_min_duration = 0;
set auto_explain.log_analyze = true;
set auto_explain.log_verbose = true;
set auto_explain.log_buffers = true;
set auto_explain.log_nested_statements = true;postgres=# do language plpgsql $$        
declare
begin
perform 1 from pg_class where oid=1;
end;
$$;LOG:  duration: 0.008 ms  plan:
Query Text: SELECT 1 from pg_class where oid=1
Index Only Scan using pg_class_oid_index on pg_catalog.pg_class  (cost=0.27..1.29 rows=1 width=4) (actual time=0.006..0.006 rows=0 loops=1)Output: 1Index Cond: (pg_class.oid = '1'::oid)Heap Fetches: 0Buffers: shared hit=2
DO

參考

1. man LOAD

2. man EXPLAIN

3.?http://www.postgresql.org/docs/9.6/static/auto-explain.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/397335.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/397335.shtml
英文地址,請注明出處:http://en.pswp.cn/news/397335.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

判斷請求來自手機還是PC

由于小程序和PC端用的是同一個后臺 所以就需要判斷請求是從哪里發過來的 在這里是利用Request Body 里面的user-agent 來判斷 /** * 根據當前請求的特征,判斷該請求是否來自手機終端,主要檢測特殊的頭信息,以及user-Agent這個header * * pa…

小旭的互聯網營銷之微信營銷

11月1日,一篇題為《什么樣的女黑客竟遭馬云強東在雙11聯手封殺?》的文章,借助雙11火熱的關注效應,在短短兩天時間內刷爆朋友圈。 該文章的女主角不僅外表靚麗,黑客技術更是驚艷:“作為美籍華人的Joanna在2015黑帽子會…

計算機專業錄取分數及大學排名,計算機專業錄取分數最高的大學有哪些?附排名前50大學名單...

高考結束之后,不少即將迎接高考的家長對于很多專業的錄取情況都抱有很大的興趣,都比較關心自己的理想專業大概能上哪些大學。今天,小編將為大家以山東高考計算機專業各大學錄取分數進行排名,供下一屆高考生參考。計算機專業作為近…

letsencrypt 自動續期不關閉nginx

為什么80%的碼農都做不了架構師&#xff1f;>>> 已失效 corntab -e 5 0 1 * * /opt/letsencrypt/letsencrypt-auto --config /etc/letsencrypt/webroot.ini -d <domain> certonly && sudo service nginx reload/etc/letsencrypt/webroot.ini rsa-key…

loss低但精確度低_低光照圖像增強網絡-RetinexNet(model.py解析【2】)

論文地址&#xff1a;https://arxiv.org/pdf/1808.04560.pdf代碼地址&#xff1a;https://github.com/weichen582/RetinexNet解析目錄&#xff1a;https://zhuanlan.zhihu.com/p/88761829整個模型架構被實現為一個類&#xff1a;class lowlight_enhance(object):其構造函數實現…

計算機應用發表論文,計算機應用論文發表.docx

計算機應用論文發表1在工程項目管理中應用計算機技術存在的問題計算機軟件是計算機運行的重要保障&#xff0c;一個好的計算機軟件直接決定計算機技術在工程項目管理的高效應用。但由于市場上計算機軟件種類繁多&#xff0c;質量好壞不一&#xff0c;質量好的價格高&#xff0c…

添加dubbo xsd的支持

使用dubbo時遇到問題&#xff1a; org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document http://code.alibabatech.com/schema/dubbo/dubbo.xsd, because 1) could not find the document; 2) the document could not be read; 3) the root ele…

byte數組穿換成pcm格式_形象地介紹DSD的編解碼原理及和PCM的區別

一直有人不清楚DSD到底是啥原理&#xff0c;和MP3, FLAC, APE, WAV等基于PCM編碼技術的音頻格式又有啥區別。特意做了兩張圖說明一下。圖一是是由很多黑點構成的蒙娜麗莎頭像&#xff0c;點擊看大圖就知道是沒有灰階只有黑白兩色。但是人眼是可以看到有豐富的灰階的。這和DSD一…

最大熵對應的概率分布

最大熵對應的概率分布 最大熵定理 設 \(X \sim p(x)\) 是一個連續型隨機變量&#xff0c;其微分熵定義為\[ h(X) - \int p(x)\log p(x) dx \]其中&#xff0c;\(\log\) 一般取自然對數 \(\ln\), 單位為 奈特&#xff08;nats&#xff09;。 考慮如下優化問題&#xff1a;\[ \b…

UBUNTU : Destination Host Unreachable

介紹我的系統的搭建的方式: WIN7 64 VMWARE STATION&#xff0c;方式是進行橋接的方式。最近突然出現了問題&#xff0c;Ubuntu ping 外網或者 PING WIN 7 的時候&#xff0c;出現 Destination Host Unreachable 的錯誤&#xff1b;想著去修改網卡的鏈接形式&#xff1a; 編輯…

焦作師范高等專科學校對口計算機分數線,焦作師范高等專科學校錄取分數線2018...

焦作師范高等專科學校錄取分數線20182018年 電子信息工程技術 理科 332 3602018年 物聯網應用技術 文科 391 4082018年 物聯網應用技術 理科 328 3692018年 學前教育 文科 388 4022018年 學前教育 理科 324 3512018年 移動應用開發 文科 02018年 移動應用開發 理科 305 3322018…

在Spring boot 配置過濾器(filter)

在spring boot 配置servlet filter 邏輯上與配置spring 是一樣的。 不過相比spring 更加簡化配置的難度。 這里只需要兩步1 創建一個自定義顧慮器并繼承spring filter 例如OncePerRequestFilterpublic class AuthenticationFilter extends OncePerRequestFilter{private final …

Flink之狀態之狀態存儲 state backends

流計算中可能有各種方式來保存狀態&#xff1a; 窗口操作使用 了KV操作的函數繼承了CheckpointedFunction的函數當開始做checkpointing的時候&#xff0c;狀態會被持久化到checkpoints里來規避數據丟失和狀態恢復。選擇的狀態存儲策略不同&#xff0c;會導致狀態持久化如何和ch…

怎么把分開的pdf放在一起_糖和鹽混在一起了要怎么分開?| 趣問萬物

趣 問 萬 物來源&#xff1a;把科學帶回家撰文&#xff1a;Mirror如何分離糖和鹽&#xff1f;圖源&#xff1a;Pixabay小手一抖&#xff0c;不小心把糖(蔗糖)和鹽(氯化鈉)混在一塊兒了該怎么辦&#xff1f;趁著光棍節&#xff0c;就讓我們吃飽了撐著研究研究把糖和鹽拆散的N種方…

《JavaScript DOM編程藝術》筆記

1. 把<script>標簽放到HTML文檔的最后&#xff0c;<body>標簽之前能使瀏覽器更快地加載頁面。 2. nodeType的常見取值 元素節點(1) 屬性節點(2) 文本節點(3) 3. <a href"http://www.baidu.com" οnclick"popUp(this.href);return false;"&g…

maven POM.xml內的標簽大全詳解

<project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd"><!--父項目的坐標。如果…

常熟理工學院計算機考研,2018江蘇專轉本考生必看-常熟理工學院介紹

原標題&#xff1a;2018江蘇專轉本考生必看-常熟理工學院介紹這次輪到默默學介紹常熟理工學院啦&#xff01;今年常熟理工學院有個專轉本的學生&#xff0c;也是默默學專轉本視頻課程考上常熟理工的一個學生&#xff0c;叫黃群超&#xff0c;當年專轉本計算機也考了八九十分吧&…

.net中調用esb_大型ESB服務總線平臺服務運行分析和監控預警實踐

今天準備談下ESB總線平臺建設項目中的服務運行統計分析&#xff0c;服務心跳監測&#xff0c;服務監控預警方面的設計和實現。可以看到&#xff0c;在一個ESB服務總線平臺上線后&#xff0c;SOA治理管控就變得相當重要&#xff0c;而這些運行監控分析本身也是提升ESB總線平臺高…

使用Maven創建Web項目后,jsp引入靜態文件提示報錯。JSP 報錯:javax.servlet.ServletException cannot be resolved to a type...

用maven創建多模塊的web工程后&#xff0c;不同于直接創建普通的web工程。 1、在普通的web工程創建后&#xff0c;在項目中會有tomcat等服務器的jar包&#xff0c;這時創建JSP文件肯定是沒有錯的&#xff1b; 2、即使是使用maven創建的單模塊的web工程&#xff0c;也會自動的在…

ES6之路第十三篇:Iterator和for...of循環

Iterator(遍歷器)的概念 JavaScript 原有的表示“集合”的數據結構&#xff0c;主要是數組&#xff08;Array&#xff09;和對象&#xff08;Object&#xff09;&#xff0c;ES6 又添加了Map和Set。這樣就有了四種數據集合&#xff0c;用戶還可以組合使用它們&#xff0c;定義自…