Oracle并行基礎(chǔ)二

Oracle并行基礎(chǔ)(連載二)

作者:沃趣科技高級數(shù)據(jù)庫技術(shù)專家 魏興華

專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站制作服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)突泉免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上1000家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。


消費者生產(chǎn)者模型的限制

根據(jù)上面的介紹,你已經(jīng)知道了,一個并行操作內(nèi)一般會具有兩組PX slave進程,一組為生產(chǎn)者,一組為消費者。生產(chǎn)者通過table queue發(fā)送數(shù)據(jù),消費者通過table queue接收數(shù)據(jù)。而且對于消費者和生產(chǎn)者模型,有一個很大的限制是:一組DFO單元最多只能有兩組PX slave進程,之所以有這個限制,一方面可能是Oracle公司為了保持并行代碼的簡潔性,一方面由于每個PX slave進程之間和每個PX slave與QC之間都要維持一個通信通道(table queue)用于傳遞消息和數(shù)據(jù),如果允許的PX slave有太多組,可能會導(dǎo)致通信通道指數(shù)級增長。例如一個DOP為5的并行操作,PX slave之間需要的通道數(shù)為55,PX slave與QC之間的通道數(shù)為25,共需要(5+2)5=35個通道??上攵?,如果Oracle允許一個并行操作內(nèi)有3組PX slave,需要維持的連接數(shù)有多少,我們假設(shè)當(dāng)前服務(wù)器共運行了50個并行,那么三組PX slave進程產(chǎn)生的通道數(shù)為5050*50=125000個,還不包括PX slave與QC之間的通道,嚇尿了不?

parallel_execution_message_size

如果進程之間傳遞消息的通道數(shù)多但不占用數(shù)據(jù)庫資源可能也并不是什么大的問題,但是事實不是這樣的,進程之間傳遞消息的通道的內(nèi)存占用大小是由參數(shù)parallel_execution_message_size控制的,在11GR2版本這個參數(shù)的值為16K,在以前的各個版本這個參數(shù)的值可能大小并不一樣(每個版本都有增大的趨勢),在非RAC環(huán)境下,每個通道的大小最大可以為3parallel_execution_message_size,在RAC環(huán)境下,每個通道的大小最大可以為4parallel_execution_message_size。
例如一個DOP為20的查詢,非rac環(huán)境下通道所占用的內(nèi)存最大可能為:
PX進程的通道內(nèi)存+QC、PX進程之間的通道內(nèi)存=202016K3+22016K3=21120K,接近21M的內(nèi)存。
通道的內(nèi)存默認(rèn)是在large pool中分配,如果沒有配置large pool則在shared pool中分配。
計算通道內(nèi)存的公式:
單節(jié)點
(NN+2N)316k
RAC節(jié)點
(NN+2N)416k

hash join buffered

其實不是hash join的缺陷。
我們已經(jīng)介紹過生產(chǎn)者消費者模型,它有一個很大“缺陷”是,一個并行操作內(nèi),最多只能有2組PX slave,2組PX slave通過table queue來傳遞消息和交互數(shù)據(jù),因此在一組SLAVE在讀table queue的時候,不能同時去寫另一個table queue。是不是不太好理解?
我們通過一個例子來進行描述:

