Library Cache是Shared pool的一部分,主要存放Shared cursor(SQL)和PLSQL對象(function,procedure,trigger)的信息。以及這些對象所依賴的table,index,view等對象信息。sql
Library cache須要解決三個問題:數據庫
快速定位的問題:Library cache中對象衆多,Oracle如何管理這些對象,以便服務進程能夠迅速找到他們須要的信息。好比某個服務進程須要迅速定位某個SQL是否存在於Library cache中。數組
關係依賴的問題:Library cache中的對象存在複雜的依賴關係,當某個objec失效時,能夠迅速將依賴其的對象也置爲失效狀態。好比某個表發生告終構變化,依賴其的SQL語句須要從新解析。session
併發控制的問題:Library cache中必須有一個併發控制的機構,好比鎖機制,來管理大量共享對象的併發訪問和修改的問題,好比某個SQL在從新編譯的同時,其所依賴的對象不能被修改。併發
Library Cache結構:ide
Oracle 利用hash table結構來解決Library cache中快速定位的問題,hash table是由不少hash bucket組成的數組:spa
其中原理與Buffer Cache中定位Block方式相同,將對象信息的hash定位至某個hash bucket中,而後順序掃描Bucket中的List,實現快速定位對象的目的。指針
Library Cache Handle是對象指針,指針的namespace屬性表示其指向的對象類型:好比CRSR(Cursor),TABL(Table),INDX(Index) ,PROD(Procedure),TRIG(Trigger)等。code
LCO(Library cache object)是handle指向的對象,LCO包含如下幾個部分:orm
1. Object Types
Object 是一組根據對象所屬類型定義的命名空間組
每一個Object只能是一種類型
全部相同類型的Object屬於相同的命名空間
一個命名空間可能用於兩個以上的相同類型
最重要的命名空間成爲遊標(CRSR)用於存放共享的SQL遊標。
Library cache object的type,包括:shared,cursor,index,table,cluster,view,synonym,sequence,procedure,function,package,table body,package,body,trigger等等。
2. Object Names
LCO名稱有三個部分:Schema名,Object名,DB Link名(僅遠程對象)
格式:SCHEMA.NAME@DBLINK
3. Object Flags
1) Public Flags
不受pins或latches的保護
包含對象的類型細節
2) Status Flags
受pins的保護
代表對象是否被created/dropped/altered/updated
3) Special status flags
受 latch的保護
與Object的有效性和權限相關
4. Object Tables
1) Dependency table
指向對象依賴的表,好比:select * from table這個cursor對象,依賴table這個表。這裏指向table這個表handle
2) Child table
指向對象的子對象,好比某個Cursor的Child Cursor,Child Cursor是指SQL文本相同,可是SQL實際含義不一樣,如執行用戶、環境、計劃不一樣等。咱們通常稱爲SQL的不一樣版本。一個SQL至少包含一對父子游標。
3) Transaltion table
4) Authorization table
對象的受權信息。
5) Access table
6) Read-only dependency table
7) Schema name table
5.Data blocks
data block是一個指針,指向了data heap,即存放真實數據的地方,主要包括:diana tree, p-code, source code, shared cursor context area等等,其中SQL執行計劃就存放在Heap 6:SQL Context中。以下:
Library cache對象依賴關係:
對象依賴關係是利用LCO中的Dependency table來完成的,經過如下狀況說明對象依賴:
兩個共享遊標:
SQL1:select * from emp
SQL2:select * from emp和select a.name from emp a,dept b where a.dept_id=b.id and b.name=:1;
SQL1產生了兩個子游標,也就是SQL文本相同的兩個不一樣版本,他們同時依賴emp表。SQL2只有一個版本,由於每一個遊標最少有一個子遊標,因此它只有一個子遊標,而且同時依賴dept表和emp表。
我這裏作個嘗試DUMP Library Cache的信息
SQL> alter session set events'immediate trace name library_cache cancel';
SQL> select * from dual //這裏我執行一個查詢DUAL的語句。觀察在Library Cache中都作了什麼。
SQL> alter session set events'immediate trace name library_cache off';
SQL> select value from v$diag_info;
能夠看到該語句位於Library Cache中的第108289個Bucket中。對應的LibraryHandle指針的地址與v$sqlarea中的ADDRESS一致:
SELECT SQL_ID,
ADDRESS,
HASH_VALUE,
EXECUTIONS,
LOADS,
PARSE_CALLS,
INVALIDATIONS,
SQL_TEXT,
CHILD_ADDRESS,
SQLTYPE
FROM V$SQL
WHERE SQL_TEXT = 'select * from dual';
Hash部分也是一致的
SQL> select to_number('382da701','xxxxxxxxx') from dual;
TO_NUMBER('382DA701','XXXXXXXXX')
---------------------------------
942515969
在Library Cache對於SQL執行的記錄部分,關注如下塊內容
ObjectName:記錄了SQL對象語句。
WaitersLists:
LibraryObject:記錄Library對象地址。
NamespaceDump:記錄SQL的ID值、父遊標的地址和最大子游標數。
Library cache中的併發控制:
Oracle利用Library cache lock和Library cache pin來實現併發控制,Library cache lock是在handle上獲取的,而Library cache pin則是在data heap上獲取。訪問對象時,首先必須獲取handle上的lock,而後將訪問的數據pin在內存中。lock的做用是控制進程間的併發訪問,而pin的做用是保證數據一致性,防止數據在訪問時被交換出去。
Library cache lock有三種模式:null,share,exclusive,Library cache pin有兩種模式:share,exclusive。下面詳細解釋在修改和訪問對象時,lock和pin的做用:
修改對象:
編譯SQL或PLSQL對象,獲取該對象(cursor,procedure)handle上exclusive類型的lock,而且持有data heap上exclusive類型的pin,防止其餘人讀取和修改。同時,在該對象所依賴的對象(table)上,必須持有一個share類型的lock和pin,防止在修改的過程當中,被其餘進程所修改。
訪問對象:
訪問SQL或PLSQL對象,獲取該對象(cursor,procedure)handle上NULL類型的lock,而且持有data heap上share類型的pin,同時,在其依賴的對象(table)上持有share類型的lock和pin。若是一個procedure依賴另一個function,那麼在被依賴的function上,也須要持有share類型的lock和pin。
NULL類型的lock比較特殊,它只存在於cursor和procedure等只讀對象上,它並不起到任何併發控制的做用,它更象是一個trigger,當對象失效時,通知全部訪問這個cursor的進程。好比:select * from emp這個SQL,依賴emp表,當emp表發生變化時,cursor上的NULL lock被打破,全部有訪問這個cursor的進程都會知道該對象已經失效。
當持有對象的library cache pin時,會在row cache中對相應的對象加鎖,就是row cache lock,阻止可能致使數據字典信息混亂的DDL發生。
lock和pin的實現相似於enqueue,在每一個handle上都有lock和pin的holder list和waiter list,用來保存持有該資源和等待該資源的隊列。
阻塞分析:
現實狀況中,咱們有一個數據庫中存在被應用大量頻繁訪問的procedure,當依賴的表發生變動時,致使該procedure失效,這時會出現大量的library cache lock和library cache pin的等待,堵塞應用訪問,形成了重大故障。出現這個問題的緣由是:當procedure失效後,全部訪問該對象的進程都嘗試去編譯,大量進程嘗試獲取exclusive類型的lock和pin,出現了大量的等待。後續的Oracle版本做出了改進,當出現這種狀況時,只容許第一個進程嘗試去編譯該對象,編譯經過後,全部的進程就能夠併發訪問,避免了大量進程同時嘗試編譯的狀況出現。
Library cache中的Latch:
Library cache中相關的latch包括:shared pool latch,library cahce latch,library cache lock latch,library cache pin latch。
Share pool latch的主要做用是分配或釋放空間時使用,從Oracle9i開始,sharedpool被分紅了不少個subpool,由多個shared pool latch保護,Oracle開始支持更大的shared pool。
Library cache latch的主要做用是在hash bucket中定位handle時使用,library cache lock latch和library cache pin latch分別是獲取lock和pin時,須要取得的latch。
shared pool大小不合理,大量的硬解析以及SQL版本過多均可能致使shared pool latch和library cache latch的爭用。
從Oracle10g開始,Oracle正在逐步用mutex取代library cache中的latch,cursor:pin S和cursor:pin X至關於share和exclusive類型的library cache pin,cursor:pin S wait on X則表示share方式正在等待exclusive鎖定。