淺談Oracle Shared Pool
學(xué)習(xí)Oracle時(shí),你可能會(huì)遇到Oracle Shared Pool問(wèn)題,這里將介紹Oracle Shared Pool問(wèn)題的解決方法,在這里拿出來(lái)和大家分享一下。我們從一個(gè)用戶請(qǐng)求開(kāi)始講,ORACLE的簡(jiǎn)要的工作機(jī)制是怎樣的,首先一個(gè)用戶進(jìn)程發(fā)出一個(gè)連接請(qǐng)求,如果使用的是主機(jī)命名或者是本地服務(wù)命中的主機(jī)名使用的是機(jī)器名(非IP地址),那么這個(gè)請(qǐng)求都會(huì)通過(guò)DNS服務(wù)器或HOST文件的服務(wù)名解析然后傳送到Oracle監(jiān)聽(tīng)進(jìn)程,監(jiān)聽(tīng)進(jìn)程接收到用戶請(qǐng)求后會(huì)采取兩種方式來(lái)處理這個(gè)用戶請(qǐng)求,下面我們分專用服務(wù)器和共享服務(wù)器分別采用這兩種方式時(shí)的情況來(lái)講:
專用服務(wù)器模式下:一種方式是監(jiān)聽(tīng)進(jìn)程接收到用戶進(jìn)程請(qǐng)求后,產(chǎn)生一個(gè)新的專用服務(wù)器進(jìn)程,并且將對(duì)用戶進(jìn)程的所有控制信息傳給此服務(wù)器進(jìn)程,也就是說(shuō)新建的服務(wù)器進(jìn)程繼承了監(jiān)聽(tīng)進(jìn)程的信息,然后這個(gè)服務(wù)器進(jìn)程給用戶進(jìn)程發(fā)一個(gè)RESEND包,通知用戶進(jìn)程可以開(kāi)始給它發(fā)信息了,用戶進(jìn)程給這個(gè)新建的服務(wù)器進(jìn)程發(fā)一個(gè)CONNECT包,服務(wù)器進(jìn)程再以ACCEPT包回應(yīng)用戶進(jìn)程,至此,用戶進(jìn)程正式與服務(wù)器進(jìn)程確定連接。我們把這種連接叫做HAND-OFF連接,也叫轉(zhuǎn)換連接。
另一種方式是監(jiān)聽(tīng)進(jìn)程接收到用戶進(jìn)程的請(qǐng)求后產(chǎn)生一個(gè)新的專用服務(wù)器進(jìn)程,這個(gè)服務(wù)器進(jìn)程選用一個(gè)TCP/IP端口來(lái)控制與用戶進(jìn)程的交互,然后將此信息回傳給監(jiān)聽(tīng)進(jìn)程,監(jiān)聽(tīng)進(jìn)程再將此信息傳給用戶進(jìn)程,用戶進(jìn)程使用這個(gè)端口給服務(wù)器進(jìn)程發(fā)送一個(gè)CONNECT包,服務(wù)器進(jìn)程再給用戶進(jìn)程發(fā)送一個(gè)ACCEPT包,至此,用戶進(jìn)程可以正式向服務(wù)器進(jìn)程發(fā)送信息了。這種方式我們叫做重定向連接。HAND-OFF連接需要系統(tǒng)平臺(tái)具有進(jìn)程繼承的能力,為了使WINDOWS NT/2000支持HAND-OFF必須在HKEY_LOCAL_MACHINE>SOFTWARE>ORACLE>HOMEX中設(shè)置USE_SHARED_SOCKET。
共享服務(wù)器模式下:只有重定向連接的方式,工作方式是監(jiān)聽(tīng)進(jìn)程接收到用戶進(jìn)程的請(qǐng)求后產(chǎn)生一個(gè)新的調(diào)度進(jìn)程,這個(gè)調(diào)度進(jìn)程選用一個(gè)TCP/IP端口來(lái)控制與用戶進(jìn)程的交互,然后將此信息回傳給監(jiān)聽(tīng)進(jìn)程,監(jiān)聽(tīng)進(jìn)程再將此信息傳給用戶進(jìn)程,用戶進(jìn)程使用這個(gè)端口給調(diào)度進(jìn)程發(fā)送一個(gè)CONNECT包,調(diào)度進(jìn)程再給用戶進(jìn)程發(fā)送一個(gè)ACCEPT包,至此,用戶進(jìn)程可以正式向調(diào)度進(jìn)程發(fā)送信息了??梢酝ㄟ^(guò)設(shè)置MAX_DISPIATCHERS這個(gè)參數(shù)來(lái)確定調(diào)度進(jìn)程的***數(shù)目,如果調(diào)度進(jìn)程的個(gè)數(shù)已經(jīng)達(dá)到了***,或者已有的調(diào)度進(jìn)程不是滿負(fù)荷,監(jiān)聽(tīng)進(jìn)程將不再創(chuàng)建新的調(diào)度進(jìn)程,而是讓其中一個(gè)調(diào)度進(jìn)程選用一個(gè)TCP/IP端口來(lái)與此用戶進(jìn)程交互。調(diào)度進(jìn)程每接收一個(gè)用戶進(jìn)程請(qǐng)求都會(huì)在監(jiān)聽(tīng)進(jìn)程處作一個(gè)登記,以便監(jiān)聽(tīng)進(jìn)程能夠均衡每個(gè)調(diào)度進(jìn)程的負(fù)荷,所有的用戶進(jìn)程請(qǐng)求將分別在有限的調(diào)度進(jìn)程中排隊(duì),所有調(diào)度進(jìn)程再順序的把各自隊(duì)列中的部分用戶進(jìn)程請(qǐng)求放入同一個(gè)請(qǐng)求隊(duì)列,等候多個(gè)ORACLE的共享服務(wù)器進(jìn)程進(jìn)行處理(可以通過(guò)SHARED_SERVERS參數(shù)設(shè)置共享服務(wù)器進(jìn)程的個(gè)數(shù)),也就是說(shuō)所有的調(diào)度進(jìn)程共享同一個(gè)請(qǐng)求隊(duì)列,共享服務(wù)器模式下一個(gè)實(shí)例只有一個(gè)請(qǐng)求隊(duì)列,共享服務(wù)器進(jìn)程處理完用戶進(jìn)程的請(qǐng)求后將根據(jù)用戶進(jìn)程請(qǐng)求取自不同的調(diào)度進(jìn)程將返回結(jié)果放入不同的響應(yīng)隊(duì)列,也就是說(shuō)有多少調(diào)度進(jìn)程就有多少響應(yīng)隊(duì)列,然后各個(gè)調(diào)度進(jìn)程從各自的響應(yīng)隊(duì)列中將結(jié)果取出再返回給用戶進(jìn)程。
以上我們講完了用戶與ORACLE的連接方式,下面我們要講ORACLE服務(wù)器進(jìn)程如何處理用戶進(jìn)程的請(qǐng)求,當(dāng)一個(gè)用戶進(jìn)程發(fā)出了一條SQL語(yǔ)句:UPDATE TABBLEA SET SALARY=SALARY*2;首先服務(wù)器進(jìn)程將對(duì)該語(yǔ)句進(jìn)行檢查語(yǔ)句有效性的語(yǔ)法檢查和確保語(yǔ)句能夠正常運(yùn)行的語(yǔ)義檢查,首先檢查該語(yǔ)句的語(yǔ)法的正確性(語(yǔ)法檢查),接著對(duì)照數(shù)據(jù)字典對(duì)語(yǔ)句中涉及的表、索引、視圖等對(duì)象及用戶的權(quán)限進(jìn)行檢查(語(yǔ)義檢查),如果以上任一檢查沒(méi)有通過(guò),就返回一個(gè)錯(cuò)誤,但不會(huì)明確的指出是語(yǔ)法檢查出錯(cuò)還是語(yǔ)義檢查出錯(cuò),它只會(huì)返回一個(gè)ORA-*****的錯(cuò)誤碼。如果檢查通過(guò)以后,服務(wù)器進(jìn)程把這條語(yǔ)句的字符轉(zhuǎn)換成ASCII等效數(shù)字碼(注意SQL中使用*是個(gè)例外,如果表的字段改變了,同樣是SELECT * FROM TABLEA轉(zhuǎn)換成的ASCII是不同的,其實(shí)它在語(yǔ)義檢查時(shí)就明確的變成了操作具體字段的SQL語(yǔ)句了),接著這個(gè)ASCII碼被傳遞給一個(gè)HASH函數(shù),并返回一個(gè)HASH值,服務(wù)器進(jìn)程將到Oracle Shared Pool的共享PL/SQL區(qū)去查找是否存在同樣的HASH值,如果存在,服務(wù)器進(jìn)程將使用這條語(yǔ)句已高速緩存在Oracle Shared Pool中的已分析過(guò)的版本來(lái)執(zhí)行(軟解析),如果不存在,則必須進(jìn)行以下兩個(gè)步驟:語(yǔ)句的優(yōu)化(生成執(zhí)行計(jì)劃)和生成執(zhí)行編碼:服務(wù)器進(jìn)程根據(jù)ORACLE選用的優(yōu)化模式以及數(shù)據(jù)字典中是否存在相應(yīng)對(duì)象的統(tǒng)計(jì)數(shù)據(jù)和是否使用了存儲(chǔ)大綱來(lái)生成一個(gè)執(zhí)行計(jì)劃或從存儲(chǔ)大綱中選用一個(gè)執(zhí)行計(jì)劃,***再生成一個(gè)編譯代碼(硬解析)。
ORACLE將這條語(yǔ)句的本身實(shí)際文本、HASH值、編譯代碼、與此語(yǔ)句相關(guān)聯(lián)的任何統(tǒng)計(jì)數(shù)據(jù)和該語(yǔ)句的執(zhí)行計(jì)劃緩存在Oracle Shared Pool的共享PL/SQL區(qū)。V$librarycache中的幾個(gè)參數(shù)解釋Pins: (Execution)即SQL實(shí)際執(zhí)行的次數(shù),不包括用戶提交的語(yǔ)法語(yǔ)義檢查失敗的SQL。Reloads: (Parse)未找到相同HASH_VALUE的次數(shù),即必須進(jìn)行硬解析的次數(shù)。Invalidations: (Parse)因?qū)ο蟾?,使得所有引用這個(gè)對(duì)象的緩存執(zhí)行計(jì)劃失效而必須再次硬解析的次數(shù)。只要DDL更改了一個(gè)對(duì)象,所有與此有關(guān)的緩存在共享池中執(zhí)行計(jì)劃都將立即失效,它的失效不是在下次執(zhí)行SQL時(shí)才發(fā)現(xiàn)其失效,而是DDL更改對(duì)象后立即就失效。主要表現(xiàn)在DDL發(fā)生后v$sql的HASH_VALUE仍保持不變,但PLAN_HASH_VALUE立即變?yōu)?,再次運(yùn)行SQL語(yǔ)句時(shí)則會(huì)向v$sql插入一條新的緩沖記錄HASH_VALUE,PLAN_HASH_VALUE都重新計(jì)算。原來(lái)的緩沖記錄仍然還存在。
服務(wù)器進(jìn)程通過(guò)Oracle Shared Pool鎖存器來(lái)申請(qǐng)可以向哪些共享PL/SQL區(qū)中緩存這些內(nèi)容,也就是說(shuō)被Oracle Shared Pool鎖存器鎖定的PL/SQL區(qū)中的塊不可被覆蓋,因?yàn)檫@些塊可能正在被其它進(jìn)程所使用。在SQL分析階段將用到LIBRARY CACHE,從數(shù)據(jù)字典中核對(duì)表、索引、視圖及用戶的權(quán)限的時(shí)候,需要將數(shù)據(jù)字典從磁盤(pán)讀入LIBRARY CACHE,因此,在讀入之前也要使用LIBRARY CACHE鎖存器來(lái)申請(qǐng)用于緩存數(shù)據(jù)字典。
【編輯推薦】