SHARED POOL总结

本文试图对shared pool的内部机制做一个总结,目的是加强对相关内容的了解。
shared pool内存的几个特征:
a.以CHUNK为单位,CHUNK大小不等,每个chunk跟x$ksmsp中每条记录有一一对应关系
b.当会话结束,相关内存空间并不全部释放,因为无法预知这些信息会不会被后来的会话用到
c.不能被PAGE OUT到系统的磁盘交换区,AGE OUT的是一些可重建的信息

[@more@]

1、shared pool内存结构及内存分配方式
shared pool 包含dictionary & sql区、保留区、永久区
保留区存储大对象,大小由shared_pool_reserved_size决定,缺省为shared pool大小的5%,当对象大小大于参数_shared_pool_reserved_min_alloc值时,对象将被存储在保留区。
永久区存放进程、会话、ENQUEUE和事务等信息
shared pool内存逻辑上由多个extent组成,每个extent由多个chunk组成,chunk大小不同,这一点不同于data block
当需要新的内存空间的时候,oracle就分配新的chunk
shared pool的内存管理依赖于三个list:free list(空闲chunk)、LRU list(没有被pin住的可重建的chunk)和reserved free list(保留区的freelist)
shared pool如何分配空闲chunk?
首先在freelist上搜索所需要大小的chunk,如果没有空闲空间,将在LRU list上搜索所需要大小的chunk,如果对象比较大,将搜索reserved free list
当这三个搜索都失败的时候,就出ORA-04031的错误。有时候shared pool有空闲空间仍然有可能出现ORA-04031的错误。
shared pool的这三个链表将所有的chunk组织起来。
2、library cache内存结构
基本结构:hash bucket->chain->handle->object
对于每个SQL语句,使用HASH函数得到HASH值,再通过HASH值找到相关的hash bucket
library cache由多个HANDLE+OBJECT组成
handle存储LCO的定义,通常是SQL语句本身以及相关信息
LCO存储依赖表(所有的依赖信息),子表(子LCO信息,也是由HANDLE和LCO组成,代表了相同的SQL语句,但是不同的执行计划,对应于v$sqlarea的version_count)和DATA BLOCKS(与执行相关的信息,比如执行计划)
3、软解析和硬解析
软解析:对于提交的语句,在语法和权限检查后,运用hash函数找到相关的hash bucket,获取library cache latch来保护hash bucket,然后搜索LCO,找到后获取library cache lock或者library cache pin,并执行相关语句。
硬解析:当软解析失败,注册新的LCO,并获取library cache lock/pin,生成执行计划,获取shared pool latch,找到相关的空闲chunk.
硬解析多会导致很长的hash chain,内存碎片。
软解析多会导致对hash chain的过多访问和library cache latch的争用。
如何查找parse次数多的SQL语句?
select sql_text, parse_calls, executions from v$sqlarea
where parse_calls > 100 and executions < 2*parse_calls;
4、library cache latch和shared pool latch
当event为library cache latch,v$session_wait的p1为latch的地址,P2为LATCH#,P3为请求次数。
_KGL_LATCH_COUNT用于控制library cache latches的个数,其数量通常为大于cpu_count的最小质数
查看Library cache latch的个数
SQL> select count(*)from v$latch_children where name='library cache';
Library cache latch争用有时候出现在具有高version_count的sql语句中,这些sql的表面字义是相同的如select * from test,但可能执行计划不同,这些sql具有相同的散列值和不同的版本,oracle需要去比较该语句和现有版本,这期间是一直持有latch的,这可能会造成其他进程无法获得该latch。-------见第2小节:library cache内存结构
查看高version_count的sql语句:
select substr(sql_text,1,40),version_count
from v$sqlarea where version_count > 10 order by version_count desc;
5、library cache lock和library cache pin
library cache lock:当访问和修改LCO时获取该锁,由LCO的handle获取。
DDL操作需要排它的library cache lock,library cache lock的获取先于library cache pin
SQL PARSE阶段为共享锁
SQL执行阶段为NULL模式的锁
library cache pin:当SQL执行的时候保护LCO中的与执行相关的信息,由LCO本身获取
语句执行阶段为共享锁
DDL或者HARD PARSE为排它锁

相关视图:DBA_KGLLOCK(X$KGLLK+X$KGLPN) DBA_DDL_LOCKS(X$KGLLK+V$SESSION+X$KGLOB)

软解析的时候给LCO加NULL型library cache lock和共享的library cache pin,给子LCO加共享型library cache lock和共享的library cache pin
硬解析的时候给LCO加NULL型library cache lock和排它的library cache pin,给子LCO加共享型library cache lock和共享的library cache pin

为什么LCO在SQL parse之后会有null模式的library cache lock?这是因为一旦对象的定义改变,那么ORACLE要唤醒NULL模式锁的持有者通知它。

硬解析和DDL都可能导致library cache pin等待,比如在系统繁忙时候flush shared pool.

如何找到library cache pin锁的持有者?

对OBJECT:

select session_id sid,lock_type type,lock_id1 object_name from dba_lock_internal where mode_requested<>'None' and mode_requested<>mode_held and session_id in (select sid from v$session_wait where wait_time=0 and event like 'library cache pin%');

对PIN HOLDER:

select sid holder,kglpnmod held,kglpnreq req,event,wait_time from v$kglpn,v$session where kglpnhdl in (select p1raw from v$session_wait where wait_time=0 and event like 'library cache pin%') and kglpnmod<>0 and v$session.saddr=x$kglpn.kglpnuse;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/85922/viewspace-1003461/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/85922/viewspace-1003461/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值