【Greenplum常見問題】 「個人SQL卡住了怎麼辦?」

你們好,我是Pivotal Greenplum團隊的一名售後工程師。平時會幫助咱們的全球的商業用戶解決數據庫的相關的問題。在實際工做中,咱們常常會被數據庫管理員問及:「個人SQL跑了很長時間沒有結果,我該怎麼樣排查?」 「數據庫某一條SQL卡住了怎麼辦?」 今天,咱們將就這個內容作一些分析和總結。

通常來講,SQL卡住或者運行時間長這類常見問題的緣由以下:sql

  • SQL由於死鎖緣由,並無執行
  • SQL由於Resource Queue或者Resource Group沒有資源而等待
  • SQL由於在某一個segment或者某個機器的問題而卡住

針對問題1 和 問題2,在Greenplum中,咱們能夠經過查詢pg_locks表和gp_toolkit/GPCC中資源隊列/組的狀態來排查。
而問題3,每每是很是棘手又不得不解決的.下面咱們將詳細介紹在排除了死鎖和資源組/隊列問題後,SQL仍然長時間沒有返回結果的排查方法。
首先,咱們須要經過以下語句肯定SQL的 Session ID也叫Connection ID。好比咱們數據庫中有一個truncate 語句長時間沒有返回結果,咱們能夠經過下面語句肯定SessionIDshell

gpadmin=# SELECT * from pg_stat_activity where upper(current_query) like '%TRUNCATE%'; datid | datname | procpid | sess_id | usesysid | usename |                              current_query | waiting |        query_start | backend_start | client_addr | client_port | application_name |        xact_start | waiting_reason | rsgid | rsgname | rsgqueueduration
-------+---------+---------+---------+----------+---------+------------------------------------------------------------------------------+---------+-------------------------------+-------------------------------+-------------+-------------+------------------+-------------------------------+----------------+-------+---------+------------------ 
16384 | gpadmin |   15103 | 310 |     10 | gpadmin | TRUNCATE aoco;                                                             | t | 2019-11-12 00:24:56.017908-05 | 2019-11-12 00:24:47.147582-05 | |     -1 | psql | 2019-11-12 00:24:56.017908-05 | lock | 0 | unknown | 16384 | gpadmin |   15218 | 91014 |   10 | gpadmin | SELECT * from pg_stat_activity where upper(current_query) like '%TRUNCATE%'; | f     | 2019-11-12 00:28:06.973462-05 | 2019-11-12 00:24:58.490902-05 | | -1 | psql       | 2019-11-12 00:28:06.973462-05 | | 0 | unknown 
|(2 rows)

上面輸出顯示的sess_id是310。緊接着, 咱們要經過gpssh 工具來檢查每一個segment的進程執行情況:
$ gpssh -f <hostfile> 'ps -ef | grep con<sess_id> | grep -v idle' 
注:這裏的con<sess_id> 就是對應sessionID 310 就是con310
這裏咱們排除了idle的進程,由於idle進程是處理完本身Slice當時分配任務的進程,咱們無需關心。經過上面gpssh命令的輸出,咱們就對全部這個SQL的對應進程在greenplum上的執行情況有個大體的瞭解。數據庫

  • 好比說SQL只在一個segment進程上有非idle的狀況,那麼咱們只要着重查看這個segment情況便可。可能引發這樣情況的緣由最多見的情況就是data Skew;就是這個SQL對應表可能有分佈不均的狀況,也有多是咱們的SQL join的鍵值緣由致使的SQL處理過程當中的分佈不均。
  • 假如說這個SQL的對應進程只在一個機器上有非idle的情況,那麼咱們能夠着重關注一下這臺機器對應的硬件是否有問題。最多見的就是磁盤的問題。是否磁盤的讀寫率一直很高在100%?是否其餘SQL在這臺機器上也有卡住的情況?
  • 若是咱們在全部的機器上看到這個SQL的進程都是分佈很均勻的,那麼頗有可能這個SQL自己處理的數據量發生了變化,因此時間變長。還有一種最很差的可能性,就是由於咱們這個SQL不能被Greenplum的優化器很好的識別,因此很慢。

