一、shared pool的组成
3块区域:free、library cache 缓存SQL语句及执行计划、row cache 字典对象的定义与权限信息缓存
(permanent area实例启动时固定分配,segmented arrays锁,事务等,library cache,row cache,reserved cache大对象保留池)
select * from v$sgastat a where a.NAME = 'library cache'; --11g已没有
select * from v$sgastat a where a.pool = 'shared pool' and a.NAME = 'free memory';
select * from v$sgastat a where a.NAME = 'row cache'; --dictionary cache
select * from v$sgastat; --shared pool各个子池的大小,名称,java pool,large pool也存在
大小参数:shared_pool_szie
数据字典:存储oracle自身信息的表或者视图java
二、硬解析、软解析
硬解析步骤:语法,对象是否存在,用户是否有权限操做对象,生成执行计划,挑选最终执行计划(消耗大量资源占解析的70%)
软解析步骤:语法,对象是否存在,用户是否有权限操做对象
shared pool内存块组织结构
两个概念:chain(bucket)、chunk
free部分的chunk是按照大小挂在chain上的,当硬解析完一个sql及执行计划后,从free中取来一个大小至关的chunk存入,放
入library cache里,剩下的小chunk再链到小的chain上,解析时先到dictionary cache中去找与语句有关的数据,字典信息,比
如表 名、表的列等,以及用户权限等信息。硬解析须要使用free空间,同时产生小的chunk,因此会出现chunk数增多
library cache中的chunk也挂在chain上(按照chunk里缓存的SQL语句相关值),判断sql是否已缓存,是将新来的sql语句通过一
系列的运算(sql-ascii-hash-运算-chain值)得出liabrary chain里的相同编号的chain,再在该chain上根据sql语句的hash值找
到存储sql及执行计划的chunk,
跟踪解析过程当中chunk的变化过程:
select count(*) from x$ksmsp; --chunk总数
select * from x$ksmsp; --每个chunk都会有一条信息
连续执行,间隔时间里产生的chunk数量,肯定是否硬解析及多少硬解析
alter system flush shared_pool; --清空library cache和row cache里的内容;
解析状况查询:
select name,value from v$sysstat where name like 'parse%'; --cpu消耗,总解析,硬解析,解析失败linux
三、SQL共享,sql彻底相同,(每个字母必须相同)
绑定变量
SQL语句组成,动态部分、静态部分
cursor_sharing: [FORCE | SIMILAR | EXACT]
FORCE 字面值强制绑定,不管是否最佳
SIMILAR 字面值强制绑定,同时选用最佳效率
EXACT 字面值严格彻底相同判断
show parameter cursor;
alter system set cursor_sharing = exact scope = both; sql
declare sql_text varchar2(2000); n2 varchar2(20); begin for i in 1..100 loop n2:='fhf'||i; sql_text:='insert into t1(object_id,name) values (:1,:2)'; execute immediate sql_text using i,n2; end loop; commit; end; select /*hello*/ count(1) from t1 where object_id =1; select /*hello*/ count(1) from t1 where object_id =2; select /*hello*/ count(1) from t1 where object_id =1;
经过sql_id区分是否实现了sql共享
select sql_id,EXECUTIONS,HASH_VALUE,PLAN_HASH_VALUE,sql_text from v$sql where sql_text like '';数据库
四、找出没有共享的SQL语句
在v$sql查找执行次数较小的sql语句,观察这些sql语句是不是常常执行的。
select SQL_FULLTEXT from v$sql where EXECUTIONS=1 and sql_text like '%from t%';
select SQL_FULLTEXT from v$sql where EXECUTIONS=1 order by sql_text;windows
五、解析命中率,软解析成功的次数>99.8%
select sum(pinhits)/sum(pins)*100 from v$librarycache; --99%接近100才好,数据库跑一段时间后查询
select sum(gets),sum(getmisses),100*sum(gets-getmisses)/sum(gets) from v$rowcache where gets>0;缓存
六、解决4031错误的方法
查看4031错误,indx子池序号,kghlunfu各子池出现4031错误次数,kghlunfs最后一次出现时申请的大小(参照设置保留对象大小),
select indx, kghlurcr, kghlutrn, kghlufsh, kghluops, kghlunfu, kghlunfs from sys.x$kghlu
where inst_id = userenv('Instance');
ora-4031错误:free空间不够解析一个新的较大sql时发生,缘由是共享池空间不足和碎片过多
一、alter system flush shared_pool; --清理碎片,碎片程度查看方法
二、共享SQL
alter system set cursor_sharing ='force';
三、强制缓存技术,手动缓存较大的SQL语句,不会被置换出来
select * from v$db_object_cache where sharable_mem > 10000
and (type = 'PACKAGE' or type='PACKAGE BODY' or type = 'FUNCTION' or type='PROCEDURE')
and kept = 'NO';
执行dbms_shared_pool.keep('对象名');
execute dbms_shared_pool.keep('DBMS_SQL');
@?/rdbms/admin/dbmspool.sql
四、保留区,达到保留区对象大小时自动缓存,专门缓存大对象
shared_pool_reserved_size:保留池大小,shared_pool_size的5%
_shared_pool_reserved_pct:指定保留池与shared_pool_size的比例,缺省5%
_shared_pool_reserved_min_alloc:缺省4400字节
调整大小:alter system set "_shared_pool_reserved_min_alloc"=4000 scope = spfile;
select * from x$ksppcv where indx in
(select indx from x$ksppi where ksppinm in
('_shared_pool_reserved_pct','_shared_pool_reserved_min_alloc'));
在保留区找不到空间
select * from v$shared_pool_reserved;
http://www.linuxidc.com/Linux/2012-05/59844.htm
五、增长shared pool空间
alter system set shared_pool_size=150M scope=both;
六、按期清理链接与实例重启
select COMPONENT,CURRENT_SIZE from V$SGA_DYNAMIC_COMPONENTS; #当前值
show parameter sga_target:动态参数,统一分配
show parameter sga_max_size:静态参数,防止动态修改的sga_target设置过大,先修改sga_max_size,重启session
七、查看执行计划
select SQL_ID,sql_text,EXECUTIONS from v$sql where SQL_TEXT;
select * from table(dbms_xplan.display_cursor('bwhzpth8a3zgv'));--经过sqlid查看执行计划并发
八、在Oracle10g中容许有多个sub shared pool,能够设置大于1G的shared pool
没有实现sql共享时shared pool做用为反的;越大危害越大10g之前不超过1个G,10g后能够设大
共享池的子池(subpool)
利:减小共享池争用,提升访问的并发;弊:增长共享池碎片的机会
4个CPU1个subpool,最多7个
最小值:9i 128M 10g 256M 11g 512M
设置shared pool的大小
SELECT
shared_pool_size_for_estimate "SP_SIZE M",
estd_lc_size "EL",
estd_lc_memory_objects "ELM",
estd_lc_time_saved "ELT", estd_lc_time_saved_factor "parse factor",
estd_lc_memory_object_hits "ELMO"
FROM v$shared_pool_advice;
查询该设置大小oracle
SELECT 'Shared Pool' component, shared_pool_size_for_estimate estd_sp_size,--值得间隔为shared pool大小的10%为间隔 estd_lc_time_saved_factor parse_time_factor, CASE WHEN current_parse_time_elapsed_s + adjustment_s < 0 THEN 0 ELSE current_parse_time_elapsed_s + adjustment_s END response_time FROM (SELECT shared_pool_size_for_estimate,shared_pool_size_factor,estd_lc_time_saved_factor,a.estd_lc_time_saved, e.VALUE/100 current_parse_time_elapsed_s,c.estd_lc_time_saved - a.estd_lc_time_saved adjustment_s FROM v$shared_pool_advice a,(SELECT * FROM v$sysstat WHERE NAME = 'parse time elapsed') e, (SELECT estd_lc_time_saved FROM v$shared_pool_advice WHERE shared_pool_size_factor = 1) c);
九、补充内容
查询oracle数据块的大小 show parameter block
查询windows物理内存大小:systeminfo
查询linux物理内存大小:free -m 单位是M
10.共享池相关闩锁及优化
shared pool
library cache
library cache pin
row cache objects
row cache enqueue latch
11.SESSION_CACHED_CURSORS
定义一个session能够缓存多少个cursor,让后续相同的SQL语句再也不打开游标,从而避免软解析的过程来提升性能。
oracle的session cursor cache是一块内存区域,用来存储关闭了的cursor,parse以前在这里找sql的缓存,会消耗内
存空间。
select name,value from v$sysstat where name like '%cursor%';
select name,value from v$sysstat where name like '%parse%';
根据session cursor cache hits/parse count(total)来调整SESSION_CACHED_CURSORS的大小;
软解析的指标:% Non-Parse CPU 解析外的时间即执行查询时间,若是很低说明解析次数多oop
12.共享池相关脚本
查询共享池内细分各种内存状态信息
SELECT KSMCHCLS CLASS, COUNT(KSMCHCLS) NUM, SUM(KSMCHSIZ) SIZ, To_char( ((SUM(KSMCHSIZ)/COUNT(KSMCHCLS)/1024)),'999,999.00')||'k' "AVG SIZE" FROM X$KSMSP GROUP BY KSMCHCLS;
查询共享池碎片化程度信息
select KSMCHIDX "SubPool", 'sga heap('||KSMCHIDX||',0)'sga_heap,ksmchcom ChunkComment, decode(round(ksmchsiz/1000),0,'0-1K', 1,'1-2K', 2,'2-3K',3,'3-4K', 4,'4-5K',5,'5-6k',6,'6-7k',7,'7-8k',8,'8-9k', 9,'9-10k','> 10K') "size", count(*),ksmchcls Status, sum(ksmchsiz) Bytes from x$ksmsp where KSMCHCOM = 'free memory' group by ksmchidx, ksmchcls, 'sga heap('||KSMCHIDX||',0)',ksmchcom, ksmchcls,decode(round(ksmchsiz/1000),0,'0-1K', 1,'1-2K', 2,'2-3K', 3,'3-4K',4,'4-5K',5,'5-6k',6,'6-7k',7,'7-8k',8,'8-9k', 9,'9-10k','> 10K');