[20210602]分析library cache轉儲 5.txt

lfree發表於2021-06-02

[20210602]分析library cache轉儲 5.txt

--//連結http://blog.itpub.net/267265/viewspace-2773571/=》[20210524]分析library cache轉儲 3.txt
--//繼續測試多個sql語句hash_value值相同的情況,說明一點實際上並不是hash_value一樣才會在一個bucket,
--//我的測試環境僅僅有131072個buecket,好像很大記憶體的配置也是131072個bucket。
--//131072 = 0x20000,也就是full_hash_vlue & 0x1ffff ,相當於後21bit相等的都會在一個bucket裡面。
--//當然hash_value一樣一定在一個bucket 裡面。

--//有朋友提示這個連結是雙向的,也許我執行oradebug peek看到的資訊不全,完善這個測試。
--//參考連結:http://blog.itpub.net/267265/viewspace-2773591/

1.環境:
SCOTT@book> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

2.找到一些sql語句hash_value一樣。
--//參考http://externaltable.blogspot.com/2012/06/hash-collisions-sql-signatures-and.html
--//花了一個下午找到僅僅有4個hash_value,注本來想找到20個以上的情況,不現實放棄。

SCOTT@book> create table dula as select * from dual ;
Table created.

define SQL1='select sysdate from dual --'
define SQL2='select sysdate from dula --'

  SELECT hashval
        ,SUBSTR (hashval, 25, 8)
        ,sql_type
        ,DECODE (sql_type,  1, '&SQL1',  2, '&SQL2',  NULL) || SQL || ';'
            sql_text
    FROM HASH_1
   WHERE SUBSTR (hashval, 25, 8) IN (  SELECT SUBSTR (hashval, 25, 8)
                                         FROM HASH_1
                                     GROUP BY SUBSTR (hashval, 25, 8)
                                       HAVING COUNT (*) > 3)
ORDER BY SUBSTR (hashval, 25, 8);

HASHVAL                                  SUBSTRHASHVAL,2    SQL_TYPE SQL_TEXT
---------------------------------------- ---------------- ---------- ------------------------------------------------------------
7fa0440cb576468eee514bd1865821d8         865821d8                  2 select sysdate from dula --QVJzuaXTQDRWAMQsUKRahCOmcllpAYLn;
9d524191de77830512606b60865821d8         865821d8                  2 select sysdate from dula --hBaTOrXVlpVzFMMfuJFHWWksdoGuzZdc;
4823f0eab9589f52ce20856e865821d8         865821d8                  1 select sysdate from dual --heqVJLdwOOvUbNnwDpaMwowplkAymAhs;
85e2a9308c0fdac36dd09edd865821d8         865821d8                  1 select sysdate from dual --SYWAvXlLqpLVnKmYQGOJxklMrToCdoUD;
--//這裡記錄的HASHVAL與實際hash_value大小頭要對調一下。

$ cat aa1.txt
select sysdate from dula --QVJzuaXTQDRWAMQsUKRahCOmcllpAYLn;
@ hash
select sysdate from dula --hBaTOrXVlpVzFMMfuJFHWWksdoGuzZdc;
@ hash
select sysdate from dual --heqVJLdwOOvUbNnwDpaMwowplkAymAhs;
@ hash
select sysdate from dual --SYWAvXlLqpLVnKmYQGOJxklMrToCdoUD;
@ hash

--//執行如下:
SCOTT@book> @ aa1.txt
SYSDATE
-------------------
2021-05-24 09:10:30

HASH_VALUE SQL_ID        CHILD_NUMBER HASH_HEX
---------- ------------- ------------ ---------
3626064006 d2kujxvc22q46            0  d8215886

SYSDATE
-------------------
2021-05-24 09:10:30

HASH_VALUE SQL_ID        CHILD_NUMBER HASH_HEX
---------- ------------- ------------ ---------
3626064006 60uv02bc22q46            0  d8215886

