oracle 11g禁用和强制direct path read
一般在混合型環(huán)境中,大表在進(jìn)行全表掃描或者走并行的時(shí)候一般會(huì)出現(xiàn)direct path read等待事件,如果在OLTP或者純粹的DSS環(huán)境中,出現(xiàn)大量的direct path read直接路徑讀取,這樣就有問(wèn)題了,尤其是一些流水線(xiàn)的批處理系統(tǒng)中,會(huì)導(dǎo)致大量的free buffer wait等(因?yàn)閐irect path reads會(huì)導(dǎo)致oracle執(zhí)行object level checkpoint將所有目標(biāo)對(duì)象的臟塊寫(xiě)入磁盤(pán),然后將這些塊從磁盤(pán)讀取到進(jìn)程的PGA,如果有未提交的事務(wù),還必須使用PGA構(gòu)造讀一致性塊緩沖。所以parallel是把雙刃劍,用的不好,系統(tǒng)性能會(huì)很慢,尤其是在跑批系統(tǒng)中,增加了大量不必要的物理讀寫(xiě),要想跑的飛快,cpu利用起來(lái),應(yīng)用層的fork-join線(xiàn)程池設(shè)計(jì)極大的決定了系統(tǒng)的性能)。一般在OLTP中,都是事務(wù)型的sql,如果想sql執(zhí)行效率,那么最好從內(nèi)存當(dāng)中讀取數(shù)據(jù),直接從數(shù)據(jù)文件中讀取,后果可想而知了。這里就可能需要我們禁用direct path read。
在oracle 11.2之前,只要沒(méi)有設(shè)置_serial_direct_read為true,同時(shí)沒(méi)有指定并行執(zhí)行,oracle會(huì)將HWM以下的塊讀入buffer cache。如果走了并行執(zhí)行,意味著所有的表都會(huì)導(dǎo)致direct read,即使表不大也如此。
從11.2開(kāi)始,oracle默認(rèn)會(huì)自動(dòng)決定要不要在非并行執(zhí)行的時(shí)候繞過(guò)buffer cache并使用direct path read(為什么這是合適的呢,舉個(gè)例子,假設(shè)有張表有1億條數(shù)據(jù),平均紀(jì)錄長(zhǎng)度200,全表掃描意味著20G的buffer cache,而服務(wù)器本身可能只配置了64G,很明顯一張1億條記錄的表不太可能是所有記錄都經(jīng)常要訪(fǎng)問(wèn)的,但是其中的1/10經(jīng)常訪(fǎng)問(wèn)是可能的,此時(shí)如果這個(gè)表沒(méi)有分區(qū)顯然是不合理的)。同時(shí),更重要的是,我們可以通過(guò)參數(shù)控制并行查詢(xún)的時(shí)候?qū)δ承┍淼膾呙杩梢宰遙uffer cache,而不是direct read。
oracle根據(jù)幾個(gè)參數(shù)決定全表掃描的時(shí)候是否走直接路徑讀,首先是_small_table_threshold隱含參數(shù),它決定oracle認(rèn)為的小表閾值(同時(shí),讀取少于該值的parallel將使用buffer cache),每個(gè)環(huán)境和版本都可能不同,默認(rèn)值約為默認(rèn)值是db cache size的2%大小。如下:
_serial_direct_read值控制非并行執(zhí)行的時(shí)候是否允許走直接讀。默認(rèn)情況下,如果表大于_small_table_threshold*5,則全表掃描的時(shí)候自動(dòng)會(huì)被調(diào)整為direct read,也就是buffer cache的1/10左右(這個(gè)算大、也不算大)。
這個(gè)值其實(shí)應(yīng)該被啟用,這是對(duì)的,但是應(yīng)該合理設(shè)置_small_table_threshold的閾值以最小化不必要的物理io。
可以通過(guò)兩種方式是禁用直接讀,如下:
SQL> alter system set event='10949 TRACE NAME CONTEXT FOREVER, level 1' scope=spfile; System alteredSQL> alter session set "_serial_direct_read"=false; Session alteredSQL> SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ2 FROM SYS.x$ksppi x, SYS.x$ksppcv y3 where x.indx = y.indx4 AND (x.ksppinm = '_small_table_threshold' or5 x.ksppinm = '_serial_direct_read'); NAME VALUE DESCRIB -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- _small_table_threshold 30338 lower threshold level of table size for direct reads _serial_direct_read FALSE enable direct read in serialSQL>還有一個(gè)參數(shù) _very_large_object_threshold 用于設(shè)定(MB單位)不使用direct path read方式的上限,這個(gè)參數(shù)需要結(jié)合10949事件共同發(fā)揮作用。10049和_very_large_object_threshold參數(shù)一起的時(shí)候,只要_very_large_object_threshold小于目標(biāo)表大小*0.8或者buffer cache*5,就可以不走direct path read。所以,要想完全禁用非并行執(zhí)行時(shí)的直接路徑讀,只要將_very_large_object_threshold設(shè)置的足夠大即可,不過(guò)不建議超過(guò)20%*buffer cache(否則要么是分區(qū)沒(méi)使用或者不合理)。
所以在并行和串行之間存在一個(gè)矛盾點(diǎn),這個(gè)矛盾點(diǎn)只能通過(guò)高配置服務(wù)器比如256GB/128C+良好的表結(jié)構(gòu)設(shè)計(jì)或者應(yīng)用層面的分而治之來(lái)解決。
當(dāng)然,我沒(méi)有仔細(xì)去測(cè),最近太忙,沒(méi)有時(shí)間一一去驗(yàn)證,后面會(huì)仔細(xì)驗(yàn)證效果如何。
這給帖子寫(xiě)的不錯(cuò),可以參考下http://www.itpub.net/thread-1815281-1-1.html
參考:http://oracleinaction.com/direct-reads-11g/
轉(zhuǎn)載于:https://www.cnblogs.com/zhjh256/p/9506247.html
總結(jié)
以上是生活随笔為你收集整理的oracle 11g禁用和强制direct path read的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 河南游记 Day0
- 下一篇: 基于keras中IMDB的文本分类 de