Shared pool的library cache lock/pin及硬解析

lusklusklusk發表於2016-11-07

Shared Pool could be divided in three major parts:
            1. Library Cache
            2. Dictionary Cache
            3. Control Structure

What is shared pool?
Shared pool是SGA中的一部分,由於它是SGA的一部分,這意味著它可以被所有的程式所訪問,Shared Pool當中主要包含了2部分:library cache和dictionary cache。
Library cache包含了共享SQL區(shared SQL areas),私有SQL區(private SQLareas,如果配置了共享伺服器),PL/SQL儲存過程以及包,還有一些控制資訊,比如說locks以及library cache handles。
Dictionary cache包含了表,檢視的依賴資訊,比如表結構,它的使用者,Oracle在解析SQL的時候就會頻繁的訪問dictionary cache。


硬解析使用library cache的流程
shared pool latch-->library cache latch-->Library cache lock-->library cache handle-->Library cache pin-->Library Cache Object

Library Cache結構:hash table-->hash bucket(hash table中的行)-->library cache handle(hash bucket指向的地址就是handle)-->Library Cache Object(Library Cache Object就是一堆library cache heap,library cache handle其實指向的是library cache heap的第一個heap,這個heap記錄了指向其他heap的指標資訊)


shared pool latch發生在shared pool中的記憶體空間塊(不能簡單認為發生在hash table),library cache latch會引發shared pool latch
library cache latch發生在hash bucket
library cache lock發生在library cache handle( 發生在LIBRARY CACHE PIN後object又重編譯或授權操作 )
library cache pin發生在Library Cache Object( 通常是發生在編譯PL/SQL,VIEW,TYPES等object時,這些object依賴的表出現了鎖,這時編譯objects就會出現這個pin )

對包,儲存過程,函式,檢視進行編譯的過程中,如果依賴的表發生了DML操作且沒有提交,不影響編譯的進行

dml不提交,不影響包的的編譯

buffer busy wait發生在buffer cache中,併發寫才發生


latch: 就像活動鎖,可以先鎖A箱子,開鎖後可以從A箱子上拿走,去鎖B箱子
1、一個latch保護多個資源
2、latch本身沒有鎖定模式。

mutex: 就像固定鎖,比如安全門上的鎖,無法移動
1、每個資源都有自己的mutex
2、mutex存在鎖定模式,S和X。S鎖不排斥S鎖,但是排斥X鎖。X鎖排斥所有鎖。

use a shared pool latch that serializes access to prevent two processes from trying to inspect or modify the shared pool simultaneously
A main cause of shared pool or library cache latch contention is parsing.
a high hard parse rate is accompanied by latch contention on the shared pool and library cache latches.
使用序列化訪問的共享池鎖,以防止兩個程式嘗試同時檢查或修改共享池
共享池或庫快取鎖定爭用的主要原因是解析。
共享池和庫快取鎖存器上的鎖存爭用伴隨著高難度的解析速率。


Library Cache Manager
Library cache Manager 可以看做是Heap Manager的客戶端,因為library cache manager是根據Heap Manager來分配記憶體從而存放library cache objects。Library cache Manager控制所有的library cache object,包括package/procedure, cursor, trigger等等

Hash Table and Hash Bucket
Library cache是由一個hash table組成,這個hash table又由hash bucket組成的陣列構成,每個hash bucket又是由一些相互指向的library cache handle所組成,library cache object handle就指向具體的library cache object以及一些引用列表。

Library Cache handle
我們對Library cache中所有物件的訪問是通過利用library cache handle來實現的,也就是說我們想要訪問library cache object,我們必須先找到library cache handle。Library cache handle指向library cache object,它包含了library object的名字,名稱空間,時間戳,引用列表,lock物件以及pin物件的列表資訊等等。Library cache handle也被library cache用來記錄哪個使用者在這個這個handle上有lock,或者是哪個使用者正在等待獲得這個lock。那麼這裡我們也知道了library cache lock是發生在handle上的。
    當一個程式請求library cache object, library cache manager就會應用一個hash 演算法,從而得到一個hash 值,根據相應的hash值到相應的hash bucket中去尋找。這裡的hash演算法原理與buffer cache中快速定位block的原理是一樣的。如果library cache object在記憶體中,那麼這個library cache handle就會被找到。 有時候,當shared pool不夠大,library cache handle會保留在記憶體中,然而library cache heap由於記憶體不足被age out,這個時候我們請求的object heap就會被過載。最壞的情況下,library cache handle在記憶體中沒有找到,這個時候就必須分配一個新的library cache handle,同時object heap也會被載入到記憶體中