select /*+ parallel(6) pq_distribute(b hash hash)*/ * from hash_t3 a ,hash_t1 b where a.id=b.id;

 Oracle并行基礎(chǔ)二

  這個例子里我通過hint pq_distribute(b hash hash)強行讓數(shù)據(jù)以hash方式進行分發(fā),關(guān)注行源ID為3的操作,出現(xiàn)很陌生的一個操作:hash join buffered,不要被這個buffered名字所迷惑,它代表著數(shù)據(jù)暫時不能向上流動,必須先暫時存放在這里,語句的執(zhí)行順序是這樣的:

  • 首先紅色的生產(chǎn)者PX slave掃描hash_t3表,并對掃描的記錄按照HASH分發(fā)方式把相關(guān)記錄寫入table queue TQ10000

  • 藍色的消費者PX slave從table queue TQ10000接收數(shù)據(jù)并構(gòu)建hash table。

  • 上面操作結(jié)束后,紅色的生產(chǎn)者繼續(xù)掃描hash_t1表,并對掃描的記錄按照HASH分發(fā)方式寫入table queue TQ10001

  • 藍色的消費者PX slave從table queue TQ10001接收數(shù)據(jù),并與上面的HASH TABLE做探測,但是結(jié)果并不能寫入table queue TQ10002,而是先暫時緩存起來(hash join buffered的由來)

  • 等HASH分發(fā)完成之后(也就是這兩組PX slave不活躍以后),然后由一組PX slave把結(jié)果集通過table queue TQ10002發(fā)送給QC。

為什么要這樣?貌似是沒有道理的。
這就是因為hash分發(fā)要求對hash join的右邊也要進行分發(fā),分發(fā)操作涉及了2組PX slave進程,一組負責(zé)掃描,一組負責(zé)接收數(shù)據(jù),也就是一組PX slave把掃描的數(shù)據(jù)寫入table queue,一組負責(zé)從table queue讀取數(shù)據(jù),這個時候不能 再進行數(shù)據(jù)的分發(fā)操作,因為join的結(jié)果集不能寫入另一個table queue TQ10002。
如果結(jié)果集較大的話,這個可能在一定程度上會導(dǎo)致消耗很多臨時表空間,導(dǎo)致大量的磁盤讀寫IO,進而引起性能降低。
如果確實產(chǎn)生了這種情況,可以通過改用broadcast分發(fā)來避免出現(xiàn)這種情況,因為broadcast分發(fā)對于hash join的右邊并不需要進行分發(fā)

select /*+ parallel(6) pq_distribute(b broadcast none)*/ * from hash_t3 a ,hash_t1 b where a.id=b.id;

 Oracle并行基礎(chǔ)二

例如改成broadcast后,hash join buffered操作已經(jīng)消失了。

布隆過濾

我們有必要介紹一下布隆過濾,它在11GR2之后版本的并行里有非常大的作用。bloom filter并非Oracle的發(fā)明,bloom filter技術(shù)出現(xiàn)的時候Oracle軟件還未誕生,它在1970年由Burton H.Bloom開發(fā)出來,布隆過濾到什么?
布隆過濾或者說布隆過濾器,是一種數(shù)據(jù)結(jié)構(gòu),它能夠快速的判斷一個數(shù)據(jù)是否屬于一個集合,hash join本身是非常消耗資源的,也是非常慢的,布隆過濾比hash join快很多。

關(guān)于布隆過濾的詳細介紹請參照:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html

 Oracle并行基礎(chǔ)二

布隆過濾器基于一個有M位的數(shù)組,例如上圖數(shù)組的大小有18位,初始化的時候全部的值都為0,如果要理解布隆過濾是如何工作的,必須要知道在什么情況下,這些標(biāo)志位需要置為1,上圖中{X,Y,Z}代表著一個集合,這個集合有3個值(元素),仔細觀察每一個值都延伸出了三個線,在這里代表著每一個值都經(jīng)過3個HASH函數(shù)計算,計算出來的值的范圍是從0-17(數(shù)組的長度),例如,X經(jīng)過3次HASH函數(shù)計算,值分別為:1,3,13,然后對應(yīng)的標(biāo)志位被置為1,Y,Z同理把相應(yīng)的標(biāo)志位置為1。經(jīng)過一番HASH計算,{X,Y,Z}集合的所有元素都已經(jīng)經(jīng)過了HASH計算,對應(yīng)的標(biāo)志位也都置為了1,然后我們再探測另一個集合,這里另一個集合的元素為W,W同樣需要經(jīng)過相同的3個HASH函數(shù)計算,并且檢測對應(yīng)的位置是否為1,如果對應(yīng)的位置都為一,那么W可能(僅僅是可能)屬于這個集合,如果有任何的位置不為1,那么這個W一定不屬于這個集合。由于布隆過濾并不對值進行精確的匹配(而HASH JOIN是需要精確匹配的),因此可能會有一些不該屬于集合的值穿越了布隆過濾器。

