共计 3508 个字符,预计需要花费 9 分钟才能阅读完成。
library cache 相关知识点有哪些,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
共享游标
Sql 首次解析后会生成父游标和 1 个子游标(DDL 除外),其可共享的部分包括解析树,执行计划,绑定变量和 sql 文本等;
父游标主要保存游标名即 sql text,文本一致的 sql 即可共享;
子游标保存剩余信息,只有当执行计划 / 绑定变量 / 环境变量(NLS optimization mode)/ 实际引用对象一致时才可共享,否则新建 1 个子游标;
硬解析:没有可重用的共享游标,仅仅共享父游标也是硬解析;
软解析:重用父游标和子游标;
软软解析:缓存 PGA 中关闭的 session cursor,相比软解析省去了游标 open/close,同时可快速定位 library cache 中的共享游标;仅供当前 session 使用;
游标的生命周期
正常情况为 open – parse – bind – execute – fetch – close
而应用据此可分 4 种类型
1 不使用绑定变量
每次执行都经历一遍 open/close,游标不可重用,每次都进行硬解析;设置 cursor_sharing=force/similar 可使用软解析;
2 使用绑定变量
每次执行都经历一遍 open/close,游标可重用,后续执行进行软解析;设置 session_cached_cursors 可使用软软解析,而且避免每次都 open/close 游标;
3 open once + parse-bind-execute-fetch loop + close once
开启 HOLD_CURSOR=NO RELEASE_CURSOR=NO 选项的 oracle precompilers 采用此种应用;每次都执行软解析,但避免了频繁的开关游标;
4 open once + parse + bind + execute-fetch loop + close once
设计良好的 OCI 或 precompiler 可能采用此应用;设置 cursor_space_for_time=true 可提升性能(11g 废弃)
如何优化软解析
V$statname 中的 session cursor cache hits/session cursor cache count/parse count (total) 分别代表会话游标缓存命中次数 / 缓存总数 / 解析总数,当 hits/total 比例很低时说明软解析很严重,而软解析同样需要 library cache latch;
1 服务器: 调整 session_cache_cursor
2 应用: 改写 pl/sql,采用上述第 4 种类型的应用
Library cache
由 KGL 管理,采用哈希表结构,每个 bucket 由 handle 链表组成,每个 handle 包含一系列 heap,其指向 heap 0;
Handle 存储有对象名 / 命名空间 / 标志位
Lock Pin
作用
Library cache lock manages concurrency between processes, whereas library cache pin manages cache coherence。
In order to access an object in library cache, a process must first lock the library cache object handle, and then pin the object data heap itself.
Acquiring a library cache lock is also the only way to locate an object in cache—a process locates and locks an object in a single operation.
If the process wants to actually examine or modify the object, then it must acquire a library cache pin on the object data heap itself (after acquiring a library cache lock on the library cache object handle.
lock 保护 handle pin 保护 heap,要想访问 library cache 中的对象必须先后获取 lock 和 pin;
10202 采用 mutex 替换了针对 cursor 的 library cache pin;
模式
Library cache lock 和 pin 都是 enqueue 锁,
lock 分为 S,X 和 null(cursor 只能用 null 维护依赖一致性),pin 只有 S 和 X;
软解析使用 S pin,硬解析使用 X pin;无论硬解析还是软解析,cursor 只是用 null lock;可使用 10049 跟踪 http://www.dbsnake.net/library-cache-pin-and-lock-continue.html
关于 pin,
An X request (3) will be blocked by any pins held S mode (2) on the object.
An S request (2) will be blocked by any X mode (3) pin held, or may queue behind some other X request.
X pin 会让 null lock 失效,相应 cursor 必须重新解析方可再次运行,即如果对表作 DDL 相应游标都会失效,极容易爆发 library cache pin 等待;
pin 和 lock 都是添加于 handle 之上的;
Library cache latch:用于串行访问 library cache 中的对象;lock 并非原子操作,上锁前后需要 latch 保护;
Library cache load lock latch/library cache load lock—对象不在内存时无法 lock,此时需先加载;前者避免对象被多次加载,先获取前者直到 load lock 被分配,由后者负责将对象加载至内存;
找出 blocker
select
waiter.sid waiter,
waiter.event wevent,
to_char(blocker_event.sid)|| , ||to_char(blocker_session.serial#) blocker,
substr(decode(blocker_event.wait_time, 0, blocker_event.event, ON CPU),1,30) bevent
from
x$kglpn p,
gv$session blocker_session,
gv$session_wait waiter,
gv$session_wait blocker_event
where
p.kglpnuse=blocker_session.saddr
and p.kglpnhdl=waiter.p1raw
and waiter.event in (library cache pin , library cache lock , library cache load lock)
and blocker_event.sid=blocker_session.sid
and waiter.sid != blocker_event.sid
order by waiter.p1raw,waiter.sid;
select
ash.session_id sid,
ash.blocking_session bsid,
nvl(o.object_name,to_char(CURRENT_OBJ#)) obj,
o.object_type otype,
CURRENT_FILE# filen,
CURRENT_BLOCK# blockn,
ash.SQL_ID,
nvl(rc.name,to_char(ash.p3)) row_cache
from v$active_session_history ash, (select cache#, parameter name from v$rowcache) rc, all_objects o
where event= row cache lock
and rc.cache#(+)=ash.p1
and o.object_id (+)= ash.CURRENT_OBJ#
and ash.session_state= WAITING
and ash.sample_time sysdate – minutes/(60*24)
Order by sample_time;
关于 library cache 相关知识点有哪些问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。