摘要:本文用來總結一些GaussDB(DWS)在實際應用過程當中,可能出現的各類做業排隊的狀況,以及出現排隊時,咱們應該怎麼去判斷是否正常,調整一些參數,讓資源分配與負載管理更符合當前的業務;或者在做業阻塞的時候,怎麼去處理這些狀況,讓業務馬上恢復正常。
數據庫系統的負載管理和資源管理,在整個系統中起着很重要的做用,好比不少用戶的業務壓力過大時,有時會致使鏈接數量被佔滿,有時會致使某種計算資源被佔滿,有時會致使存儲空間被佔滿,這些狀況都會致使整個集羣進入異常甚至不可用的狀態:正在執行的做業互相爭搶CPU,會致使你們都不能好好執行;大量做業執行時,佔用大量內存,很容易觸發到內存瓶頸,形成做業內存不可用問題,致使業務報錯等等。在不進行併發控制的狀況下,這些狀況都極可能會出現,影響到正常業務。數據庫
本文用來總結一些GaussDB(DWS)在實際應用過程當中,可能出現的各類做業排隊的狀況,以及出現排隊時,咱們應該怎麼去判斷是否正常,調整一些參數,讓資源分配與負載管理更符合當前的業務;或者在做業阻塞的時候,怎麼去處理這些狀況,讓業務馬上恢復正常。session
本文分爲如下幾個小節去介紹並解答以上問題:併發
DWS的負載管理分爲兩層,第一層爲cn的全局併發控制,第二層爲資源池級別的併發控制。在經過第一層控制的時候,會繼續向前走到第二層資源池控制,根據資源池當前的負載資源狀況決定做業繼續執行或者排隊。ssh
DWS併發控制邏輯示意圖以下:高併發
從本圖的邏輯咱們能夠看到,實際做業執行中,可能會在兩種隊列中排隊:post
一種是全局隊列(global queue),這種隊列不區分簡單和複雜做業,也不區分是DDL或者是普通語句,優化
一種是資源池隊列(resource pool queue),用戶下發的通常語句會根據資源消耗估算以及複雜程度在這裏進行判斷是否排隊。spa
在兩層隊列的過濾下,DWS會篩選出當前能執行的語句,使其正常運行,運行時也會受到其所屬資源池資源的限制(只能使用資源池配置的CPU、內存、IO配額)。線程
這裏介紹幾個經常使用視圖以及SQL語句,能夠迅速判斷目前的業務出現問題的緣由,受限根據如下視圖能夠看到目前的做業是否是在排隊,以後要迅速分析爲何在排隊,是由於負載管理各個參數配置問題,仍是由於正在執行的語句佔據了過多的資源致使的排隊。設計
經常使用語句:
#查詢當前執行時間最長的語句的排隊狀態,query_id(數據庫中做業的惟一標識),以及詳細的語句信息。 select coorname,usename, current_timestamp-query_start as duration, enqueue,query_id,query from pgxc_stat_activity where state='active' and usename <> 'Ruby' order by duration desc;
根據該語句能夠迅速判斷出哪些語句執行時間很長,是什麼樣的語句執行很慢以及該語句的query_id,便於迅速進入下一步排查。
執行結果以下:
上圖解說:圖中爲在沒有做業的狀況下查詢,能夠看到有幾個WLM的語句已經執行了不少,不過這兩個是內部常駐線程,因此不影響業務,也不會佔用鏈接數等數據庫資源。
其他的行能夠看到有bi用戶,在執行一些做業,時間大概1-6分鐘左右。
經常使用語句:
#查詢每一個用戶下的做業執行狀況,排隊狀況以及做業的複雜狀況和內存消耗狀況。 select usename,enqueue,datname,status,attribute,count(*),sum(statement_mem) from pg_session_wlmstat group by 3,1,2,4,5 order by 1,3,4,5 ;
執行結果以下:
上圖解說:
上圖中說明當前鏈接的cn中有用戶名爲usr1的用戶執行做業,而且在資源池上排隊(第一節介紹的resourcepool隊列),數據庫爲postgres,做業在排隊因此當前status爲pending狀態。
其餘字段包括做業的屬性和當前使用內存資源的總和狀況(根據該數值能夠看出是否由於內存資源不足而進入排隊狀態)。做業在排隊時候不涉及到資源消耗,所以可能沒有具體數值。
經常使用語句:
#在根據pgxc_stat_activity查詢到具體執行時間長的語句以後,能夠根據本視圖查詢: select * from pgxc_thread_wait_status where query_id = xxxxxxxx;
該語句能夠查看執行慢語句的阻塞點,語句卡住時,能夠經過該語句查看語句卡在了哪一個步驟。
舉例以下:
上圖能夠看到做業在wait io,此時能夠檢查下磁盤的讀寫速度是否,raid卡讀寫策略是否正常等等。
當出現排隊的時候,wait_status通常的狀態是waiting in ccn queue/waiting resourcepool queue等狀態。
通常當業務上發現任務阻塞時,能夠從後臺查詢部分語句排查目前的狀況,此時要先看下現象上是什麼狀況,通常併發控制有如下幾種現象,暫時先列出這麼多,後續繼續補充:
若是當前cn的活躍做業超過這個參數,會出現語句排隊的狀況,主要排隊狀況爲waiting in global queue,以下圖所示,下圖狀況中,max_active_statements=6。
如圖:圖中最下方的兩個做業,執行時間已經達到了11小時,可是仍然沒有執行完,後面還有未執行的語句在排隊。總體對於客戶來講就是數據庫已經hang死了,什麼做業都執行不出來。
排查步驟
show enable_dynamic_workload; //查看該參數目前是否爲打開狀態(2020年的版本都是默認打開)
經過鏈接cn 5001查詢視圖:
select * from pg_session_wlmstat where threadid = $query_id;
該視圖能夠看到某個語句使用了多大的內存,statement_mem字段能夠看到我這個語句是使用了1G,可是實際狀況中,1個語句使用幾十個語句的狀況不少。當一個或者幾個語句的內存達到整個集羣的整體可用內存上限,或者達到資源池上限的時候,就會使這些語句後面的語句開始排隊。資源不放,排隊不止。
應急處理:及時將卡住的語句terminate,釋放其佔用的資源,後續進行優化以後再執行,優化手段不少,包括計劃調優,analyze等操做,均可以免一個語句佔用太大內存,也能夠提高執行效率。
舉例:查詢pgxc_stat_activity時,語句的執行狀態以下:能夠看到,全部語句都在waiting in ccn queue,只有兩個語句在運行。此時集羣設置的max_active_statements是40,可是該用戶實際活躍數量只有2個。
舉例:查詢pgxc_stat_activity時,語句的執行狀態以下:能夠看到,全部語句都在waiting in ccn queue,只有兩個語句在運行。此時集羣設置的max_active_statements是40,可是該用戶實際活躍數量只有2個。
這個視圖能夠清晰看到做業是在哪裏排隊:
首先,上圖中有totalsize,這個就是整體可用的最大內存,freesize_limit:執行語句可用的最大內存,freesize:當前可用的最大內存。
因此能夠得出結論,此時不是在全局排隊,全局內存freesize足夠,那麼做業就是在資源池排隊,資源池排隊也會顯示waiting in ccn queue。
能夠經過界面或者後臺查看一下,這個用戶對應的租戶上,是否是作了內存資源限制:
查看租戶界面內存配置以下:
能夠看到圖中給這個租戶或者說給這個用戶所在的資源池配置了10%的內存配額,一共是2277MB,即2G左右。
所以這種場景下,內存資源只能知足當前兩個語句的執行,其他屬於該用戶的語句都會進行排隊。
舉例:以前某局點出現高併發DDL的狀況,該類高併發DDL在全局併發計數中會受到統計,佔用max_active_statements中的併發數量。
好比:max_active_statements=20,其中某用戶一直持續不停地下發DDL,此時在DWS設計ap場景並未涉及此類場景。會出現該20個併發設置廣泛被該用戶佔用的狀況,其餘用戶可能出現連不上的狀況。
這種場景下,即時再調大併發,也會再被該用戶的DDL語句佔用。
處理方案:
針對高併發DDL的不合理業務場景進行優化,好比把連續建立刪除臨時表的動做,改成對永久表的操做,此時就能夠極大幅度減小DDL併發數量,保證自身業務以及其他用戶業務的正常鏈接和運行。
用戶的做業分爲如下幾種,DDL/DML/以及常規查詢,在DWS的視角中,常規查詢有分爲簡單查詢和複雜查詢。
對於DWS的兩層管控,受到第一層管控的有DDL、start transaction、DML、常規查詢等,基本是全部語句,只有內部線程的語句(好比WLM線程)以及超級用戶權限的用戶執行的做業。
受到第二層管控的語句,主要是能夠從優化器獲取到具體執行計劃以及執行代價的語句。
除了DDL/start transaction 之類的語句,以及部分白名單語句,此類語句都是視爲基本不消耗資源,而且不會形成阻塞的語句。
針對目前的管控機制來講,能夠將單個用戶關聯到一個單獨的資源池,這個資源池不設置內存配置,只設置併發配置,達到進行做業管控的效果。
具體步驟及解釋以下:
1.在全部節點建立好控制組
gs_ssh -c "gs_cgroup -c -S class_a" gs_ssh -c "gs_cgroup -c -S class_a -G workload_a"
2.建立業務資源池(此時能夠同步設置max_dop參數,active_statements會限制複雜做業的併發數量,max_dop參數會限制簡單做業的併發數量)
create resource pool p1 with (control_group="class_a:workload_a"); alter resource pool p1 with (active_statements=10,mem_percent=0,max_dop=1);
3.關聯用戶與該資源池
ALTER USER testuser RESOURCE POOL 'p1';
併發管理的用處,主要是爲了防止用戶跑太多的做業,致使集羣負載過大,資源發生爭搶,系統不能穩定運行,會由於資源出現各類問題,CPU/內存/IO,哪個都是讓人頭疼的問題,併發控制也能夠同步控制某一個用戶的併發做業,避免由於一個用戶的做業數量太大,致使其餘用戶在使用數據庫的時候出現問題。
負載管理最主要的現象就是會出現做業排隊的狀況,排隊是否合理,是否由於不合理的參數配置致使大量的業務阻塞;或者配置正常,可是沒有達到上限就出現排隊,本文的主要目的就是解決此類問題,或者及時定界到是什麼緣由致使了阻塞。
實際使用過程當中,許多時候出現排隊的狀況,均可能和正在執行的語句有關,正在執行的語句佔用着這個位置,又執行不完,其他語句天然會排隊。所以咱們碰到語句大量阻塞的狀況,要迅速定界到是由於什麼而形成阻塞,怎麼樣能恢復正常使用。找到問題的語句後,要及時去將它作一些適當的調優,避免再次執行到這個語句,還會出現同樣的狀況。