作者: fuyuncat
来源: www.HelloDBA.com
4. Dump 内存解析
下面以 shared pool 为例,解释一下 dump 出来的内存结构。
SQL> conn sys/sys as sysdba Connected. SQL> oradebug setmypid Statement processed. SQL> oradebug dump heapdump 2 Statement processed.
SQL>
以下时 trace 文件的内容,我们分别解释各个部分:
Dump file c:/oracle/product/10.2.0/admin/fuyuncat/udump/fuyuncat_ora_4032.trc
Tue Jul 11 16:03:26 2006
ORACLE V10.2.0.1.0 - Production vsnsta=0
vsnsql=14 vsnxtr=3
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Windows XP Version V5.1 Service Pack 2
CPU : 2 - type 586
Process Affinity : 0x00000000
Memory (Avail/Total): Ph:885M/2039M, Ph+PgF:2702M/3890M, VA:1590M/2047M
Instance name: fuyuncat Redo thread mounted by this instance: 1
Oracle process number: 18
Windows thread id: 4032, image: ORACLE.EXE (SHAD)
*** SERVICE NAME:(SYS$USERS) 2006-07-11 16:03:26.322
*** SESSION ID:(159.7) 2006-07-11 16:03:26.322
这部分是关于 trace 文件的基本信息, oracle 版本、资源情况、用户和会话等。
KGH Latch Directory Information
ldir state: 2 next slot: 75
Slot [ 1] Latch: 03C3D280 Index: 1 Flags: 3 State: 2 next: 00000000
Slot [ 2] Latch: 1EC9D4B0 Index: 1 Flags: 3 State: 2 next: 00000000
Slot [ 3] Latch: 1EC9D540 Index: 1 Flags: 3 State: 2 next: 00000000
Slot [ 4] Latch: 03C3E100 Index: 1 Flags: 3 State: 2 next: 00000001
Slot [ 5] Latch: 1ED65CE4 Index: 1 Flags: 3 State: 2 next: 00000000
Slot [ 6] Latch: 1ED65F14 Index: 1 Flags: 3 State: 2 next: 00000000
... ...
这部分记录的是 shared pool 中的 latch 信息。每个 latch 的具体信息可以通过视图 V$LATCH 、 V$LATCH_PARENT 、 V$LATCH_CHILDREN 或者表 x$ksllt 查出
******************************************************
HEAP DUMP heap name="sga heap" desc=03C38510
extent sz=0x32c8 alt=108 het=32767 rec=9 flg=-126 opc=0
parent=00000000 owner=00000000 nex=00000000 xsz=0x10
******************************************************
这是堆 dump 信息的头部, heap name 说明了内存所述的堆, shared pool 是属于 SGA 区的,因此,这里是 "sga heap" ;
extent sz 记录的是所有扩展段的大小。
HEAP DUMP heap name="sga heap(1,0)" desc=04EC131C
extent sz=0xfc4 alt=108 het=32767 rec=9 flg=-126 opc=0
parent=00000000 owner=00000000 nex=00000000 xsz=0x400000
EXTENT 0 addr=1CC00000
Chunk 1cc00038 sz= 24 R-freeable "reserved stoppe"
Chunk 1cc00050 sz= 212888 R-free " "
Chunk 1cc33fe8 sz= 24 R-freeable "reserved stoppe"
Chunk 1cc34000 sz= 3977544 perm "perm " alo=3977544
Chunk 1cfff148 sz= 3768 free " "
EXTENT 1 addr=1D000000
Chunk 1d000038 sz= 24 R-freeable "reserved stoppe"
Chunk 1d000050 sz= 212888 R-free " "
Chunk 1d033fe8 sz= 24 R-freeable "reserved stoppe"
Chunk 1d034000 sz= 2097168 perm "perm " alo=2097168
这部分信息是 trace 文件中的主要部分,它详细记录了 shared pool 中各个 chunk 的信息。
首先看它的头部信息,注意到这里 heap name 是 "sga heap(1,0)" 。这是什么意思呢?我们前面提到, oracle 10g 会将 shared pool 分为几个区来管理,这里就是其中的一个区。共有 4 个区。通过表 X$KGHLU 可以看到对应的 LRU 链表。
EXTENT 0 addr=1CC00000
这一行说明下面的 chunk 都属于这个扩展段( extent ), 0 是它的编号, addr 是它的起始地址。
Chunk 1cc00038 sz= 24 R-freeable "reserved stoppe"
这是一个 chunk 的信息, sz 是这个 chunk 的大小( 24 字节)。 R-freeable 是这个 chunk 的状态, "reserved stoppe" 是这个 chunk 的用途。 Chunk 有 4 种可能状态,以下是这四种状态的含义:
free :即空闲 chunk ,可以随时分配给适合大小的请求;
freeable :这种状态的 chunk 表示它当前正在被使用,但是这种使用是短期的,比如在一次调用中或者一个会话中,会话或者调用解释就可以被释放出来。这种状态的 chunk 是不放在 LRU 链表中的,一旦使用结束,自动成为 free 状态,放到空闲列表中;
recreatable :这种状态的 chunk 正在被使用,但是它所包含的对象是可以被暂时移走、重建,比如解析过的语句。它是被 LRU 链表管理的。
permanent :顾名思义,这种状态的 chunk 所包含的对象是永远不会被释放的。即使 flush shared pool 也不会释放。
我们注意到,这里还有一些状态是有前缀“ R- ”的。带有这种前缀的 chunk 说明是 shared pool 中的保留区的 chunk 。
Total heap size = 41942480
最后是这一 shared pool 区的总的大小。
FREE LISTS:
Bucket 0 size=16
Bucket 1 size=20
Chunk 166ed050 sz= 20 free " "
Chunk 167de068 sz= 20 free " "
Chunk 164b9c10 sz= 20 free " "
Chunk 1f2776f8 sz= 20 free " "
接下来便是这个 shared pool 区的空闲列表。 Bucket 是一个空闲列表的范围,例如 Bucket 1 ,它的最小值是上一个 Bucket 的最大值,即 16 ,最大值为 20 。 Bucket 下面是空闲列表中 chunk ,后面的信息和前面解释 chunk 的信息一样, 8 位的 16 进制数字是它的地址; sz 是 chunk 的大小; free 是 chunk 的状态,因为是空闲列表中的 chunk ,这里只有一个状态;最后是 chunk 的用途,因为都是 free ,所以肯定为空。
Total free space = 1787936
最后是这块 shared pool 区中空闲 chunk 的总的大小。
RESERVED FREE LISTS:
Reserved bucket 0 size=16
Reserved bucket 1 size=4400
Reserved bucket 2 size=8204
Reserved bucket 3 size=8460
Reserved bucket 4 size=8464
Reserved bucket 5 size=8468
Reserved bucket 6 size=8472
Reserved bucket 7 size=9296
Reserved bucket 8 size=9300
Reserved bucket 9 size=12320
Reserved bucket 10 size=12324
Reserved bucket 11 size=16396
Reserved bucket 12 size=32780
Reserved bucket 13 size=65548
Chunk 1b800050 sz= 212888 R-free " "
Chunk 16c00050 sz= 212888 R-free " "
Chunk 1ac00050 sz= 212888 R-free " "
Total reserved free space = 638664
Shared pool 的普通区的空闲列表下面就是关于这块 shared pool 区中保留区的空闲列表的描述,其中除了在名字上 bucket 前面都有一个 Reserved 标识,和状态前面有“ R- ”前缀外,含义和普通空闲列表相同。
UNPINNED RECREATABLE CHUNKS (lru first):
Chunk 1aee99c0 sz= 4096 recreate "sql area " latch=1D8BDD48
Chunk 1ae4aeec sz= 4096 recreate "sql area " latch=1D8BDDB0
... ...
SEPARATOR
Chunk 166e8384 sz= 540 recreate "KQR PO " latch=1DD7F138
Chunk 1f333a5c sz= 284 recreate "KQR PO " latch=1DC7DFC8
Chunk 166e9340 sz= 540 recreate "KQR PO " latch=1DE00A70
Chunk 1f0fe058 sz= 284 recreate "KQR PO " latch=1DC7DFC8
Chunk 1f2116b4 sz= 540 recreate "KQR PO " latch=1DE81910
Chunk 1f21127c sz= 540 recreate "KQR PO " latch=1DE81910
... ...
Unpinned space = 1611488 rcr=645 trn=864
空闲列表后面就是 LRU 链表了。 LRU 链表不是按照大小分的,因而没有 Bucket 。它的 chunk 是按照最近最少使用的顺序排列。其中 chunk 的信息和前面解释的一样。但是要注意一点,因为 LRU 链表中的 chunk 都是使用的,因为每个 chunk 根据用途不同,都会有一个 latch 来保护, Chunk 信息最后便是 latch 的地址。
注意,我们前面提到, shared pool 中是有两种 LRU 链表的,一种循环 LRU 链表;另外一种是暂时 LRU 链表。在这里 LRU 信息中前面部分是循环 LRU 链表, SEPARATOR 后面部分是暂时 LRU 链表信息。
最后是 LRU 链表中 chunk 的总的大小, rcr 是循环 LRU 链表中的 chunk 数, trn 是暂时 LRU 链表中的 chunk 数。
此外,有一点提示,如果是有多个 shared pool 区,第一个区是不含 LRU 链表信息的。
PERMANENT CHUNKS:
Chunk 1d234010 sz= 1884144 perm "perm " alo=1728440
Chunk 1cc34000 sz= 3977544 perm "perm " alo=3977544
Chunk 1d034000 sz= 2097168 perm "perm " alo=2097168
Chunk 1d434000 sz= 3117112 perm "perm " alo=3117112
... ...
Chunk 1f434000 sz= 3917704 perm "perm " alo=3917704
Permanent space = 38937696
最后是永久 chunk 的信息。 Chunk 部分解释和前面一致。 alo 表示已经分配的大小。
如果有多个 shared pool 区,永久 chunk 信息则只存在于第一个 shared pool 区。