共享池之八:軟解析、硬解析、軟軟解析 詳解一條SQL在library cache中解析涉及的鎖

還不算暈發表於2014-03-17

先來張大圖:

結合上圖來說明一下解析的各個步驟涉及的鎖。

軟解析、硬解析、軟軟解析區別的簡單說明:

為了將使用者寫的sql文字轉化為oracle認識的且可執行的語句,這個過程就叫做解析過程。

解析分為硬解析和軟解析,SQL語句第一次解析時必須進行硬解析

一句話說明硬解析與軟解析的區別是:

硬解析=需要生成執行計劃   軟解析=不需要生成執行計劃

在Oracle中存在兩種型別的SQL語句,一類為DDL語句,不共享使用,也就是每次執行都需要進行硬解析。還有一類就是DML語句,會進行硬解析或軟解析。

硬解析變成軟解析:繫結變數

軟解析變成軟軟解析:設定session_cached_cursors,詳見


圖中涉及的各結構簡單介紹:

涉及的各結構的簡單介紹: 詳見:

父遊標:儲存HASH值,SQL文字--相同SQL語句,就只有一個父遊標

父遊標裡主要包含兩種資訊:sql文字以及優化目標。父遊標在第一次開啟時被鎖定,直到其他所有的session都關閉該遊標後才被解鎖。當父遊標被鎖定的時候是不能被交換出librarycache的,只有在解鎖以後才能被交換出library cache。父遊標被交換出記憶體時父遊標對應的所有子游標也被交換出library cache。

 

子游標:一個父遊標下會有多個子遊標,各個子游標的執行計劃不一樣--多版本.一個父下必有一個子遊標,可以有多個子遊標。

子游標包括遊標所有的資訊,比如具體的執行計劃、繫結變數等。子游標隨時可以被交換處library cache,當子游標被交換出library cache時,oracle可以利用父遊標的資訊重新構建出一個子遊標出來,這個過程叫做reload(過載)。

 

父HANDLE,裡面有父遊標堆0的地址。。

父遊標堆0:有指向一個或多個子遊標的HANDLE夠控制程式碼地址

子游標的HANDLE:有子游標堆0地址

子游標堆0:有SQL語句依賴關係,並指向子游標的堆6

子游標堆6:存有SQL語句的執行計劃

SQL語句在Library cache執行的第一次檢查過程:

1.通過語法語義許可權等檢查的SQL語句進入Library cache
2.將SQL文字轉化為ASCII值(大小寫ASCII不同)並進行hash函式的運算
4.得到一個HASH值對應到hash bucket的號碼
################以上檢查通過後,進入以下解析過程

軟軟解析:

--通過設定session_cached_cursors引數實現-
SQL執行=3次(可以不是一個會話執行的SQL),堆6的DS-堆描述符地址被放入UGA(屬於PGA)--LOCK變為1-NULL標記語句為快取並保證記憶體不被釋放(堆6釋放堆0才能釋放)。
也就是SQL執行3次,被快取。第四次,就是軟軟解析了。
--優化目標:命中率90%以上。
會話發起SQL,會首先在User Global Area中查詢CURSOR資訊。
此時,在父遊標handle,子游標handle和子游標堆6上使用NULL 1。

####################################

軟解析:

1.獲得library cacheLatch   ---如未獲得將產生:Latch:library cache
2.獲得library cache lock,檢索bucket上的父遊標handle,得到所指向的父遊標堆0-LCO的記憶體地址。
3.獲得library cache pin,讀取父遊標堆0-LCO,得到子游標handle地址。
4.獲得library cache lock,檢索子游標handle,得到所指向的子游標堆0-子LCO的記憶體地址。
5.獲得library cache pin,讀取子游標堆0-子LCO從而得到子游標堆6地址。
6.讀取子游標堆6,得到SQL執行計劃。
###找到child lco後,增加parsecount(total)統計值。
SQL開始執行:此時以共享模式獲得library cache lock和library cache pin,並執行SQL。
FETCH階段:執行完成進入FETCH階段,SQLCURSOR將library cache lock轉換為null模式,釋放library cache pin。
###############################################################

在嘗試軟解析時:
--如果未檢索到相同的父遊標LCO或子游標LCO時,發生硬解析。
--如果子游標堆6上不能加共享library cachepin或者child lco中資訊不完整,需要重建執行計劃--記錄為硬解析。

硬解析:

如果未檢索到相同的父遊標LCO或子游標LCO時,發生硬解析。程式會一直持有library cache latch,直到硬解析結束為止。
1.獲取shared pool latch,從freelist的bucket上查詢合適大小的CHUNK。
不存在大小合適的CHUNK會分割大CHUNK,剩餘的會再進入相應的BUCKET。
如 果不能從free list的bucket上查詢到合適大小的CHUNK,則進入 lru list;如果仍不能獲取到CHUNK,則從shared pool剩餘內在中分配。如果CURSOR達到 _shared_pool_reserved_min_alloc隱含引數的大小標準(11.2.0.4中是4400),則從保留池中分配CHUNK;如 果這些分配CHUNK操作都失敗,報錯:ORA-04031。如bucket列表過長或者碎片嚴重,產生latch:shared pool爭用。

2.分配到CHUNK後。獲得library cachelock--獨佔模式,建立父遊標handle
3.獲得library cache pin,建立父遊標堆0-父LCO的資訊。--library cache lock轉為NULL
4.獲得library cache lock,建立子游標handle
5.獲得library cache pin,建立子游標堆0-子LCO的資訊。
6.library cache pin,建立子游標堆6-執行計劃的資訊(通過優化器建立一個最優的執行計劃,這個過程會根據資料字典裡面記錄的物件的統計資訊,來計算最優的執行計劃,這一步涉及的運算量很大,最耗CPU資源)。
SQL開始執行:此時以共享模式獲得library cache lock和library cache pin,並執行SQL。
FETCH階段:執行完成進入FETCH階段,SQLCURSOR將library cache lock轉換為null模式,釋放library cache pin。


 關於MUTEX與圖中librarycache Latch/PIN/LOCK的對應:

關於MUTEX,可以簡單的把library cache Latch/PIN/LOCK當做MUTEX的不同模式來套入此步驟。

在10G中,Mutex主要保護 handle和LCO---替代library cache PIN/LOCK

在11G中,Mutex可以保護bufket上鍊表,handle和LCO---替代library cache Latch/PIN/LOCK

控制程式碼上訪問競爭:Cursor:mutex   堆的訪問競爭:Cursor:pin

解析時MUTEX的相關爭用

1、相關鎖

(1)、計算HASH值,找到Bucket,搜尋HASH連結串列,查詢控制程式碼。

    LIbrary Cache Latch(11G後被Mutex取代)

(2)、在父遊標控制程式碼中查詢父遊標堆0

    mutex(取代Library cache lock latch) ,Library cache lock

(3)、在父遊標堆0中,查詢子游標控制程式碼。

     兩次mutex。兩種型別的Mutex。取代了Librarycache pin latch和Library cache pin 。

(4)、在子游標控制程式碼中,查詢子游標堆0地址。

    mutex(取代Library cache lock latch) ,Library cachelock     

(5)、在子游標堆0中,查詢子游標堆6地址。

     一次mutex。取代了Librarycache pin latch和Library cache pin 。

(6)、在子游標堆6中,讀取SQL執行計劃。

     一次mutex。取代了Librarycache pin latch和Library cache pin 。

 

相關文章