ora-04031处理过程,欢迎进行讨论

本文针对ORA-04031错误进行了详细分析,并提供了多种解决方案,包括调整保留区设置、使用dbms_shared_pool.keep等方法,帮助读者有效解决因共享内存不足引起的错误。
解决ora-04031错误
一、错误提示:
> EXP-00008: ORACLE error 4031 encountered
> ORA-04031: unable to allocate 4096 bytes of shared memory  
("shared pool","BEGIN  :EXEC_STR := SYS.DBMS...","PL/SQL MPCODE","BAMIMA: Bam Buffe
二、错误原因:
共享内存太小,存在一定碎片,没有有效的利用保留区,造成无法分配合适的共享区。
三、解决步骤:
1.查看当前环境
SQL>   show sga
  
   Total System Global Area  566812832 bytes
   Fixed Size                    73888 bytes
   Variable Size              28811264 bytes
   Database Buffers          536870912 bytes
   Redo Buffers                1056768 bytes
   
         show parameter shared_pool
   NAME                                 TYPE    VALUE
   ------------------------------------ ------- -----
   shared_pool_reserved_size            string  1048576
   shared_pool_size                     string  20971520
   
   SQL> select sum(free_space) from v$shared_pool_reserved;
   
   SUM(FREE_SPACE)
   ---------------
           1048576      
            
   我们可以看到没有合理利用保留区         
   
   SQL> SELECT SUM(RELOADS)/SUM(PINS) FROM V$LIBRARYCACHE;
  
              SUM(RELOADS)/SUM(PINS)
              ----------------------
                          .008098188
                          
              不算太严重  
         SQL> SELECT round((B.Value/A.Value)*100,1) hardpaseperc
                FROM V$SYSSTAT A,  
                     V$SYSSTAT B
               WHERE A.Statistic# = 171
                 AND B.Statistic# = 172
                 AND ROWNUM = 1;
                  
              hardpaseperc
              ------------------   
              26.5
               
2.查看保留区使用情况
SQL>   SELECT FREE_SPACE,
                FREE_COUNT,
                REQUEST_FAILURES,
                REQUEST_MISSES,
                LAST_FAILURE_SIZE  
          FROM V$SHARED_POOL_RESERVED;
  
   FREE_SPACE FREE_COUNT REQUEST_FAILURES REQUEST_MISSES LAST_FAILURE_SIZE
   ---------- ---------- ---------------- -------------- -----------------
      1048576          1              146              0              4132
      
   最近一次申请共享区失败时该对象需要的共享区大小4132
   
   select name from v$db_object_cache where sharable_mem = 4132;
   name
   ----------------
   dbms_lob
   
   -- dbms_lob正是exp时申请保留区的对象
3.查看导致换页的应用
SQL> select * from x$ksmlru where ksmlrsiz>0;                                                                        
                                                                                                                       
         ADDR     INDX    INST_ID KSMLRCOM      KSMLRSIZ  KSMLRNUM KSMLRHON KSMLROHV KSMLRSES                                   
                                                                                                                              
         50001A88 0          1 BAMIMA: Bam Buffer  4100         64 DBMS_DDL 402745060 730DEB9C                                 
                                                                                                                              
         50001ACC 1          1 BAMIMA: Bam Buffer  4108        736 DBMS_SYS_SQL 1909768749 730D0838                           
                                                                                                                              
         50001B10 2          1 BAMIMA: Bam Buffer  4112       1576 STANDARD 2679492315 730D7E20                                
                                                                                                                              
         50001B54 3          1 BAMIMA: Bam Buffer  4124       1536 DBMS_LOB 853346312 730DA83C                                 
                                                                                                                              
         50001B98 4          1 BAMIMA: Bam Buffer  4128       3456 DBMS_UTILITY 4041615653 730C5FC8                           
                                                                                                                              
         50001BDC 5          1 BAMIMA: Bam Buffer  4132       3760 begin :1 := dbms_lob.getLeng...  2942875191 730CFFCC        
                                                                                                                              
         50001C20 6          1 state objects       4184       1088 0 00                                                        
                                                                                                                              
         50001C64 7          1 library cache       4192        488 EXU8VEW   2469165743 730C1C68                              
                                                                                                                              
         50001CA8 8          1 state objects       4196         16 0 730C0B90                                                  
                                                                                                                              
         50001CEC 9          1 state objects       4216       3608 0 730D0838  
         
3.分析各共享池的使用情况
SQL> select KSPPINM,KSPPSTVL                              
        from x$ksppi,                                       
             x$ksppcv                                       
       where x$ksppi.indx = x$ksppcv.indx                  
         and KSPPINM = '_shared_pool_reserved_min_alloc';   
                                                            
       KSPPINM         KSPPSTVL           
       -------------------------------   --------           
       _shared_pool_reserved_min_alloc   4400    --(门值)           
         
           我们看到INDX=5,DBMS_LOB造成换页(就是做exp涉及到lob对象处理造成的换页情况),换出
       最近未使用的内存,但是换出内存并合并碎片后在共享区仍然没有合适区来存放数据,说明共享
       区小和碎片过多,然后根据_shared_pool_reserved_min_alloc的门值来申请保留区,而门值为4400,
       所以不符合申请保留区的条件,造成4031错误。我们前面看到保留区全部为空闲状态,所以我们可以
       减低门值,使更多申请共享内存比4400小的的对象能申请到保留区,而不造成4031错误。
        
4.解决办法:
       1).增大shared_pool (在不DOWN机的情况下不合适)
       2).打patch   (在不DOWN机的情况下不合适)
       3).减小门值 (在不DOWN机的情况下不合适)
         因为LAST_FAILURE_SIZE<_shared_pool_reserved_min_alloc所以表明没有有效的使用保留区                 
         SQL> alter system set "_shared_pool_reserved_min_alloc" = 4000;
              alter system set "_shared_pool_reserved_min_alloc"=4000
                               *
              ERROR at line 1:
              ORA-02095: specified initialization parameter cannot be modified
  
              -- 9i的使用方法alter system set "_shared_pool_reserved_min_alloc"=4000 scope=spfile;
               
       4).使用alter system flush shared_pool; (不能根本性的解决问题)
       5).使用dbms_shared_pool.keep
        
