Library Cache internal

Library Cache internal

 

一,library cache的结构

Library cacheshared pool中最重要的一部分,主要存放sql(parent cursorchild cursor)plsql(procedurefunctionpackage)对象的信息,以及这些对象所依赖的tableindex等。

 

1.hash bucket

    Library cachehash bucket来管理,hash bucket由多个object handle组成。

Library Cache internal_第1张图片 

2.object handle

    Object handle存放了对象的namenamespace及相关信息(对象是否只读,是本机的还是远端的等),也存放了当前正在lockpin以及正在等待lockpin该对象的用户的列表等。

Library Cache internal_第2张图片 

3.library cache objects

    Library cache objects由多个独立的data heap组成,object handle存放指向第一个data heap(heap 0)的指针,heap 0存放指向其他data heap的指针。任何对象都有heap 0,至于其它的heap则由对象的类型决定,比如sql cursor具有heap 1heap 6plsql程序包则具有heap 1234。那么,对于sql cursor来说,heap 0就存放指向heap 1heap 6的指针。

当进程需要寻找一个对象时,library cache manager就会使用hash算法定位到相应的object handle。如果object handle还在,但是相关的object heap已经被刷出内存,此时object heap就要被重新reload(v$librarycache.reloads);如果,进程发现相关object的定义已经被更改(v$librarycache.invalidations),此时进程就要重新解析相关对象。

 

4.data heap

Library cache的全局结构如下图:

Library Cache internal_第3张图片 

4.1 data heap 0

 

如图,Heap 0包含以下信息:

– Type

Objects are grouped in namespaces according to their type.

Each object can only be of one type.

All the objects of the same type are in the same namespace.

A namespace may be used by more than one type.

The most important namespace is called cursor(CRSR) and houses the shared SQL cursors.

– Name

Library cache object names have three parts:

– Name of schema

– Name of object

- For shared cursors (SQL statements or anonymous PL/SQL blocks) the name is the entire text string that makes the cursor itself. For example, select * from employees. Note that this is different from select * from hr.employees or even select* from EMPLOYEES. Every character, including the case, is taken into consideration.

- For the rest of the objects (tables, views, indexes, and so on) the name is the one given to the object at creation time. 
通过dump文件来看,sql text存放在handle下面,不是放在heap 0里面的。不知道此处的entire text string指的是什么???(望广大网友帮忙澄清一下)

– Name of database link (remote objects only)

The format used is SCHEMA.NAME@DBLINK.

For example, [email protected]

Child cursor没有name,通过parent cursor来访问。

– Flags

Public flags:

– Are not protected by pins or latches

– Indicate in detail the type of the object

Status flags:

– Are protected by pins

– Indicate whether the object is being created/dropped/altered/updated

Special status flags:

– Are protected by the library cache latch

– Are related to object validity and authorization

– Tables

Dependency table

Child table

只有cursor才有子对象,一个sql语句至少有一个parent cursor(heap 0)和一个child cursor(heap 1heap 6),但是出于某种原因,比如1sql语句的对象是不同用户下的同名对象;2sql语句使用了不同类型的绑定变量;3,执行sql语句的会话的优化器模式不同等。就会出现一个parent cursor对应多个child cursor的情况(v$sqlarea.version_count)Parent cursor对应的所有child cursor的指针都存放在child table里面。Child cursor除了没有name,其结构和parent cursor一样,parent cursor也只是存放指向child cursor的指针,而child cursor存放指向其依赖对象的指针。

Translation table

Authorization table

Access table

Read-only dependency table

Schema name table

– Data blocks

The remainder of an object’s data is stored in other independent data heaps.

The object structure contains an array of data block structures.

The data block structures have a pointer to a different data heap.

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

一个对象由多个不同的data heap组成,object handle存放指向 data heap0的指针,而data heap0中的data blocks就是用来存放指向其他data heap的指针

 

4.2 other data heap

 

Library Cache internal_第4张图片 

a SQL cursor has heaps 1 and 6, while a PL/SQL procedure may have heaps 1, 2, 3,and 4.

 

Heap 0 (Object): Stores the object structure

Heap 1 (Source): Stored the source code for a PL/SQL object

Heap 2 (Diana) : Contains the DIANA (Parse tree metadata) for a PL/SQL object

Heap 3 (Pcode): Stores the pseudocode for a PL/SQL object

Heap 4 (Mcode): Machine-dependent pseudocode for a PL/SQL object

Heap 5 (Errors): Stores compilation errors

Heap 6 (SQL Context): Contains context information for a shared cursor object

Heap 7: Free (not used)

Heaps 811: Subordinate heaps that are used for different purposes depending on the object

 

二、Sql对象

 

1.父游标

 

    每一个sql语句都包含一个父游标和一个或多个子游标。

Library Cache internal_第5张图片 