布隆過濾器有如下特點:

  • 構(gòu)建布隆過濾數(shù)組要求的內(nèi)存非常小,經(jīng)常可以完全放入在CPU的cache中。當(dāng)然布隆過濾的數(shù)組越大,布隆過濾誤判的可能性也就越小。

  • 由于不需要精確匹配,因此布隆過濾的速度非常的快,但是有一些不該出現(xiàn)的值可能會穿越布隆過濾器。

 Oracle并行基礎(chǔ)二

PX Deq Credit: send blkd 與PX Deq Credit: need buffer

布隆過濾有啥用呢?也許你是一位有著豐富經(jīng)驗的老DBA,那么你對PX Deq Credit: send blkd 、PX Deq Credit: need buffer等待事件也許就比較熟悉。經(jīng)過上面的介紹,我們已經(jīng)具備了很多的知識,table queue,生產(chǎn)者消費者模型等等,一組消費者PX slave寫入table queue,另一組通過讀取table queue來獲取數(shù)據(jù),完成進程間數(shù)據(jù)的傳遞,但是一定會出現(xiàn)一種情況,當(dāng)一組生產(chǎn)者PX slave在往table queue中寫入數(shù)據(jù)的時候,發(fā)現(xiàn)table que中的內(nèi)存已經(jīng)滿了,沒有剩余內(nèi)存可以寫了,這種情況大部分時候都意味著消費者PX slave從table queue中消費數(shù)據(jù)過慢,過慢最大可能原因是由于消費者不得不把table queue中讀取到的數(shù)據(jù)溢出到磁盤,從內(nèi)存讀取數(shù)據(jù)寫入磁盤是個很慢的操作,因此在這種情況下,就會遭遇PX Deq Credit: send blkd 、PX Deq Credit: need buffer等待,如何優(yōu)化?這種情況下,布隆過濾就發(fā)揮了作用。
如果優(yōu)化器認(rèn)為表X返回1000條記錄,表Y需要掃描一億條記錄,但是經(jīng)過HASH JOIN后,有90%都不需要返回,這種情況下使用布隆過濾在進行HASH分發(fā)前預(yù)HASH JON。這樣經(jīng)過布隆過濾器,有大量的記錄就被布隆過濾器所淘汰,最后HASH JOIN右邊的結(jié)果集就變得非常小,也就讓HASH 分發(fā)的數(shù)據(jù)量變得非常的小,大大減少了出現(xiàn)PX Deq Credit: send blkd 、PX Deq Credit: need buffer的概率。如果不使用布隆過濾,進程不得不傳遞大量的數(shù)據(jù)給另一組進程,增加了內(nèi)存,CPU,增加了兩組進程的進程間競爭。
不要期待布隆過濾是完美的,他能消除掉大部分的行,但是不是 所有的行,因此有一些不需要的數(shù)據(jù)會穿過布隆過濾器達到第二組進程。

并行度降級

無論你使用的是手工指定DOP,還是使用11G的AUTO DOP,運行時的DOP都有可能與你預(yù)期的不一樣:可能被降級??赡軙泻芏喾N原因?qū)е虏⑿斜唤档停?,?dāng)前系統(tǒng)中可用的并行進程已經(jīng)不能滿足需要的DOP,或者你已經(jīng)使用了Oracle的資源管理器對并行度做了限制,等等。
監(jiān)控并行度降低的最好工具是oracle 12.1版本的SQL MONITORING,例如:

 Oracle并行基礎(chǔ)二