無論針對上面的任何的狀況,strace和pstack這兩個工具均可以幫助咱們理解在進程級別這些SQL都作了什麼動做。因此,咱們建議全部的機器都要裝這兩個工具。(另外,針對狀況2的磁盤問題,咱們建議iotop工具來甄別那個進程用的磁盤資源較多)
Strace是一個動態追蹤進程系統調用的工具(進程跟操做系統內核的交互),咱們能夠直接使用strace -p 這個命令直接查看,也能夠用以下命令:
strace -T -f -ff -y -yy -p
根據咱們的經驗,這個strace的參數組合的能夠更好的輸出可讀性更好的結果。Strace 是一個在順着時間動態追蹤的工具,而pstack能夠縱向打印出來某個肯定時間點上進程的Call Stack 信息。Call Stack 可讓咱們知道進程在某個具體時間點某個進程究竟在作什麼事情。好比:數組

[root@bdlgpscprd07 gpadmin]# pstack 6495
Thread 2 (Thread 0x7f442920e700 (LWP 6504)):
#0 0x00007f4424e2d043 in poll () from /lib64/libc.so.6
#1 0x0000000000bc1ac4 in rxThreadFunc ()
#2 0x00007f442588f9d1 in start_thread () from /lib64/libpthread.so.0
#3 0x00007f4424e3686d in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7f44293d2720 (LWP 6495)):
#0 0x00007f4424e2f2e3 in select () from /lib64/libc.so.6
#1 0x00000000008e1cfa in sendSequenceRequest ()
#2 0x00000000006ee69d in nextval_oid ()
#3 0x0000000000759606 in ExecMakeFunctionResultNoSets ()
#4 0x000000000075e662 in ExecProject ()
#5 0x0000000000784727 in ExecHashJoin ()
#6 0x0000000000757d64 in ExecProcNode ()
#7 0x000000000078f249 in SubqueryNext ()
#8 0x0000000000762d5b in ExecScan ()
#9 0x0000000000757c09 in ExecProcNode ()
#10 0x0000000000798b0a in ExecMotion ()
#11 0x0000000000757b66 in ExecProcNode ()
#12 0x000000000074d5bc in ExecutePlan ()
#13 0x000000000074dd76 in ExecutorRun ()
#14 0x000000000099d634 in ProcessQuery ()
#15 0x00000000009a0050 in PortalRun ()
#16 0x0000000000995dc0 in exec_mpp_query ()
#17 0x0000000000999c95 in PostgresMain ()
#18 0x00000000008f6e3e in ServerLoop ()
#19 0x00000000008f9ae0 in PostmasterMain ()
#20 0x00000000007fb13f in main ()

從上面這個callstack中咱們能夠看到這個進程在執行一個Hashjoin.因此若是看到全部的進程都是這個地方比較慢,咱們能夠嘗試考慮對應的hashjoin是否有問題。(更加具體的分析可能須要結合代碼) 網絡

針對pstack,咱們能夠用一個簡單的shell腳本沒20秒鐘打印出一次,去更好的理解進程的工做情況,每20秒的工做情況。
$ while true; do date; pstack <pid>; sleep 20; done;
在運用了strace和pstack以後咱們會對問題有個大體的判斷。好比磁盤操做比較慢,好比大部分進程是在等待網絡上的數據,等等。可是若是pstack和stace後,咱們仍然沒法對問題有一個深刻的瞭解,對於商業用戶,能夠經過聯絡Pivotal技術支持獲取幫助。(注:若是問題能夠在您的環境重現問題,那麼將極大的幫助Pivotal 技術支持定位問題)。那麼,咱們怎麼樣幫助Pivotal 技術支持收集相關信息呢?
Pivotal 技術支持已經開發了gpmt analyze_session tool來幫助商業用戶收集SQL卡住的對應信息:
GPMT是一個很是好的收集日誌的工具,也很是建議你們在環境中安裝。另外,若是問題能夠連續復現,咱們建議您使用mini-repro來收集對應SQL的DDL和統計信息。這個咱們在以前的文章也有過度享過收集日誌的步驟,詳情請查看連接。session

今天的分享就到這裏,很是感謝你們的關注,請你們繼續關注咱們的文章系列。若是有任何問題,能夠給咱們留言,商業用戶能夠經過Pivotal 技術支持與咱們保持聯絡!app


關於做者:ssh

姜天旭(Alex Jiang), Pivotal 技術支持中心售後支持專家。做者曾就任於EMC、埃森哲、愛立信等知名公司。有多年的數據庫相關經驗,熟悉Greenplum、PostgreSQL。 工具

相關文章
相關標籤/搜索