oracle 体系结构及内存管理 07_shared pool

早过忘川 提交于 2020-02-29 08:20:18

1、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自身信息的表或者视图

2、硬解析、软解析
    硬解析步骤:语法,对象是否存在,用户是否有权限操作对象,生成执行计划,挑选最终执行计划(消耗大量资源占解析的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消耗,总解析,硬解析,解析失败

3、SQL共享,sql完全相同,(每一个字母必须相同)
    绑定变量
    SQL语句组成,动态部分、静态部分
        cursor_sharing: [FORCE | SIMILAR | EXACT]
            FORCE 字面值强制绑定,无论是否最佳
            SIMILAR 字面值强制绑定,同时选用最佳效率
            EXACT 字面值严格完全相同判断
        show parameter cursor;
        alter system set cursor_sharing = exact scope = both;    

        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 '';

4、找出没有共享的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;

5、解析命中率,软解析成功的次数>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;

6、解决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时发生,原因是共享池空间不足和碎片过多
    1、alter system flush shared_pool;    --清理碎片,碎片程度查看方法
    2、共享SQL
    alter system set cursor_sharing ='force';
    3、强制缓存技术,手动缓存较大的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
    4、保留区,达到保留区对象大小时自动缓存,专门缓存大对象
    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
    5、增加shared pool空间
        alter system set shared_pool_size=150M scope=both;
    6、定期清理连接与实例重启
    select COMPONENT,CURRENT_SIZE from V$SGA_DYNAMIC_COMPONENTS; #当前值
    show parameter sga_target:动态参数,统一分配
    show parameter sga_max_size:静态参数,防止动态修改的sga_target设置过大,先修改sga_max_size,重启

7、查看执行计划
    select SQL_ID,sql_text,EXECUTIONS from v$sql where SQL_TEXT; 
    select * from table(dbms_xplan.display_cursor('bwhzpth8a3zgv'));--通过sqlid查看执行计划

8、在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;
查询该设置大小

    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);

9、补充内容
   查询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 解析外的时间即执行查询时间,如果很低说明解析次数多

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');

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!