Oracle Library cache 內部機制 說明

一. Library Cache 說明

            LibraryCache 是Oracle SGA 中Shared pool 的組成部分。Shared Pool的說明,參考之前的blog:

            Oracle Shared pool 詳解

           http://www.cndba.cn/Dave/article/1540

 

            這裏重點看一下Library Cache的一個管理機制。 參考瞭如下2篇blog,重新進行了整理:

            Librarycache內部機制詳解

          http://www.cndba.cn/Dave/article/1381

 

            Oracle中執行計劃的存儲位置

            http://dbsnake.com/2011/05/exe-plan-stor-location.html

 

1. DSI 中對Library Cache的說明:

(1)An area in the shared pool thatmanages information about:

                        --Sharedcursors (SQL and PL/SQL objects)

                        --Databaseobjects (tables, indexes, and so on)

(2)Initially created to manage PL/SQLprograms and library units, therefore called library cache

(3)Scope was extended to includeshared cursors and information about other RDBMS objects.

 

2. Library Cache Objects

(1)The units of information that arestored in the library cache are called objects.

(2)There are two classes of objects:

            1)Stored objects

                        --Created and dropped withexplicit SQL or PL/SQL commands

                        Examples: Tables, views, packages,functions

            2)Transient objects

                        --Created at execution time and liveonly for the      duration of the instance(or aged out)

                        Example: Shared and nonsharedcursors

 

3. Shared Cursors

(1)In-memory representation of anexecutable object:

            SQLstatements

            AnonymousPL/SQL block

            PL/SQLstored procedures or functions

            Javastored procedures

            ObjectMethods

(2)Represented by two or more objects:

            Aparent cursor that has a name

            Oneor more child cursors containing the execution plan

 

4. Library Cache Architecture

(1)The library cache is a hash tablethat is accessible through an array of hash buckets.

(2)The library cache manager (KGL)controls the access and usage of library cache objects.

(3)Memory for the library cache isallocated from the shared pool.

 

 

5. Library cache需要解決三個問題:

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

            (2).關係依賴的問題:Library cache中的對象存在複雜的依賴關係,當某個objec失效時,可以迅速將依賴其的對象也置爲失效狀態。比如某個表發生了結構變化,依賴其的SQL語句需要重新解析。

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

 

            Oracle利用hash table結構來解決library cache中快速定位的問題,hash table就是很多hash bucket組成的數組。 先看DSI 405 裏有幾張相關的圖片:

 

 

 

            LibraryCache 保存了explicitSQL, PL/SQLcommands,shared 和 nonshared cursors。 這些對象都保存在Hash table裏,Hash table 又由Hash Bucket組成。 Hash Bucket 由一些Object Handle List 組成,所以在Hash Bucket裏查找某個對象,就是搜索這個Handle List。

 

6. Object Handle

            在上圖我們可以看到Object handle 保存的信息。 Library cache handle指向library cache object(LCO, heap 0),它包含了library object的名字,命名空間,時間

戳,引用列表,lock對象以及pin對象的列表信息等等。

 

關於Namespace,參考我的blog:

            Oracle Namespace 說明

            http://blog.csdn.net/tianlesoftware/article/details/6624122

 

            所以對Library cache中所有對象的訪問是通過利用library cache handle來實現的,也就是說我們想要訪問library cache object,我們必須先找到library cache handle。

            因爲Object handle保存了lock 和pin 的信息,即記錄哪個用戶在這個這個handle上有lock,或者是哪個用戶正在等待獲得這個lock。那麼這裏我們也知道了library cache lock是發生在handle上的。

 

            當一個進程請求library cache object, librarycache manager就會應用一個hash 算法,從而得到一個hash 值,根據相應的hash值到相應的hash bucket中去尋找。

            如果library cache object在內存中,那麼這個library cache handle就會被找到。有時候,當shared pool不夠大,library cache handle會保留在內存中,然而library cache heap由於內存不足被age out,這個時候我們請求的object heap就會被重載。最壞的情況下,library cache handle在內存中沒有找到,這個時候就必須分配一個新的library cachehandle,同時object heap也會被加載到內存中。

 

7. Library Cache Object(LCO: Heap 0)

            它的結構信息如下圖。 這個圖需要認真的去理解。

 

 

DSI 的說明:

(1)Internally, most of the objectidentity is represented by structures of type kglob.

