indx RECURRENT TRANSIENT FLUSHED PINS AND ORA-4031 LAST ERROR
indx num CHUNK CHUNK CHUNK RELEASES ERRORS SIZE
---------- ---------- ---------- ---------- ---------- ---------- ----------
0 975 5907 582888 1402121 1043 3200
1 2756 20749 572392 1180944 1 4064
Library Cache内部结构 Shared Pool的内存由KGH(Kernel Generic Heap)管理,Library Cache则由KGL(Kernel Generic Library Cache)管理,KGL利用KGH分配得到必要的内存Chunk.Library Cache的内存结构如图所示
SQL经过Hash函数生成一个Hash值,然后根据这个Hash值去检索Library Cache是否存在相同的SQL,检索过程中需要持有Latch Cache Latch.如果不存在相同的SQL则将SQL文本分配到适当的Bucket上.具有相同的Hash值的SQL以Handle为单位,以Chain的形式挂载到同一个Bucket上.一个Handle管理一个Library Cache Object.Handle对实际的Library Cache Object起到指针的作用.Library Cache Object保存着SQL的实际信息.Bucket主要由Library Cache Latch保护;Handle由Library Cache Lock保护;Library Cache Object有Library Cache Pin保护.Library Cache Latch的数量默认与大于CPU数量的最小质数相同
另外,Library Cache Latch的数量受隐含参数_kgl_latch_count影响,Library Cache Bucket受隐含参数_kgl_bucket_count影响.一个Library Cache Latch管理者多个Library Cache Bucket.如果在申请Library Cache Latch过程中发生争用.则会发生Latch:Library Cache等待事件
Library Cache Object保存着Cursor具体信息,LCO的集体信息如下:
LCO包含众多信息,最关键是以下3个信息: Dependency Table:保存当前LCO以来的其他LCO信息,比如SQL语句所以来的表、视图.Child Table:保存当前LCO的子LCO信息.通俗点说,就是一条SQL 至少有一个和子游标.可能一些SQL由于某些原因无法共享子游标(比如不同用户拥有相同名字的表T,他们都执行select * from T.),这样就会出现一个父游标和多个子游标的情况.即Version Count 很高。 那么这种情况下.父游标里对应的所有子游标的指针都会保存在child table里面.父游标Data Blocks:保存着SQL语句、执行计划、执行文本等信息. Child Table存放指向子游标的指针,存在不同Version的SQL往往是由于不同用户执行了相同的SQL
最简单的理解就是:父游标的名字就是SQL TEXT而相同的SQL TEXT可能会有不同执行计划,于是产生了子游标 比如SCOTT用户和TOM用户都执行SELECT * FROM T,两个用户都有T表,但表的内容和结构完全不同,他们共用一个父游标.
Version Count过高(子游标过多)造成的后果就是定位子游标时间延长,持有Library Cache Latch的时间会增长,增加Library Cache Latch的争用.Oracle的BUG也会导致SQL的版本数异常增高.我们可以使用一下脚本定位SQL版本高的原因: SQL> SET PAGES 0
SQL> SET HEADING OFF;
'SQL_TYPE_MISMATCH: '||SUM(TO_NUMBER(DECODE(sql_type_mismatch,'Y',1,'N','0'))),
'OPTIMIZER_MISMATCH: '||SUM(TO_NUMBER(DECODE(optimizer_mismatch,'Y',1,'N','0'))),
'OUTLINE_MISMATCH: '||SUM(TO_NUMBER(DECODE(outline_mismatch,'Y',1,'N','0'))),
'STATS_ROW_MISMATCH: '||SUM(TO_NUMBER(DECODE(stats_row_mismatch,'Y',1,'N','0'))),
'LITERAL_MISMATCH: '||SUM(TO_NUMBER(DECODE(literal_mismatch,'Y',1,'N','0'))),
'FORCE_HARD_PARSE: '||SUM(TO_NUMBER(DECODE(force_hard_parse,'Y',1,'N','0'))),
'EXPLAIN_PLAN_CURSOR: '||SUM(TO_NUMBER(DECODE(explain_plan_cursor,'Y',1,'N','0'))),
'BUFFERED_DML_MISMATCH: '||SUM(TO_NUMBER(DECODE(buffered_dml_mismatch,'Y',1,'N','0'))),
'PDML_ENV_MISMATCH: '||SUM(TO_NUMBER(DECODE(pdml_env_mismatch,'Y',1,'N','0'))),
'INST_DRTLD_MISMATCH: '||SUM(TO_NUMBER(DECODE(inst_drtld_mismatch,'Y',1,'N','0'))),
'SLAVE_QC_MISMATCH: '||SUM(TO_NUMBER(DECODE(slave_qc_mismatch,'Y',1,'N','0'))),
'TYPECHECK_MISMATCH: '||SUM(TO_NUMBER(DECODE(typecheck_mismatch,'Y',1,'N','0'))),
'AUTH_CHECK_MISMATCH: '||SUM(TO_NUMBER(DECODE(auth_check_mismatch,'Y',1,'N','0'))),
'BIND_MISMATCH: '||SUM(TO_NUMBER(DECODE(bind_mismatch,'Y',1,'N','0'))),
'DESCRIBE_MISMATCH: '||SUM(TO_NUMBER(DECODE(describe_mismatch,'Y',1,'N','0'))),
'LANGUAGE_MISMATCH: '||SUM(TO_NUMBER(DECODE(language