背景
本文为oracle 11g latch系列的第三篇文章,继续深入学习latch,想要熟悉其原理,还是先了解下相关视图的含义,尔后进一步深入其中,便于解决问题。
本系列前2文链接如下:
oracle 11g latch之系列一
http://blog.itpub.net/9240380/viewspace-1820418/
oracle 11g latch之v$latch系列二
http://blog.itpub.net/9240380/viewspace-1820457/
结论
1,oradebug poke手工模拟shared pool latch虽然成功,但v$latchholder却一直没值,还是没有理解清晰latch的机制和v$latchholder的关系2,没有子LATCH的LATCH的情况只在V$LATCH及V$LATCH_PARENT存储数据
而有子LATCH的LATCH在v$latch及v$latch_parent和v$latch_childrent皆存储数据
3,模拟占有shared pool latch为
用oradebug模拟shared poo latch
SQL> select 'oradebug poke 0x'||addr||' 4 0x00000001;' from v$latch_children where latch#=293;
'ORADEBUGPOKE0X'||ADDR||'40X00000001;'
--------------------------------------------------------------------------------------------
oradebug poke 0x0000000060103C88 4 0x00000001;
oradebug poke 0x0000000060103BE8 4 0x00000001;
oradebug poke 0x0000000060103B48 4 0x00000001;
oradebug poke 0x0000000060103AA8 4 0x00000001;
oradebug poke 0x0000000060103A08 4 0x00000001;
oradebug poke 0x0000000060103968 4 0x00000001;
oradebug poke 0x00000000601038C8 4 0x00000001;
4,模拟释放shared pool latch为
oradebug poke 0x0000000060103C88 4 0x00000000;
oradebug poke 0x0000000060103BE8 4 0x00000000;
oradebug poke 0x0000000060103B48 4 0x00000000;
oradebug poke 0x0000000060103AA8 4 0x00000000;
oradebug poke 0x0000000060103A08 4 0x00000000;
oradebug poke 0x0000000060103968 4 0x00000000;
oradebug poke 0x00000000601038C8 4 0x00000000;
可见即1为占有,0为释放
测试
1,数据库版本
SQL> select * from v$version where rownum=1;
BANNER
----------------------------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
2,获取有子latch的测试latch
SQL> select addr,latch#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch where gets >0 and immediate_gets>0 and rownum<=10;
ADDR LATCH# LEVEL# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
---------------- ---------- ---------- ------------------------------ ---------- ---------- ---------- -------------- ---------------- ----------
0000000060009720 2 8 post/wait queue 823771719 685636 1383 858180 2479 0
0000000060009F38 9 7 process allocation 2600548697 22679 2 7624 0 0
000000006000A9E0 16 8 longop free list parent 853437045 96 0 88 0 0
000000006000CF38 28 4 enqueue hash chains 1456202064 11610594 4823 325 0 3
000000006000D3A0 33 6 SGA IO buffer pool latch 2719726273 1 0 1 0 0
00000000600101C8 70 0 active service list 4226341592 1931885 58 10716 1 9
00000000600178B0 137 7 Memory Management Latch 1808980316 26 0 6943 0 0
00000000600188A8 145 2 cache buffers lru chain 3559635447 177525 149 170932 140 0
0000000060019E38 149 5 checkpoint queue latch 4259362863 298484 1 81957 3 0
000000006001A620 150 1 cache buffers chains 3563305585 299012270 13426 182643 77 7195
10 rows selected.
可见上述的10个LATCH只有6个LATCH有有子LATCH,还有4个LATCH没有子LATCH
SQL> select latch#,count(child#) from v$latch_children where latch# in (select latch# from v$latch where gets >0 and immediate_gets>0 and rownum<=10) group by latch# order by 2;
LATCH# COUNT(CHILD#)
---------- -------------
28 1
16 1
2 7
145 16
149 16
150 8192
6 rows selected.
v$latch和v$latch_parent存储数据是相同的,源自官方手册
SQL> select addr,latch#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch where latch#=2;
ADDR LATCH# LEVEL# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
---------------- ---------- ---------- ------------------------------ ---------- ---------- ---------- -------------- ---------------- ----------
0000000060009720 2 8 post/wait queue 823771719 702401 1412 879227 2545 0
SQL> select addr,latch#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch_parent where latch#=2;
ADDR LATCH# LEVEL# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
---------------- ---------- ---------- ------------------------------ ---------- ---------- ---------- -------------- ---------------- ----------
0000000060009720 2 8 post/wait queue 823771719 158 0 0 0 0
获取上述LATCH的子LATCH,可见有7个子LATCH,且每个子LATCH的地址和其父LATCH的地址各为不同
SQL> select addr,latch#,child#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch_children where latch#=2 order by 3;
ADDR LATCH# CHILD# LEVEL# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
---------------- ---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- -------------- ---------------- ----------
00000000DF0E8E18 2 1 8 post/wait queue 823771719 0 0 0 0 0
00000000DF0E8ED8 2 2 8 post/wait queue 823771719 0 0 0 0 0
00000000DF0E8F98 2 3 8 post/wait queue 823771719 0 0 0 0 0
00000000DF0E9058 2 4 8 post/wait queue 823771719 0 0 0 0 0
00000000DF0E9118 2 5 8 post/wait queue 823771719 0 0 0 0 0
00000000DF0E91D8 2 6 8 post/wait queue 823771719 318043 822 437417 1505 0
00000000DF0E9298 2 7 8 post/wait queue 823771719 382458 585 439529 1031 0
7 rows selected.
再看下余下LATCH的没有子LATCH的4个LATCH的情况
可见没有子LATCH的LATCH,只在V$LATCH及V$LATCH_PARENT存储数据
SQL> select addr,latch#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch where latch#=9;
ADDR LATCH# LEVEL# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
---------------- ---------- ---------- ------------------------------ ---------- ---------- ---------- -------------- ---------------- ----------
0000000060009F38 9 7 process allocation 2600548697 23328 2 7789 0 0
SQL> select addr,latch#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch_parent where latch#=9;
ADDR LATCH# LEVEL# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
---------------- ---------- ---------- ------------------------------ ---------- ---------- ---------- -------------- ---------------- ----------
0000000060009F38 9 7 process allocation 2600548697 23328 2 7789 0 0
SQL> select addr,latch#,child#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch_children where latch#=9 order by 3;
no rows selected
再学习下v$latchholder
经用ORADEBUG POKE模拟shared pool latch,虽然成功,但始终v$latchholder没有数据,也就是说我对于v$latchholder理解不准确
会话1
可见当前没有进程或会话持有LATCH
pid为持latch的进程号,sid为持latch会话,laddr为latch地址,gets为请求LATCH的次数(以乐意等待或不乐意等待),这理还是没有掌握到如何模拟出v$latchholder的深一层使用
SQL> select pid,sid,laddr,name,gets from v$latchholder;
no rows selected
SQL> select latch#,child#,name from v$latch_children where latch#=293 order by 2;
LATCH# CHILD# NAME
---------- ---------- --------------------
293 1 shared pool
293 2 shared pool
293 3 shared pool
293 4 shared pool
293 5 shared pool
293 6 shared pool
293 7 shared pool
7 rows selected.
SQL> select pid,spid from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat where rownum=1));
PID SPID
---------- ------------------------------------------------
31 7675
SQL> select sid from v$mystat where rownum=1;
SID
----------
40
可见当前SHARE POOL LATCH的MISES为1931
SQL> select addr,latch#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch where latch#=293;
ADDR LATCH# LEVEL# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
---------------- ---------- ---------- ------------------------------ ---------- ---------- ---------- -------------- ---------------- ----------
0000000060033B08 293 7 shared pool 2276811941 607836 1931 0 0 0
SQL> select addr,latch#,level#,name,hash,gets,misses,immediate_gets,immediate_misses,spin_gets from v$latch where latch#=293;
ADDR LATCH# LEVEL# NAME HASH GETS MISSES IMMEDIATE_GETS IMMEDIATE_MISSES SPIN_GETS
---------------- ---------- ---------- ------------------------------ ---------- ---------- ---------- -------------- ---------------- ----------
0000000060033B08 293 7 shared pool 2276811941 618910 1931 0 0 0
会话2
SQL> select pid,spid from v$process where addr=(select paddr from v$session where sid=(select sid from v$mystat where rownum=1));
PID SPID
---------- ------------------------------------------------
30 7581
SQL> select sid from v$mystat where rownum=1;
SID
----------
38
会话1
用oradebug模拟shared poo latch
SQL> select 'oradebug poke 0x'||addr||' 4 0x00000001;' from v$latch_children where latch#=293;
'ORADEBUGPOKE0X'||ADDR||'40X00000001;'
--------------------------------------------------------------------------------------------
oradebug poke 0x0000000060103C88 4 0x00000001;
oradebug poke 0x0000000060103BE8 4 0x00000001;
oradebug poke 0x0000000060103B48 4 0x00000001;
oradebug poke 0x0000000060103AA8 4 0x00000001;
oradebug poke 0x0000000060103A08 4 0x00000001;
oradebug poke 0x0000000060103968 4 0x00000001;
oradebug poke 0x00000000601038C8 4 0x00000001;
7 rows selected.
SQL> oradebug setmypid
Statement processed.
SQL> oradebug poke 0x0000000060103C88 4 0x00000001;
oradebug poke 0x0000000060103BE8 4 0x00000001;
oradebug poke 0x0000000060103B48 4 0x00000001;
oradebug poke 0x0000000060103AA8 4 0x00000001;
oradebug poke 0x0000000060103A08 4 0x00000001;
oradebug poke 0x0000000060103968 4 0x00000001;
BEFORE: [060103C88, 060103C8C) = 00000000
AFTER: [060103C88, 060103C8C) = 00000001
SQL> BEFORE: [060103BE8, 060103BEC) = 00000000
AFTER: [060103BE8, 060103BEC) = 00000001
SQL> BEFORE: [060103B48, 060103B4C) = 00000000
AFTER: [060103B48, 060103B4C) = 00000001
SQL> BEFORE: [060103AA8, 060103AAC) = 00000000
AFTER: [060103AA8, 060103AAC) = 00000001
SQL> BEFORE: [060103A08, 060103A0C) = 00000000
AFTER: [060103A08, 060103A0C) = 00000001
SQL> BEFORE: [060103968, 06010396C) = 00000000
AFTER: [060103968, 06010396C) = 00000001
SQL> oradebug poke 0x00000000601038C8 4 0x00000001;
BEFORE: [0601038C8, 0601038CC) = 00000000
AFTER: [0601038C8, 0601038CC) = 00000001
会话2
SQL> create table t_latch(a int);
hang住了
会话1
SQL> select pid,sid,laddr,name,gets from v$latchholder;
no rows selected
但好像没有数据显示
会话1
释放shared pool latch
SQL> oradebug setmypid
Statement processed.
SQL> oradebug poke 0x0000000060103C88 4 0x00000000;
BEFORE: [060103C88, 060103C8C) = 00000001
AFTER: [060103C88, 060103C8C) = 00000000
SQL> oradebug poke 0x0000000060103BE8 4 0x00000000;
BEFORE: [060103BE8, 060103BEC) = 00000001
AFTER: [060103BE8, 060103BEC) = 00000000
oradebug poke 0x0000000060103B48 4 0x00000000;
BEFORE: [060103B48, 060103B4C) = 00000001
AFTER: [060103B48, 060103B4C) = 00000000
SQL> oradebug poke 0x0000000060103AA8 4 0x00000000;
BEFORE: [060103AA8, 060103AAC) = 00000001
AFTER: [060103AA8, 060103AAC) = 00000000
SQL> oradebug poke 0x0000000060103A08 4 0x00000000;
BEFORE: [060103A08, 060103A0C) = 00000001
AFTER: [060103A08, 060103A0C) = 00000000
SQL> oradebug poke 0x0000000060103968 4 0x00000000;
BEFORE: [060103968, 06010396C) = 00000001
AFTER: [060103968, 06010396C) = 00000000
SQL> oradebug poke 0x00000000601038C8 4 0x00000000;
BEFORE: [0601038C8, 0601038CC) = 00000001
AFTER: [0601038C8, 0601038CC) = 00000000
会话2
ddl执行成功
SQL> create table t_latch2(a int);
Table created.
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9240380/viewspace-1821684/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9240380/viewspace-1821684/