父游标由KGLHD - Handle structure、KGLOB - Object structure、KGLNA - Name structure组成。

Objects are joined with their handles in X$KGLOB.Julian Dyke的图如下:

Library Cache internal_第6张图片

SQL> conn test/test

Connected.

SQL> select count(*) from tt;

 

  COUNT(*)

----------

   3318546

 

SQL> select sql_id,address,hash_value,sql_text from v$sql where sql_text like 'select count(*) from tt';

 

SQL_ID        ADDRESS          HASH_VALUE SQL_TEXT

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

cm6stbx539mcz 0000000393558EE8 1244974495 select count(*) from tt

 

SQL> select * from x$kglna where kglnahsh=1244974495;

 

ADDR                   INDX    INST_ID KGLHDADR           KGLNAHSH   KGLOBOCT KGLNASQLID         PIECE NAME

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

FFFFFD7FFDA53A88          0          1 0000000393558EE8 1244974495          3 cm6stbx539mcz          0 select count(*) from tt

由此可见,kglna描述的是sql_text的相关信息。

V$sqlarea一行代表一个父游标。

 

2.子游标

 

    子游标和父游标有着类似的结构,也都包含Handle structure、Object structure,子游标还包含sql语句的执行计划等,此处,heap6存放的就是sql语句的执行计划。

 Library Cache internal_第7张图片

Library Cache internal_第8张图片

再用不同的用户执行select count(*) from tt,使得生成一个新的child cursor:

 

SQL> select kglhdadr,kglhdpar,kglobsta,kglnaobj from x$kglob where kglnahsh=1244974495;

 

KGLHDADR         KGLHDPAR parent)          KGLOBSTA KGLNAOBJ

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

0000000393557FB8 0000000393558EE8          1 select count(*) from tt

0000000393558EE8 0000000393558EE8          1 select count(*) from tt

 

第一行是子游标,第二行是父游标(kglhdadr=kglhdpar)。

V$sql一行代表一个子游标。由此可见,v$sqlareav$sql的区别是v$sqlarea是在v$sql的基础上以相同的sql_text做的group by

 

3.造成cursor不共享的原因

 

造成parent cursor不共享的原因是sql语句的写法不同,比如,关键字的大小写不同等。

造成child cursor不共享的原因是1,系统或会话参数不同。2,同名对象但不属于同一用户。3,绑定变量类型不同。4nls参数不同

V$sql_shared_cursor视图可以查看cursor不共享的原因。如果一个parent cursor存在多个child cursor,那么在此视图中,第一个child cursorboolean值为N

      以下为优化器环境不同造成的cursor不共享:

SQL> show parameter optimizer 

 

NAME                                 TYPE        VALUE

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

optimizer_dynamic_sampling           integer     2

optimizer_features_enable            string      10.2.0.4

optimizer_index_caching              integer     0

optimizer_index_cost_adj             integer     100

optimizer_mode                       string      CHOOSE

optimizer_secure_view_merging        boolean     TRUE

SQL> select count(*) from test.tt;

 

  COUNT(*)

----------

   3318546

 

SQL> alter session set optimizer_mode=all_rows;

 

Session altered.

 

SQL> select count(*) from test.tt;

 

  COUNT(*)

----------

   3318546

 

SQL> select address,child_address,sql_text from v$sql where sql_text like 'select count(*) from test.tt';

 

ADDRESS          CHILD_ADDRESS    SQL_TEXT

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

00000003935DF758 000000039384BAA0 select count(*) from test.tt

00000003935DF758 0000000393272008 select count(*) from test.tt

 

SQL> select kglhdadr,kglhdpar,kglobsta,kglnaobj from x$kglob where kglnahsh=458373349;

 

KGLHDADR         KGLHDPAR           KGLOBSTA KGLNAOBJ

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

000000039384BAA0 00000003935DF758          1 select count(*) from test.tt

0000000393272008 00000003935DF758          1 select count(*) from test.tt

00000003935DF758 00000003935DF758          1 select count(*) from test.tt

 

SQL> select child_number,child_address,optimizer_mode_mismatch from v$sql_shared_cursor where address='00000003935DF758';

 

CHILD_NUMBER CHILD_ADDRESS    OPTIMIZER_MODE_MISMATCH

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

           0 000000039384BAA0 N

           1 0000000393272008 Y

还有许多其它因素造成cursor的不共享。

4.library cache dump

    使用以下命令dump library cache

ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME LIBRARY_CACHE LEVEL n';

where <n> specifies information to be included

1 - include library cache statistics

2 - include library cache hash table

4 - include library cache handles and objects

8 - include dependencies, read-only dependencies, accesses, authorizations, translations, schemas and data blocks

16 - include sizes for data blocks

32 - include heap dumps for data blocks 

 

SQL> conn test/test

Connected.

SQL> select count(*) from t;

 

  COUNT(*)

----------

         1