如上圖,在【一般信息】部分,將你的鼠標(biāo)放在Execution Plan部分的藍色小人上,將會出現(xiàn)一些并行度的信息,例如上圖中,運行時間的DOP為4,實際請求的并行服務(wù)進程為10,實際分配的并行服務(wù)進程為4,并行度被降低的百分比為60%。
為了找出語句被降級的理由,你可以點擊【計劃統(tǒng)計信息】部分,PX COORDINATOR行源的其他列,如下圖,用紅色框標(biāo)記: Oracle并行基礎(chǔ)二
點擊后出現(xiàn):
 Oracle并行基礎(chǔ)二
以下是被降級的一些代碼說明:
350 DOP downgrade due to adaptive DOP
351 DOP downgrade due to resource manager max DOP
352 DOP downgrade due to insufficient number of processes
353 DOP downgrade because slaves failed to join
我這里的情況是,由于系統(tǒng)可以使用的并行進程不足導(dǎo)致分配并行資源失敗。
如果你不方便使用EMCC,也可以通過視圖觀察到并行度降級的情況,但是被降級的理由,暫時還沒有視圖反應(yīng)(或者我還不知道,如果你知道請告訴我)
 Oracle并行基礎(chǔ)二

DEGREE 列為實際的并行度,REQ_DEGREE 為請求的并行度。
有一些手段可以避免并行度降級,例如如果使用的是ORACLE 11G版本,可以使用自動并行管理功能,然后結(jié)合在語句級指定并行度。因為自動并行度功能一單被打開,并行語句排隊功能將被啟用,如果語句運行時發(fā)現(xiàn)沒有足夠的可用并行進程,那么會排隊等待,直到有滿足目標(biāo)的可用并行進程。

多個DFO 單元

一些命令可以有多個DFO單元,因為每個DFO單元最多可以使用2個PX slaves set,如果一個命令有多個DFO單元,那么它就可以使用超過2個PX slaves set,可以在執(zhí)行計劃里看到是否使用了多個DFO單元:
select count() from (select /+ parallel(a 4) /count() from hash_t1 a
union
select /+ parallel(b 4) / count(*) from hash_t2 b)

 Oracle并行基礎(chǔ)二
行ID為6和12的行源兩處都有coordinator標(biāo)識,這意味著這個命令使用了2個DFO單元。 Oracle并行基礎(chǔ)二

通過SQL MONITORING也可以看到這個命令具有了2個并行組,理論上每個DFO單元之間可以同時進行并行操作,但是我們這個例子里,兩個DFO單元之間的執(zhí)行順序是,先執(zhí)行DFO單元1,再執(zhí)行DFO單元2,可以通過【時間表】列看到,第一個DFO單元先活躍,等結(jié)束后,第二個DFO單元開始活躍。
從上圖還可以看出,DFO單元2復(fù)用了DFO單元1的并行進程,沒有重新產(chǎn)生新的并行進程,從并行進程編號上可以看出這一點。SQL MONTIRONG是不是超級好用?

v$pq_sesstat視圖


通過查詢v$pq_sesstat視圖,可以知道語句運行時的DFO單元的數(shù)量(DFO Trees),并行集的個數(shù)(Slave Sets ),服務(wù)進程的個數(shù)(Server Threads),執(zhí)行所采用的并行度(DOP)。如下:
 Oracle并行基礎(chǔ)二

寫到這里文章已經(jīng)有點長了,對于12C的新特性還少有涉及,對于并行執(zhí)行傾斜的內(nèi)容也還未涉及,對于布隆過濾的傳遞和高級知識也未涉及。對于這些內(nèi)容,我會在下一篇進行介紹。

分享名稱:Oracle并行基礎(chǔ)二
標(biāo)題鏈接:http://muchs.cn/article22/ghiicc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序動態(tài)網(wǎng)站、靜態(tài)網(wǎng)站、網(wǎng)站改版、定制網(wǎng)站、App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管