SYSDATE
-------------------
2021-05-24 09:10:30

HASH_VALUE SQL_ID        CHILD_NUMBER HASH_HEX
---------- ------------- ------------ ---------
3626064006 6x190tvc22q46            0  d8215886

SYSDATE
-------------------
2021-05-24 09:10:30

HASH_VALUE SQL_ID        CHILD_NUMBER HASH_HEX
---------- ------------- ------------ ---------
3626064006 dv7qhdrc22q46            0  d8215886

--//執行多次可以發現HASH_VALUE一樣,記住sql_id 分別是d2kujxvc22q46,60uv02bc22q46,6x190tvc22q46,dv7qhdrc22q46。
--//位於 bueckt = 3626064006 % 131072  = 88198,88198 = 0x15886。

3.轉儲library cache:
SYS@book> oradebug setmypid
Statement processed.
SYS@book> @ tix
New tracefile_identifier =  /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_36826_0001.trc

SYS@book> oradebug dump library_cache 10;
Statement processed.

--//單獨把Bucket: #=88198內容儲存為一個檔案(bucket88198a.txt)便於分析。

$ grep "select sysdate from du" bucket88198a.txt
    ObjectName:  Name=select sysdate from dual --SYWAvXlLqpLVnKmYQGOJxklMrToCdoUD
    ObjectName:  Name=select sysdate from dual --heqVJLdwOOvUbNnwDpaMwowplkAymAhs
    ObjectName:  Name=select sysdate from dula --hBaTOrXVlpVzFMMfuJFHWWksdoGuzZdc
    ObjectName:  Name=select sysdate from dula --QVJzuaXTQDRWAMQsUKRahCOmcllpAYLn
//顯示的順序正好與前面的執行順序相反。

$ egrep "sql_id|^  LibraryHandle" bucket88198a.txt
  LibraryHandle:  Address=0x7edc8b38 Hash=d8215886 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD
      Parent Cursor:  sql_id=dv7qhdrc22q46 parent=0x807b2930 maxchild=1 plk=y ppn=n
  LibraryHandle:  Address=0x7ed68170 Hash=d8215886 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD
      Parent Cursor:  sql_id=6x190tvc22q46 parent=0x807b7930 maxchild=1 plk=y ppn=n
  LibraryHandle:  Address=0x7efafac0 Hash=d8215886 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD
      Parent Cursor:  sql_id=60uv02bc22q46 parent=0x7eeda690 maxchild=1 plk=y ppn=n
  LibraryHandle:  Address=0x7ed683c0 Hash=d8215886 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD
      Parent Cursor:  sql_id=d2kujxvc22q46 parent=0x7efadae0 maxchild=1 plk=y ppn=n

 $ head -1 bucket88198a.txt
Bucket: #=88198 Mutex=0x815b4150(0, 15, 0, 6)
--//mutex地址0x815b4150,減去0x10 就是bucket的地址:0x815b4140,注意測試輸出的mutex地址與上次不同。

SYS@book> oradebug peek 0x815b4140 40
[0815B4140, 0815B4168) = 7EDC8B38 00000000 7ED683C0 00000000 00000000 00000000 0000000F 00000000 00015886 00000000

--//注意看前16位元組,0x7edc8b38正好是sql_id=dv7qhdrc22q46的父遊標控制程式碼地址。0x7ED683C0正好是sql_id=d2kujxvc22q46的 父遊標控制程式碼地址.
--//這樣bucket記錄的前8位就是連結串列的尾部,後8位就是連結串列的開頭。如何連結起來的呢?
--//後記:看了後面的分析,感覺應該反過來,前8位就是連結串列的開頭(最後執行的sql語句父遊標控制程式碼),後8位就是連結串列的尾部。

4.看看如何連結:
--//我以前測試可以發現父遊標控制程式碼的地址減去0x30正好就是父遊標控制程式碼chunk的開始地址。

