oracle 體系結構及內存管理 07_shared pool

一、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');
相關文章
相關標籤/搜索