SQL> alter session set tracefile_identifier=111; 

 

Session altered.

 

SQL> alter session set events 'immediate trace name library_cache level 8';

 

Session altered.

 

SQL> select hash_value,address,child_address,sql_text from v$sql where sql_text like 'select count(*) from t';

 

HASH_VALUE ADDRESS          CHILD_ADDRESS    SQL_TEXT

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

2763161912 0000000393B710A8 0000000393B71590 select count(*) from t

2763161912 0000000393B710A8 0000000393D45D20 select count(*) from t

 

根据hash_valuedump文件中寻找

SQL> select to_char(2763161912,'xxxxxxxxxxxxxxx') from dual;

 

TO_CHAR(27631619

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

        a4b28138

Parent cursor

BUCKET 33080:

  LIBRARY OBJECT HANDLE: handle=393b710a8 mtx=393b711d8(2) cdp=2

  name=select count(*) from t    ----验证了sql_text是放在handle下面的

  hash=10bef657c8a7ea0dcf7ff45fa4b28138 timestamp=12-04-2013 15:01:12

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

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

  lwt=393b71150[393b71150,393b71150] ltm=393b71160[393b71160,393b71160]

  pwt=393b71118[393b71118,393b71118] ptm=393b71128[393b71128,393b71128]

  ref=393b71180[393b71180,393b71180] lnd=393b71198[393b71198,393b71198]

    LIBRARY OBJECT: object=393b70a38

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

    CHILDREN: size=16    ----存放的是child cursor的信息。Child table初始大小为16,也就是说初始可以存放

    child#    table reference   handle    16个子游标的信息,但为了性能考虑最好不要超过16个。

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

         0 393b70500 393b70170 393b71590

         1 393b70500 393b703f0 393d45d20    ----找寻此handlechild cursor

    DATA BLOCKS:

    data#     heap  pointer    status pins change whr

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

        0 393b70fe8 393b70b50 I/P/A/-/-    0 NONE   00 

  BUCKET 33080 total object count=1

 

Child cursor

 LIBRARY OBJECT HANDLE: handle=393d45d20 mtx=393d45e50(0) cdp=0

  namespace=CRSR flags=RON/KGHP/PN0/EXP/[10010100]    ----child cursor没有name

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

  lwt=393d45dc8[393d45dc8,393d45dc8] ltm=393d45dd8[393d45dd8,393d45dd8]

  pwt=393d45d90[393d45d90,393d45d90] ptm=393d45da0[393d45da0,393d45da0]

  ref=393d45df8[393b703f0,393b703f0] lnd=393d45e10[393d45e10,393d45e10]

    LIBRARY OBJECT: object=393d45850

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

    DEPENDENCIES: count=1 size=16

    dependency#    table reference   handle position flags

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

              0 393d44318 393d44058 393d4c0b8       21 DEP[01]    ----找寻cursor的依赖表T

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

    00000000 3a000000 00020000 00000000 

    ACCESSES: count=1 size=16

    dependency# types

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

              0 0009

    TRANSLATIONS: count=1 size=16

    original    final

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

    393d4c0b8 393d4c0b8

    DATA BLOCKS:

    data#     heap  pointer    status pins change whr

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

        0 393d45c60 393d45968 I/-/A/-/-    0 NONE   00 

        6 393b70290 393d450b8 I/-/A/-/E    0 NONE   00      ----heap 6保存的是cursor的执行计划。

 

Dependency table

BUCKET 109969:

  LIBRARY OBJECT HANDLE: handle=393d4c0b8 mtx=393d4c1e8(0) cdp=0

  name=TEST.T 

  hash=776506cbf60f0b9d0c63341052d5ad91 timestamp=12-04-2013 15:01:56

  namespace=TABL flags=KGHP/TIM/SML/[02000000]

  kkkk-dddd-llll=0000-0741-0741 lock=0 pin=0 latch#=1 hpc=0004 hlc=0004

  lwt=393d4c160[393d4c160,393d4c160] ltm=393d4c170[393d4c170,393d4c170]

  pwt=393d4c128[393d4c128,393d4c128] ptm=393d4c138[393d4c138,393d4c138]

  ref=393d4c190[393d4c190,393d4c190] lnd=393d4c1a8[3940dfb20,393d40c00]

    LIBRARY OBJECT: object=393d4bbe8

    type=TABL flags=EXS/LOC[0005] pflags=[0000] status=VALD load=0

    DATA BLOCKS:

    data#     heap  pointer    status pins change whr

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

        0 393d4bff8 393d4bd40 I/-/A/-/-    0 NONE   00 

        8 393d4b118 393d4aec0 I/-/A/-/-    0 NONE   00 

  BUCKET 109969 total object count=1

 

Parent cursorchild cursor的结构如下:

Library Cache internal_第9张图片 

你可能感兴趣的:(Library Cache internal)