SYS@book> @ fcha 0x7EDC8B38
Find in which heap (UGA, PGA or Shared Pool) the memory address 0x7EDC8B38 resides...

WARNING!!! This script will query X$KSMSP, which will cause heavy shared pool latch contention
in systems under load and with large shared pool. This may even completely hang
your instance until the query has finished! You probably do not want to run this in production!

Press ENTER to continue, CTRL+C to cancel...

LOC KSMCHPTR           KSMCHIDX   KSMCHDUR KSMCHCOM           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR
--- ---------------- ---------- ---------- ---------------- ---------- -------- ---------- ----------------
SGA 000000007EDC8B08          6          1 KGLHD                   592 recr             80 00

--//0x000000007EDC8B08 0x7EDC8B38 正好相差0x30.後面的不再執行fcha,不然寫的太長..

SYS@book> @ tix
New tracefile_identifier =  /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_40996_0003.trc

oradebug peek 0x7EDC8B38 60 1
oradebug peek 0x7ed68170 60 1
oradebug peek 0x7efafac0 60 1
oradebug peek 0x7ed683c0 60 1
--//注:直接使用上面的地址轉儲。

SYS@book> oradebug peek 0x815b4140 40
[0815B4140, 0815B4168) = 7EDC8B38 00000000 7ED683C0 00000000 00000000 00000000 00000014 00000000 00015886 00000000

SYS@book> oradebug peek 0x7EDC8B38 60 1
[07EDC8B38, 07EDC8B74) = 7ED68170 00000000 815B4140 00000000 807B2890 00000000 7EDC8C90 00000000 00010000 10012841 00000001 00000001 00010001 00000002 00000000
                        ~~~~~~~~~~~~~~~~~##################
--//注意看下劃線0x7ED68170對應寫一個要peek的地址,而####對應的就是0x815b4140就是bucket的地址。

SYS@book> oradebug peek 0x7ed68170 60 1
[07ED68170, 07ED681AC) = 7EFAFAC0 00000000 7EDC8B38 00000000 807B7890 00000000 7ED682C8 00000000 00010000 10012841 00000001 00000001 00010001 00000002 00000000

SYS@book> oradebug peek 0x7efafac0 60 1
[07EFAFAC0, 07EFAFAFC) = 7ED683C0 00000000 7ED68170 00000000 7EEDA5F0 00000000 7EFAFC18 00000000 00010000 10012841 00000001 00000001 00010001 00000002 00000000

SYS@book> oradebug peek 0x7ed683c0 60 1
[07ED683C0, 07ED683FC) = 815B4140 00000000 7EFAFAC0 00000000 7EFADA40 00000000 7ED68518 00000000 00010000 10012841 00000001 00000001 00010001 00000002 00000000

--//注意看前面的8位,7ED68170,7ED683C0,7ED683C0,815B4140。
--//這不正好與前面看到LibraryHandle的地址對應上嗎,
--//再繼續看接下來的8位:815B4140,7EDC8B38,7ED68170,7EFAFAC0。

--//這樣兩條鏈就形成了雙向連結。

$  egrep "^  LibraryHandle" bucket88198a.txt
  LibraryHandle:  Address=0x7edc8b38 Hash=d8215886 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD
  LibraryHandle:  Address=0x7ed68170 Hash=d8215886 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD
  LibraryHandle:  Address=0x7efafac0 Hash=d8215886 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD
  LibraryHandle:  Address=0x7ed683c0 Hash=d8215886 LockMode=N PinMode=0 LoadLockMode=0 Status=VALD

4.疑問:
--//就是知道了hash_value,就能計算使用那個buckect,但是oracle如何快速定位那個bucket呢,oracle的library cache bucket好像是按需分配的。
--//被分成好幾個chunk,顯然無法簡單的計算 基地址 + 40*buckect值 獲得偏移,有時間在仔細測試與觀察看看。

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

相關文章