5.
       由于数据库不能DOWN机,所以只能选择3)和4)
       运行dbmspool.sql            
       SQL> @/home/oracle/products/8.1.7/rdbms/admin/dbmspool.sql
       找出需要keep到共享内存的对象   
                                                                                      
   SQL> select a.OWNER,                                                            
              a.name,                                                              
              a.sharable_mem,                                                           
              a.kept,                                                                  
              a.EXECUTIONS ,                                                            
              b.address,                                                               
              b.hash_value                                                              
         from v$db_object_cache a,                                                      
              v$sqlarea b                                                               
        where a.kept = 'NO' and                                                            
          (( a.EXECUTIONS > 1000                                                      
            and a.SHARABLE_MEM > 50000)
            or  a.EXECUTIONS > 10000)                                                   
           and SUBSTR(b.sql_text,1,50) = SUBSTR(a.name,1,50);                           
       OWNER    NAME                        SHARABLE_MEM KEP EXECUTIONS ADDRESS  HASH_VALUE                                 
       -------  ----------------------—---  ------------ --- ---------- -------- ----------                              
                SELECT COUNT(OBJECT_ID)     98292        NO   103207    74814BF8 1893309624   
                  FROM ALL_OBJECTS   
                 WHERE OBJECT_NAME = :b1     
                   AND WNER = :b2
                 
                STANDARD                    286632       NO   13501
                DBMS_LOB                    98292   NO   103750
                DBMS_LOB               47536        NO   2886542
                DBMS_LOB               11452        NO   2864757
                DBMS_PICKLER                10684        NO   2681194
                DBMS_PICKLER                5224         NO   2663860
                 
       SQL> execute dbms_shared_pool.keep('STANDARD');
       SQL> execute dbms_shared_pool.keep('74814BF8,1893309624','C');            
       SQL> execute dbms_shared_pool.keep('DBMS_LOB');  
       SQL> execute dbms_shared_pool.keep('DBMS_PICKLER');
       SQL> select OWNER, name, sharable_mem,kept,EXECUTIONS from v$db_object_cache where kept = 'YES' ORDER BY sharable_mem;
       SQL> alter system flush shared_pool;      
       System altered.                        
              
       SQL> SELECT POOL,BYTES FROM V$SGASTAT WHERE NAME ='free memory';
        
       POOL             BYTES
       ----------- ----------
       shared pool    7742756
       large pool      614400
       java pool        32768                       
        
       [oracle@ali-solution oracle]$ sh /home/oracle/admin/dbexp.sh
        
       [oracle@ali-solution oracle]$ grep ORA- /tmp/exp.tmp
       未发现错误,导出数据成功
        
四、建议:由于以上解决的方法是在不能DOWN机的情况下,所以没能动态修改初始化参数,
       但问题的本质是共享区内存过小,需要增加shared pool,使用绑定变量,才能根本
       的解决问题,所以需要在适当的时候留出DOWN机时间,对内存进行合理的配置。

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

转载于:http://blog.itpub.net/10522815/viewspace-364436/

已经博主授权,源码转载自 https://pan.quark.cn/s/a4b39357ea24 QueueForMcu 基于单片机实现的队列功能模块,主要用于8位、16位、32位非运行RTOS的单片机应用,兼容大多数单片机平台。 开源代码:https://.com/xiaoxinpro/QueueForMcu 一、特性 动态创建队列对象 动态设置队列数据缓冲区 静态指定队列元素数据长度 采用值传递的方式保存队列数据 二、快速使用 三、配置说明 目前QueueForMcu只有一个静态配置项,具体如下: 在文件 中有一个宏定义 用于指定队列元素的数据长度,默认是 ,可以根据需要更改为其他数据类型。 四、数据结构 队列的数据结构为 用于保存队列的状态,源码如下: 其中 为配置项中自定义的数据类型。 五、创建队列 1、创建队列缓存 由于我们采用值传递的方式保存队列数据,因此我们在创建队列前要手动创建一个队列缓存区,用于存放队列数据。 以上代码即创建一个大小为 的队列缓存区。 2、创建队列结构 接下来使用 创建队列结构,用于保存队列的状态: 3、初始化队列 准备好队列缓存和队列结构后调用 函数来创建队列,该函数原型如下: 参数说明: 参考代码: 六、压入队列 1、单数据压入 将数据压入队列尾部使用 函数,该函数原型如下: 参数说明: 返回值说明: 该函数会返回一个 枚举数据类型,返回值会根据队列状态返回以下几个值: 参考代码: 2、多数据压入 若需要将多个数据(数组)压入队列可以使用 函数,原理上循环调用 函数来实现的,函数原型如下: 参数说明: 当数组长度大于队列剩余长度时,数组多余的数据将被忽略。 返回值说明: 该函数将返回实际被压入到队列中的数据长度。 当队列中的剩余长度富余...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值