Library Cache Object
Library Cache Object是由一些獨立的heap所組成,前面說了Library cache handle指向Library cache Object,其實handle是指向第一個heap,這個heap 我們就稱之為heap 0。Heap 0記錄了指向其他heap的指標資訊。

Library cache lock/pin
Library cache lock/pin是用來控制對library cache object的併發訪問的。Lock管理併發,pin管理一致性,lock是針對於library cache handle,而pin是針對於heap。
當我們想要訪問某個library cache object,我們首先要獲得這個指向這個object的handle的lock,獲得這個lock之後我們就需要pin住指向這個object的heap。
當我們對包,儲存過程,函式,檢視進行編譯的時候,Oracle就會在這些物件的handle上面首先獲得一個library cache lock,然後再在這些物件的heap上獲得pin,這樣就能保證在編譯的時候其它程式不會來更改這些物件的定義,或者將物件刪除。
對包,儲存過程,函式,檢視進行編譯的過程中,如果依賴的表發生了DML操作且沒有提交,不影響編譯的進行
當一個session對SQL語句進行硬解析的時候,這個session就必須獲得library cache lock,這樣其他session就不能夠訪問或者更改這個SQL所引用的物件。如果這個等待事件花了很長時間,通常表明共享池太小(由於共享池太小,需要搜尋free的chunk,或者將某些可以被移出的object page out,這樣要花很長時間),當然了,也有可能另外的session正在對object進行修改(比如split分割槽),而當前session需要引用那個table,那麼這種情況下我們必須等另外的session進行完畢。

Library Cache lock有3中模式:
l  Share(S):     當讀取一個library cache object的時候獲得
l  Exclusive(X): 當建立/修改一個library cache object的時候獲得
l  Null(N):     用來確保物件依賴性
比如一個程式想要編譯某個檢視,那麼就會獲得一個共享鎖,如果我們要create/drop/alter某個物件,那麼就會獲得exclusive lock。Null鎖非常特殊,我們在任何可以執行的物件(cursor,function)上面都擁有NULL鎖,我們可以隨時打破這個NULL鎖,當這個NULL鎖被打破了,就表示這個物件被更改了,需要從新編譯。NULL鎖主要的目的就是標記某個物件是否有效。比如一個SQL語句在解析的時候獲得了NULL 鎖,如果這個SQL的物件一直在共享池中,那麼這個NULL鎖就會一直存在下去,當這個SQL語句所引用的表被修改之後,這個NULL鎖就被打破了,因為修改這個SQL語句的時候會獲得Exclusive 鎖,
由於NULL鎖被打破了,下次執行這個SQL的時候就需要從新編譯。

Library Cache pin有2種模式:
l  Share(S):     讀取object heap
l  Exclusive(X):修改object heap
Library Cache pin沒有什麼好說的,當某個session想要讀取object heap,就需要獲得一個共享模式的pin,當某個session想要修改object heap,就需要獲得排他的pin。當然了在獲得pin之前必須獲得lock。
 
Library cache Latch   
Library cache Latch用來控制對library cache object的併發訪問。前面已經提到,我們要訪問library cache object之前必須獲得library cache lock, lock不是一個原子操作(原子操作就是在操作程中不會被打破的操作,很明顯這裡的lock可以被打破),Oracle為了保護這個lock,引入了library cache latch機制,也就是說在獲得library cache lock之前,需要先獲得library cache latch,當獲得library cache lock之後就釋放library cache latch。

存在大量硬解析的系統上面就必然引發library cache latch, library cache lock競爭,比如每秒高達上100個硬解析

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30126024/viewspace-2127947/,如需轉載,請註明出處,否則將追究法律責任。

相關文章