在进程sql硬解析的时候,Oracle需要获得Shared Pool Latch来进行内存分配等。从Oracle 9i开始,Shared Pool 缺省的有7个子Latch,在我的测试系统上,只使用了其中一个child:
SQL> select ADDR,LATCH#,CHILD#,LEVEL#,NAME,HASH,GETS,MISSES,SLEEPS from v$latch_children where NAME = 'shared pool'; ADDR LATCH# CHILD# LEVEL# NAME HASH GETS MISSES SLEEPS -------- ---------- ---------- ---------- --------------- ---------- ---------- ---------- ---------- 200A79A4 293 7 7 shared pool 2276811941 20 0 0 200A7940 293 6 7 shared pool 2276811941 20 0 0 200A78DC 293 5 7 shared pool 2276811941 20 0 0 200A7878 293 4 7 shared pool 2276811941 20 0 0 200A7814 293 3 7 shared pool 2276811941 20 0 0 200A77B0 293 2 7 shared pool 2276811941 20 0 0 200A774C 293 1 7 shared pool 2276811941 152638 29 29 已选择7行。可以用过实验来验证一下Shared Pool Latch的使用。首先以sysdba身份登录,通过Latch地址200A774C来持有Latch:
SQL> show user USER 为 "SYS" SQL> oradebug setmypid 已处理的语句 SQL> oradebug call kslgetl 0x200A774C 1 Function returned 1然后在另外一个session执行一个查询(确保是硬解析):
SQL> conn u1/u1 已连接。 SQL> select count(*) from t;这时候可以看到,这个查询被挂起,无法执行下去。这就是因为Shared Pool Latch无法获取,在session 1中释放Shared Pool Latch:
SQL> oradebug call kslfre 0x200A774C Function returned 0这时在session 2中的查询立即显示了结果:
SQL> select count(*) from t; COUNT(*) ---------- 143926此时应当建立一个概念,SQL的执行缓慢,很多时候是阻塞在解析层,远远不到执行层面。找到session 2的sid:
SQL> select sid from v$mystat where rownum = 1; SID ---------- 43根据这个sid,来看看在阻塞阶段,这个会话在做什么,采样部分v$active_session_history视图信息,获得以下输出:
SQL> select EVENT,P1TEXT,P1,P2TEXT,P2,P3TEXT,P3,WAIT_CLASS,TIME_WAITED from v$active_session_history where SESSION_ID = 43; EVENT P1TEXT P1 P2TEXT P2 P3TEXT P3 WAIT_CLASS TIME_WAITED ------------------------- --------------- ---------- --------------- ---------- -------------------- ---------- --------------- ----------- latch: shared pool address 537556812 number 293 tries 0 Concurrency 14547548 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 latch: shared pool address 537556812 number 293 tries 0 Concurrency 0 ... ...从这个输出中可以看到,用户正是在等待latch: shared pool。这里的第一个参数是537556812,其十六进制表示200A774C,也就是Shared Pool Latch的内存地址;第二个参数是293,是Latch号;第三个参数是重试次数,不适用。