1. 在游标存在多个child crusor时,结构如上图。有一个非常重要的结构上图没画出来,就是data blocks会指向heap堆,就是海波说的heap 6。
从你的实验清晰的看出child cursor占用的heap内存,在对象的结构发生变更后,可以被释放,也就是data blocks指向的heap内存可以被释放。
但是各个child cursor的原信息metadata还是保留的,也就是lco信息还是保留的,只是lco里data blocks指向的heap堆被清除了。我dump了一
个测试库的library cache,一个有将近两千version_count的sql在v$sql 里只有六条记录。Dump文件里父lco里也的确记录了2000个child cursor,
而且这2000个child cursor的headler在dump文件里都能够找到。只是分析dump文件后只有六个cursor的是有效的,其余都是无效的。截取一
个无效的dump记录如下,并且关注一下最后的一句提示:LIBRARY OBJECT last freed from HPD addn data CBK
Dump内容如下:
LIBRARY HANDLE:0x6fa36308 bid=0 hid=0 lmd=0 pmd=0 sta=INVL
exc=4 ivc=2 ldc=2 slc=0 lct=18 pct=24
cbb=9 rpr=9 kdp=0 kep=0 bus=0 hus=0 dbg=0
dmtx=0x6fa363b0(0, 0, 0) mtx=0x69161f00(993, 291, 0)
nsp=CRSR(00) typ=CRSR(00) llm=0 flg=RON/KGHP/FUL/PN0/EXP/[14012100]
lwt=0x6fa36390[0x6fa36390,0x6fa36390]
pwt=0x6fa36370[0x6fa36370,0x6fa36370]
ref=0x6fa363a0[0xad3f8e68,0xad3f8e68]
HANDLE REFERENCES:
reference handle flags
--------- --------- -------------------
ad3f8e68 69161df0 CHL[02]
LIBRARY OBJECT last freed from HPD addn data CBK
而正常的cursor的dump会有 data blocks信息,如下,请关注下红色部分:
LIBRARY HANDLE:0x715e3110 bid=0 hid=0 lmd=N pmd=0 sta=VALD
exc=3 ivc=0 ldc=1 slc=1 lct=3 pct=4
cbb=1 rpr=1 kdp=0 kep=0 bus=0 hus=0 dbg=0
dmtx=0x715e31b8(0, 0, 0) mtx=0x7519b1a0(1310, 47, 0)
nsp=CRSR(00) typ=CRSR(00) llm=0 flg=RON/KGHP/PN0/EXP/[10012100]
lwt=0x715e3198[0x715e3198,0x715e3198]
pwt=0x715e3178[0x715e3178,0x715e3178]
ref=0x715e31a8[0x6b9a55d8,0x6b9a55d8]
HANDLE REFERENCES:
reference handle flags
--------- --------- -------------------
6b9a55d8 7519b090 CHL[02]
LOCK OWNERS:
lock user session count mode flags
-------- -------- -------- ----- ---- ------------------------
69f85130 b13b01a0 b13b01a0 1 N [00]
LIBRARY OBJECT: 0x93c7c9b8
flg=EXS[0001] pfl=[0000] ssta=VALD
DEPENDENCIES: count=1 size=16
dependency# table reference handle position flags
----------- -------- --------- -------- -------- -------------------
0 741d6f30 741d6c70 697d7fd0 142 DEP[01]
AUTHORIZATIONS: count=1 size=16 minimum entrysize=16
00000000 00000000 00020000 00000000
ACCESSES: count=1 size=16
dependency# types
----------- -----
0 0009
TRANSLATIONS: count=1 size=16
original final
-------- --------
697d7fd0 697d7fd0
DATA BLOCKS:
data# heap pointer status pins change whr
----- -------- -------- --------- ---- ------ ---
0 75fbea90 93c7ca98 93c7c988 I/P/A/-/- 0 NONE 00
6 6b9a53a8 aee0f6b8 aee0ea28 I/-/A/-/E 0 NONE 00
可见对于无效的cursor,ORACLE会选择在某个时间把其占用的heap清理出去。我的疑问是,虽然只有六个是有效的。ORACLE在进行查找
library cache的时候,是不是还得扫描2000个list。如果是这样的话,虽然释放了共享内存,但是占用library cache latch的时间并不会减少。
2. 还有一点我似乎想明白了为什么之前在生产库上一个update sql的version_count非常高,可是查看他的执行时间,跟其他正常的update的
SQL执行时间几乎一样。似乎没有我想象的library cache latch占用时间长,会导致整个执行时间变长。我查看了v$open_cursor视图,发现大
量的session都有这个cursor的cache,应该是由于我们服务器端设置了session_cached_cursor参数的原因。如果这个cursor被客户端cache后,
客户端就保留了指向到子lco的信息,定位就会非常快,而不需要去大量占有library cache latch时间了。
可以通过如下查询查看共享内存信息:
sys@ORA11G>sys@ORA11G>select kglhdadr,kglhdpar,kglhdlmd,kglhdpmd,kglobhs0,kglobhs6,
2 kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6 MEM
3 from x$kglob where kglnaobj like 'select * from cur1';
KGLHDADR KGLHDPAR KGLHDLMD KGLHDPMD KGLOBHS0 KGLOBHS6 MEM
---------------- ---------------- ---------- ---------- ---------- ---------- ----------
07000000187A7538 0700000017ED1F20 1 0 3600 0 3600
0700000016D265F0 0700000017ED1F20 1 0 3600 0 3600
0700000017ED1F20 0700000017ED1F20 1 0 2732 0 2732
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22034023/viewspace-681647/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/22034023/viewspace-681647/