Library Cache庫緩存

Library Cache是Shared pool的一部分,主要存放Shared cursor(SQL)和PLSQL對象(function,procedure,trigger)的信息。以及這些對象所依賴的table,index,view等對象信息。sql

Library cache須要解決三個問題:數據庫

  1. 快速定位的問題:Library cache中對象衆多,Oracle如何管理這些對象,以便服務進程能夠迅速找到他們須要的信息。好比某個服務進程須要迅速定位某個SQL是否存在於Library cache中。數組

  2. 關係依賴的問題:Library cache中的對象存在複雜的依賴關係,當某個objec失效時,能夠迅速將依賴其的對象也置爲失效狀態。好比某個表發生告終構變化,依賴其的SQL語句須要從新解析。session

  3. 併發控制的問題:Library cache中必須有一個併發控制的機構,好比鎖機制,來管理大量共享對象的併發訪問和修改的問題,好比某個SQL在從新編譯的同時,其所依賴的對象不能被修改。併發

 

Library Cache結構:ide

Oracle 利用hash table結構來解決Library cache中快速定位的問題,hash table是由不少hash bucket組成的數組:spa

0_1314972638Fw82.gif

 

其中原理與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中。以下:0_1314972598nq3k.gif

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;

0_1314972990Y2Vh.gif

 

       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;

 

wKioL1ZOnkTS6DRDAACnmNKdaIA363.png能夠看該語句位於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';

wKiom1ZOmiPgdLDQAAAXe3XRgJk669.png

 

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發生。

0_1314973012EvMa.gif

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鎖定。

相關文章
相關標籤/搜索