zoukankan      html  css  js  c++  java
  • 解决0RA-04031故障

    1.客户反应报表数据很慢,简单查询5分钟都出不来。

    2.登陆数据库服务器检查日志:
    Thu Mar 21 16:20:30 2013
    Errors in file /opt/oracle/diag/rdbms/rptdw/rptdw2/trace/rptdw2_lms0_9538.trc (incident=144231):
    ORA-04031: unable to allocate 4064 bytes of shared memory ("shared pool","unknown object","sga heap(1,0)","gcs dynamic r")
    Incident details in: /opt/oracle/diag/rdbms/rptdw/rptdw2/incident/incdir_144231/rptdw2_lms0_9538_i144231.trc

    3.了解一下shared pool的原理
    library cache包含 SQL语句,分析的代码,执行计划等
    data dictionary cache包含 table, column等对象的定义以及权限的信息

    主要包含如下组件:
    Permanent Area
    Segmented Arrays(锁、事务、资源等)
    Library Cache
    Row Cache
    Reserved Area

    查看共享池大小和共享池保留区大小
    select * from v$sga_dynamic_components ;
    shared pool 3019898880

    SQL> show parameter shared
    NAME TYPE
    ------------------------------------ --------------------------------
    VALUE
    ------------------------------
    shared_pool_reserved_size big integer
    154350387

    查看共享池隐含参数
    SELECT ksppinm, ksppstvl, ksppdesc
    FROM x$ksppi x, x$ksppcv y
    WHERE x.indx = y.indx AND TRANSLATE (ksppinm, '_', '#') LIKE '#share%';
    ksppinm ksppstvl ksppdesc
    _shared_pool_reserved_pct 5 percentage memory of the shared pool allocated for the reserved area
    _shared_pool_reserved_min_alloc 4400 minimum allocation size in bytes for reserved area of shared pool
    _shared_pool_max_size 0 shared pool maximum size when auto SGA enabled
    _shared_pool_minsize_on FALSE shared pool minimum size when auto SGA enabled
    _shared_io_pool_size 0 Size of shared IO pool
    _shared_iop_max_size 536870912 maximum shared io pool size
    _shared_io_pool_buf_size 1048576 Shared IO pool buffer size
    _shared_io_pool_debug_trc 0 trace kcbi debug info to tracefile
    _shared_io_set_value FALSE shared io pool size set internal value - overwrite zero user size
    _shared_server_load_balance 0 shared server load balance
    _shared_server_num_queues 2 number of shared server common queues


    转储shared pool 共享内存的内容
    SQL> alter session set events 'immediate trace name heapdump level 2' ;

    Session altered.

    直观查看shared pool结构:
    FREE LISTS:
    Bucket 0 size=32
    Bucket 1 size=40
    Bucket 2 size=48
    Bucket 3 size=56
    Bucket 4 size=64
    Chunk 09e3fffc0 sz= 64 free " "
    Bucket 5 size=72
    Bucket 6 size=80
    Chunk 09d3fffb0 sz= 80 free " "

    RESERVED FREE LISTS:
    Reserved bucket 0 size=32
    Reserved bucket 1 size=4400
    Reserved bucket 2 size=8216
    Reserved bucket 3 size=8696
    Reserved bucket 4 size=8704
    Reserved bucket 5 size=8712
    Reserved bucket 6 size=8720
    Reserved bucket 7 size=9368
    Reserved bucket 8 size=9376
    Reserved bucket 9 size=12352
    Reserved bucket 10 size=12360
    Reserved bucket 11 size=16408
    Reserved bucket 12 size=32792
    Reserved bucket 13 size=65560
    Chunk 099c00088 sz= 212808 R-free " "
    Chunk 09a000088 sz= 212808 R-free " "
    Chunk 09a400088 sz= 212808 R-free " "
    Chunk 09a800088 sz= 212808 R-free " "


    SQL> show parameter user_

    NAME TYPE VALUE
    ------------------------------------ ----------- ------------------------------
    license_max_users integer 0
    user_dump_dest string /opt/oracle/diag/rdbms/etldb2/
    etldb2/trace

    了解 X$KSMSP视图(Kernal Storage Memoty Management SGA HeaP)

    1、其中每一行都代表shared pool中的一个chunk(内存块)
    2、主要字段的解释
    ksmchcom:是注释字段,每个内存块被分配以后,注释会添加在该字段中。
    ksmchsiz:代表块大小
    ksmchcls:代表类型,主要有4类
    1)free
    free chunks 不包含任何对象的chunk,可以不受限制的被自由分配。
    2)recreate
    recreatable chunks:包含可以被临时移出内存的对象,在需要的时候,这个对象可以被重新创建。例如,许多存储共享sql代码的内存都是可以重建的。
    3)freeable
    freeable chunks:包含session周期或调用的对象,随后可以释放。这部分内存有时候可以全部或部分提前释放,但是注意,由于某些对象是中间过程产生的,这些对象不能临时被移除内存(因为不可以重建)
    4)perm
    permanent memory chunks:包含永久对象,通常不能独立释放。

    4.处理ORA-04031
    当尝试在共享池分配大块的连续内存失败(很多时候是由于碎片过多,而并非真是内存不足)时,oracle首先清除共享池中当前没有使用的多有对象,
    使空闲内存合并。如果任然没有足够大德单块内存可以满足需要,就会差生ora-04031错误。

    解决思路:
    使用flush shared pool 缓解共享池问题
    1、 刷新共享池:
    alter system flush shared pool;刷新共享池可以帮助合并碎片,强制老化sql,释放共享池,但是这通常是不推荐的做法。因为
    1)flush shared pool 会导致当前未使用的cursor被清除共享池,如果这些sql随后需要执行,那么数据库将经历大量的硬解析,系统将会经历严重的cpu争用,数据库将会产生激烈的latch竞争。
    2)如果应用没有使用绑定变量,大量类似的sql不停的执行,那么flush shared pool可能会带来短暂的改善,数据库很快会回到原来的状态。
    3)如果shared pool很大,并且系统非常的繁忙,刷新shared pool可能会导致系统挂起,对于类似系统尽量在系统空闲时进行。

    shared_pool_reserved_size参数的设置和作用
    1、shared_pool_reserved_size参数指定了保留的共享池空间,用于满足大的连续的共享池空间请求。当共享池出现多碎片时,请求大块空间会导致oracle大范围地查找并释放共享池内存来满足请求,由此可能会带来较为严重的性能下降,设置合适的shared_pool_reserved_size参数和_shared_pool_reserved_min_alloc参数可以避免由此导致的性能下降。_shared_pool_reserved_min_alloc这个参数控制这保留内存的控制和分配。缺省值为4400bytes,即当请求的内存大于这个值时就进入共享池保留空间分配内存。
    2、查看v$shared_pool_reserved视图可以判断共享池问题的引发原因。
    select free_space,avg_free_size,used_space,avg_used_size,request_failures,last_failure_size from v$shared_pool_reserved;
    若request_failures大于0且last_failure_size大于shared_pool_reserved_min_alloc,那么ora-04031错误就可能是因为共享池保留空间缺少连续空间所致。要解决这个问题,可以考虑加大shared_pool_reserved_min_alloc来降低缓冲进共享池保留空间的对象数目。并增大shared_pool_reserved_size 和 shared_pool_size来加大共享池保留空间的可用内存。如果request_failures > 0 并且 last_failure_size < _shared_pool_reserved_min_alloc,那么是因为在库高速缓冲缺少连续空间导致ORA-04031错误。对于这一类情况应该考虑降低_shared_pool_reserved_min_alloc,以放入更多的对象到共享池保留空间并加大shared_pool_size。

    表面看是共享池资源不足语句造成的。
    查询一下共享池参数配置
    SELECT free_space, avg_free_size,used_space, avg_used_size, request_failures,last_failure_size FROM v$shared_pool_reserved;
    FREE_SPACE AVG_FREE_SIZE USED_SPACE AVG_USED_SIZE REQUEST_FAILURES LAST_FAILURE_SIZE
    129027376 781984.097 100931920 611708.6061 1209 4000


    SQL> SELECT nam.ksppinm NAME, v.ksppstvl VALUE
    FROM x$ksppi n, x$ksppsv v
    WHERE n.indx = v.indx AND n.ksppinm LIKE '%shared%'
    ORDER BY 1;
    _shared_pool_reserved_min_alloc
    4400

    通过REQUEST_FAILURES > 0 并且 LAST_FAILURE_SIZE < SHARED_POOL_RESERVED_MIN_ALLOC ,可以知道是因为共享池库缓存不足造成,可以降低_shared_pool_reserved_min_alloc
    并且增加share_pool_size。


    5.我的处理方法
    因为我们使用了数据库内存自动管理,不方便修改share pool的大小,并且修改隐藏参数是有风险的,可能会引发其它的bug,我觉得可以从sql语句上控制产生ORA-04031发生。
    通过sql语句监控可以知道发生错误时候我们执行了清理历史分区的语句,类似下面的:
    alter table DW.TW_RS_I2000_PLATFORM_H drop partition P2012101415 ;
    alter table DW.TW_RS_I2000_PLATFORM_H drop partition P2012102223 ;
    alter table DW.TW_RS_I2000_PLATFORM_H drop partition P2012103107 ;
    alter table DW.TW_RS_I2000_STORAGE_H drop partition P2012100815 ;

    清除这些分区之前,oracle都需要把这些块读入共享池,然后再处理,既然share pool不足以一次装这么多新的数据块,那我们可以让共享池分批处理这些数据,就可以有效的避免ORA-04031错误

    通过一个简单的python脚本,把删除语句加工一下,每200行插入清理共享池的语句即可
    #!/usr/bin/python
    #Filename : droptbs.py
    import os
    num = 0
    file_src = open('/home/etl/etl_script/lisx/dropdw.txt')
    file_dest = open('/home/etl/etl_script/lisx/dropdw2.txt','a')
    for l in file_src.xreadlines():
    num += 1
    file_dest.write(l)
    if num % 200 == 0:
    file_dest.write('alter system flush shared_pool ; ')
    file_src.close()
    file_dest.close()
    再次执行删除清理表空间的脚本,数据库响应正常。

  • 相关阅读:
    小白月赛4 A 三角形
    小白月赛4 A 三角形
    Trouble HDU
    Trouble HDU
    K
    K
    2016年第七届蓝桥杯C/C++ A组国赛 —— 第一题:随意组合
    2016年第七届蓝桥杯C/C++ B组国赛 —— 第一题:一步之遥
    2016年第七届蓝桥杯C/C++ B组国赛 —— 第一题:一步之遥
    Koch Curve Aizu
  • 原文地址:https://www.cnblogs.com/caibird2005/p/3607241.html
Copyright © 2011-2022 走看看