(2)These are thestructures stored in heap 0.

(3)Object structures have thefollowing components:

                        Type

                        Name

                        Flags

                        Tables

                        Datablocks

 

            LibraryCache 存儲SQL或者shared cursors 等。 這些信息就是通過Heap 0 這個LCO 來保存的。

 

7.1 Object Types

(1)Objects aregrouped in namespaces according to their type.

(2)Each object can only be of onetype.

(3)All the objects of the same typeare in the same namespace.

(4)A namespace may be used by morethan one type.

(5)The most important namespace iscalled cursor (CRSR) and houses the shared SQL cursors.

 

7.2 Object Names

(1)Library cache object names havethree parts:

            Nameof schema

            Nameof object

            Nameof database link (remote objects only)

(2)The format used isSCHEMA.NAME@DBLINK.

            Forexample, [email protected]

 

7.3 Object Flags

(1)Public flags:

            Arenot protected by pins or latches

            Indicatein detail the type of the object

(2)Status flags:

            Areprotected by pins

            Indicatewhether the object is being created/dropped/altered/updated

(3)Special status flags:

            Areprotected by the library cache latch

            Arerelated to object validity and authorization

 

7.4 Object Tables

(1)Dependency table

(2)Child table

(3)Translation table

(4)Authorization table

(5)Access table

(6)Read-only dependency table

(7)Schema name table

 

Object Table 又分爲以上7中類型。

7.4.1 dependency table

            指向本對象所依賴的對象,比如:select * from emp這個cursor的對象,依賴emp這個表,這裏指向了emp這個表的handle。

7.4.2.child table

            指向本對象的子對象,比如某個遊標的子游標。通俗點說,就是一條SQL 至少有一個parent cursor 和 child cursor。 可能一些SQL 由於某些原因無法共享childcursor,這樣就會出現一個parentcursor 和 多個child cursor的情況。 即version count 很高。 那麼這種情況下。 parent cursor 裏對應的所有childcursor的指針都會保存在child table裏面。 Oracle 是用C 寫的,所以這裏是指針。

            注意一點,parent cursor和child cursor都是用library cache object handle 存儲在Library Cache裏的。即他們的結構完全一樣。

            這個結論可以通過library cache的dump 文件來證明。在後面我們會做一個測試。

 

Oracle 高 Version counts 問題說明

http://blog.csdn.net/tianlesoftware/article/details/6628232

 

7.4.3.authorization table

對象的授權信息。

 

7.5 Object Data Blocks

(1)The remainder ofan object’s data is stored in other independent data heaps.

(2)The object structure contains anarray of data block structures.

(3)The data blockstructures have a pointer to a different data heap.

(4)An object structure has room for 16data block structures but not all of them are in use.

 

            Heap0 也僅僅保存是一個結構,它不保存實際的data。 而實際data 的存儲Heap 的指針就存放在這個Data Blocks裏。 這個也可以通過dump 來查看。這個Data Blocks指向的Heap 結構如下圖:

 

            這裏要注意的,就是我們SQL的執行計劃就是存放在這個Heap 6:SQL Context 中。

 

二. 測試

            在上面的說明中,提到,對於多child cursor,所有的child cursor 都保存在child table裏,並且SQL 的執行計劃也保存在child cursor的Heap 6中。 下面進行相關的測試,證明以上結論。

 

SYS@anqing1(rac1)> create table lct asselect * from dba_objects;

Table created.

 

分別用SYSTEM和Dave 用戶執行如下SQL:

/* Formatted on 2011/7/24 15:07:20(QP5 v5.163.1008.3004) */

DECLARE

   x     VARCHAR2 (20);

   str   VARCHAR2 (200);

BEGIN

   x := 'I_PROXY_ROLE_DATA$_1';

   str := 'select* from sys.lct where object_name=:x';

 

   EXECUTE IMMEDIATE str USING x;

END;

/

 

查看SQL 的version count信息

SYS@anqing1(rac1)> selectsql_id,version_count from v$sqlarea where sql_text like 'select * from sys.lctwhere %';

 

SQL_ID        VERSION_COUNT

------------- -------------

5d8tu19t1fug2             2

 

--查看parentcursor 和 child cursor的handle address:

SYS@anqing1(rac1)> selectaddress,child_address from v$sql where sql_id='5d8tu19t1fug2';

 

ADDRESS CHILD_AD

-------- --------

30A9DCDC 2CBA64AC

30A9DCDC 2A32C000

 

將library cache dump出來:

SQL> alter session set events 'immediatetrace name library_cache level 11';

Session altered.

 

SQL> oradebug setmypid

Statement processed.

SQL> oradebug tracefile_name

/oradata/XEZF/admin/udump/xezf_ora_14041.trc

 

--查看trace 文件:搜索30A9DCDC

 

BUCKET 92642:

  LIBRARY OBJECT HANDLE:handle=30a9dcdc mtx=0x30a9dd90(2) cdp=2

 --object handle 的內存地址

name=select * from sys.lct whereobject_name=:x

--object 的名稱

 hash=55555e74e494aa0356a33a0a721769e2 timestamp=07-24-2011 15:03:04

--hash值和timestamp

 namespace=CRSRflags=RON/KGHP/TIM/PN0/SML/KST/DBN/MTX/[120100d0]

--namespace 和 flags 

kkkk-dddd-llll=0000-0001-0001 lock=N pin=0latch#=1 hpc=0006 hlc=0006

--Heaps loaded and kept,lock, pin, and latch modes

 lwt=0x30a9dd38[0x30a9dd38,0x30a9dd38]ltm=0x30a9dd40[0x30a9dd40,0x30a9dd40]

 pwt=0x30a9dd1c[0x30a9dd1c,0x30a9dd1c]ptm=0x30a9dd24[0x30a9dd24,0x30a9dd24]

 ref=0x30a9dd58[0x30a9dd58,0x30a9dd58]lnd=0x30a9dd64[0x30a9dd64,0x30a9dd64]

--以上是:Linklists of lock waiters, temporary locks, pin waiters, temporary pins andreferences

   LOCK OWNERS:

       lock     user  session count mode flags

   -------- -------- -------- ----- ---- ------------------------

   2d1a0cac 30efbd20 30efbd20     2N    [00]

   2d10501c 30f10e78 30f10e78     2N    [00]

 

    LIBRARY OBJECT: object=2aa6cf2c

--Memory address of theobject (heap 0)

   type=CRSR flags=EXS[0001] pflags=[0000] status=VALD load=0

--Object type, flags, andstatus

  CHILDREN: size=16

   child#    table reference   handle

   ------ -------- --------- --------

        02c08c08c  2c08bd5c 2cba64ac

        1 2c08c08c  2c08bec8 2a32c000

--這個就是所有child cursor 的handle 的內存地址

   DATA BLOCKS:

   data#     heap  pointer   status pins change whr

   ----- -------- -------- --------- ---- ------ ---

       0 2b8839b4 2aa6cfc4 I/P/A/-/-    0NONE   00

--Object data structures(heap descriptors)

 BUCKET 92642 total object count=1

 

 

查看其中一個child cursor 地址,在trace 裏搜索:2cba64ac

 

LIBRARY OBJECT HANDLE: handle=2cba64acmtx=0x2cba6560(0) cdp=0

 namespace=CRSR flags=RON/KGHP/PN0/EXP/[10010100]

 kkkk-dddd-llll=0000-0001-0001 lock=N pin=0 latch#=1 hpc=0002 hlc=0002

 lwt=0x2cba6508[0x2cba6508,0x2cba6508] ltm=0x2cba6510[0x2cba6510,0x2cba6510]

 pwt=0x2cba64ec[0x2cba64ec,0x2cba64ec]ptm=0x2cba64f4[0x2cba64f4,0x2cba64f4]

 ref=0x2cba6528[0x2c08bd5c,0x2c08bd5c]lnd=0x2cba6534[0x2cba6534,0x2cba6534]

   CHILD REFERENCES:

   reference latch flags

   --------- ----- -------------------

    2c08bd5c     0 CHL[02]

   LOCK OWNERS:

       lock     user  session count mode flags

   -------- -------- -------- ----- ---- ------------------------

   2d345160 30efbd20 30efbd20     1N    [00]

   2d1a0bdc 30f10e78 30f10e78     1N    [00]

   LIBRARY OBJECT: object=2c1a3280

   type=CRSR flags=EXS/RIV[0201] pflags=[0000] status=VALD load=0

   DEPENDENCIES: count=1 size=16

   dependency#    tablereference   handle position flags

   ----------- -------- --------- -------- -------- -------------------

              0 2db7d838  2db7d770 2bb25644       18 DEP[01]

   AUTHORIZATIONS: count=1 size=16 minimum entrysize=16

   00000000 30000000 00020000 00000000

   ACCESSES: count=1 size=16

   dependency# types

   ----------- -----

              0 0009

   SCHEMA: count=1 size=262144

   0000003d

   DATA BLOCKS:

   data#     heap  pointer   status pins change whr

   ----- -------- -------- --------- ---- ------ ---

       0 2a078574 2c1a3318 I/P/A/-/-    0NONE   00

        6 2aa6d2542c4f9cf0 I/-/A/-/E    0 NONE   00

 

            這個結構和Heap 0的差不多。 但是這個child cursor 沒有name了。 因爲我們訪問時先通過parent cursor。 在到child cursor。所以parent cursor 有name 就可以了。

            這裏的Data blocks 有2個: data block 0和data block 6. 對應heap 0 和heap 6.  關於Heap 0的說明如下:

            The data block structure for a heap, stored in heap 0,contains a pointer to the first data block that is allocated for the heap, astatus indicator, the pin under which the heap is loaded, and so on.

 

            執行計劃保存在Heap 6裏,我們把Heap 6 dump 出來,看一下:

SYS@anqing1(rac1)> alter session setevents 'immediate trace name heapdump_addr level 2,addr0x2aa6d254';

Session altered.

--注意,這裏的addr前面加了0x。

 

SYS@anqing1(rac1)> oradebug setmypid

Statement processed.

SYS@anqing1(rac1)> oradebugtracefile_name

/u01/app/oracle/admin/anqing/udump/anqing1_ora_1533.trc

 

在trace 裏搜索:0x2aa6d254

HEAP DUMP heapname="sql area" desc=0x2aa6d254

 extent sz=0xff4 alt=32767 het=156 rec=0 flg=2opc=2

 parent=0x2000002c owner=0x2aa6d1c8 nex=(nil)xsz=0xff4

EXTENT 0 addr=0x2a73d5e8

 Chunk 2a73d5f0 sz=      788    free     "               "

Dump of memory from 0x2A73D5F0 to0x2A73D904

2A73D5F0 C0000315 00000000 2AA6D2B42AA6D2B4  [...........*...*]

2A73D600 2B10E1FC C0000051 000000002C49E55C  [...+Q.......\.I,]

2A73D610 2AEA8820 00314E00 0000800400010035  [ ..*.N1.....5...]

2A73D620 00930024 00020001 0019003A00020074  [$.......:...t...]

2A73D630 001A0019 000200BF 007400B000500004  [..........t...P.]

2A73D640 001A0024 00BF0033 0003001200010022  [$...3......."...]

2A73D650 62000006 0000024D 2A73D6040C9D040C  [...bM.....s*....]

2A73D660 00000000 2A73D8A0 0035000000240001  [......s*..5...$.]

2A73D670 00010093 003A0002 0074001900190002  [......:...t.....]

2A73D680 00BF001B 00B00002 0004007400240039  [........t...9.$.]

2A73D690 0033001B 001200BF 0022000300060001  [..3.......".....]

2A73D6A0 12021400 00010022 0A000006006B0802  [....".........k.]

2A73D6B0 03671F85 EF042C04 001C004E000C0000  [..g..,..N.......]

2A73D6C0 001D0400 001C0056 000002E0001D0040  [....V.......@...]

2A73D6D0 00B10028 000D0028 008C00260026005E  [(...(...&...^.&.]

2A73D6E0 00A40026 000E000C 0E00002612011201  [&.......&.......]

2A73D6F0 00010022 AC000009 00AF0A0000010021  ["...........!...]

2A73D700 00020074 00210009 001500BF00780026  [t.....!.....&.x.]

....

 

dbsnake blog裏的總結如下:

            heap6實際上就是sql area(這個和上圖中描述的heap 6是sql context不盡相同)。 Oracle把sql的執行計劃存在了這個sql的子cursor的heap 6(也就是sql area)中,只不過存儲的形式是編譯好的二進制格式。

 

MOS 上的相關說明:

            Parsinga cursor builds four different library cache structures, if they do not alreadyexist, within the library cache:

1、parent cursor handle

2、parent cursor object, containing the child dependency list

3、child cursor handle, inserted in the child dependency list of theparent object

4、childcursor object, containing the compilation and run-time execution plan for thecompiled SQL statement.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章