【OPEN_CURSORS】oracle参数open_cursors和sess

系统 2420 0
    SQL
    
      >
    
     show parameter open_cursors           
    
      --
    
    
      每个session(会话)最多能同时打开多少个cursor(游标)  
    
    
  
NAME                                 TYPE        VALUE  

    
      --
    
    
      ---------------------------------- ----------- ------------------------------  
    
    
open_cursors                         
    
      integer
    
    
      300
    
      
SQL
    
      >
    
     show parameter session_cached_cursor  
    
      --
    
    
      每个session(会话)最多可以缓存多少个关闭掉的cursor  
    
    
  
NAME                                 TYPE        VALUE  

    
      --
    
    
      ---------------------------------- ----------- ------------------------------  
    
    
session_cached_cursors               
    
      integer
    
    
      20
    
      

SQL
    
      >
    
    
      select
    
    
      count
    
    (
    
      *
    
    ) 
    
      from
    
     v$open_cursor;  
    
      --
    
    
      是指当前实例的某个时刻的打开的cursor数目
    
    
      COUNT
    
    (
    
      *
    
    )  

    
      --
    
    
      --------  
    
    
      108
    
  
    

1、open_cursors与session_cached_cursor的作用?

open_cursors设定每个session(会话)最多能同时打开多少个cursor(游标)。session_cached_cursor 设定每个session(会话)最多可以缓存多少个关闭掉的cursor。想要弄清楚他们的作用,我们得先弄清楚oracle如何执行每个sql语句。

【OPEN_CURSORS】oracle参数open_cursors和session_cached_cursor详解!

看完上图后我们明白了两件事:

a、两个参数之间没有任何关系,相互也不会有任何影响。

b、两个参数有着相同的作用:让后续相同的sql语句不在打开游标,从而避免软解析过程来提供应用程序的效率。

2、如何正确合理设置参数的大小? a、如果Open_cursors设置太小,对系统性能不会有明显改善,还可能触发ORA-O1000:m~imum open CUrsOrs exceeded.的错误。如果设置太大,则无端消耗系统内存。我们可以通过如下的sql语句查看你的设置是否合理:

      SQL
      
        >
      
      
        SELECT
      
      
        MAX
      
      (A.VALUE) 
      
        AS
      
       HIGHEST_OPEN_CUR, P.VALUE 
      
        AS
      
       MAX_OPEN_CUR  
      
      
        2
      
      
        FROM
      
       V$SESSTAT A, V$STATNAME B, V$PARAMETER P  
      
      
        3
      
      
        WHERE
      
       A.STATISTIC# 
      
        =
      
       B.STATISTIC#  
      
      
        4
      
      
        AND
      
       B.NAME 
      
        =
      
      
        '
      
      
        opened cursors current
      
      
        '
      
      
        5
      
      
        AND
      
       P.NAME 
      
        =
      
      
        '
      
      
        open_cursors
      
      
        '
      
      
        6
      
      
        GROUP
      
      
        BY
      
       P.VALUE;  
      
    HIGHEST_OPEN_CUR MAX_OPEN_CUR  
    
      
        --
      
      
        -------------- --------------------  
      
      
        28
      
      
        300
      
    
      

HIGHEST_ OPEN CUR是实际打开的cursors 的最大值,MAX_OPEN_ CUR是参数Open_cursors的设定值,如果二者太接近,甚至触发eRA一01000错误,那么你就应该调大参数Open_cursors的设定 值。如果问题依旧没有解决,盲目增大Open_cursors也是不对的,这个时候你得检查应用程序的代码是否合理,比如说应用程序是否打开了游标,却没 有在它完成工作后没有及时关闭。以下语句可以帮助你确定导致游标漏出的会话:

        
              SELECT
        
         A.VALUE, S.USERNAME, S.SID, S.SERIAL#  
      
        
          FROM
        
         V$SESSTAT A, V$STATNAME B, V$SESSION S  
     
        
          WHERE
        
         A.STATISTIC# 
        
          =
        
         B.STATISTIC#  
       
        
          AND
        
         S.SID 
        
          =
        
         A.SID  
       
        
          AND
        
         B.NAME 
        
          =
        
        
          '
        
        
          opened cursors curent
        
        
          '
        
        ;  
      
        

同样,session_cached_cursors的值也不是越大越好,我们可以通过下面两条语句得出合理的设置。

              SQL
          
            >
          
          
            SELECT
          
           NAME, VALUE 
          
            FROM
          
           V$SYSSTAT 
          
            WHERE
          
           NAME 
          
            LIKE
          
          
            '
          
          
            %cursor%
          
          
            '
          
          ;  
      
    NAME                                                                  VALUE  
    
          
            --
          
          
            -------------------------------------------------------------- ----------  
          
          
    opened cursors cumulative                                             
          
            15095
          
            
    opened cursors 
          
            current
          
          
            34
          
            
    session 
          
            cursor
          
           cache hits                                             
          
            12308
          
            
    session 
          
            cursor
          
           cache 
          
            count
          
          
            775
          
          
            cursor
          
           authentications                                                  
          
            324
          
            
      
    SQL
          
            >
          
          
            SELECT
          
           NAME, VALUE 
          
            FROM
          
           V$SYSSTAT 
          
            WHERE
          
           NAME 
          
            LIKE
          
          
            '
          
          
            %parse%
          
          
            '
          
          ;  
      
    NAME                                                                  VALUE  
    
          
            --
          
          
            -------------------------------------------------------------- ----------  
          
          
    parse time cpu                                                          
          
            332
          
            
    parse time elapsed                                                     
          
            1190
          
            
    parse 
          
            count
          
           (total)                                                    
          
            9184
          
            
    parse 
          
            count
          
           (hard)                                                     
          
            1031
          
            
    parse 
          
            count
          
           (failures)                                                    
          
            3
          
        
          

session cursor cache hits就是系统在高速缓存区中找到相应cursors的次数,parse count(total)就是总的解析次数,二者比值越高,性能越好。如果比例比较低,并且有较多剩余内存的话,可以考虑加大该参数。

c、使用下面的sql判断'session_cached_cursors' 的使用情况。如果使用率为100%则增大这个参数值。

SQL > SELECT ' session_cached_cursors ' PARAMETER,

            
              2
            
                     LPAD(VALUE, 
            
              5
            
            ) VALUE,  
      
            
              3
            
                     DECODE(VALUE, 
            
              0
            
            , 
            
              '
            
            
               n/a
            
            
              '
            
            , TO_CHAR(
            
              100
            
            
              *
            
             USED 
            
              /
            
             VALUE, 
            
              '
            
            
              990
            
            
              '
            
            ) 
            
              ||
            
            
              '
            
            
              %
            
            
              '
            
            ) USAGE  
      
            
              4
            
            
              FROM
            
             (
            
              SELECT
            
            
              MAX
            
            (S.VALUE) USED  
      
            
              5
            
            
              FROM
            
             V$STATNAME N, V$SESSTAT S  
      
            
              6
            
            
              WHERE
            
             N.NAME 
            
              =
            
            
              '
            
            
              session cursor cache count
            
            
              '
            
            
              7
            
            
              AND
            
             S.STATISTIC# 
            
              =
            
             N.STATISTIC#),  
      
            
              8
            
                     (
            
              SELECT
            
             VALUE 
            
              FROM
            
             V$PARAMETER 
            
              WHERE
            
             NAME 
            
              =
            
            
              '
            
            
              session_cached_cursors
            
            
              '
            
            )  
      
            
              9
            
            
              UNION
            
            
              ALL
            
            
              10
            
            
              SELECT
            
            
              '
            
            
              open_cursors
            
            
              '
            
            ,  
     
            
              11
            
                     LPAD(VALUE, 
            
              5
            
            ),  
     
            
              12
            
                     TO_CHAR(
            
              100
            
            
              *
            
             USED 
            
              /
            
             VALUE, 
            
              '
            
            
              990
            
            
              '
            
            ) 
            
              ||
            
            
              '
            
            
              %
            
            
              '
            
            
              13
            
            
              FROM
            
             (
            
              SELECT
            
            
              MAX
            
            (
            
              SUM
            
            (S.VALUE)) USED  
     
            
              14
            
            
              FROM
            
             V$STATNAME N, V$SESSTAT S  
     
            
              15
            
            
              WHERE
            
             N.NAME 
            
              IN
            
            
              16
            
                             (
            
              '
            
            
              opened cursors current
            
            
              '
            
            , 
            
              '
            
            
              session cursor cache count
            
            
              '
            
            )  
     
            
              17
            
            
              AND
            
             S.STATISTIC# 
            
              =
            
             N.STATISTIC#  
     
            
              18
            
            
              GROUP
            
            
              BY
            
             S.SID),  
     
            
              19
            
                     (
            
              SELECT
            
             VALUE 
            
              FROM
            
             V$PARAMETER 
            
              WHERE
            
             NAME 
            
              =
            
            
              '
            
            
              open_cursors
            
            
              '
            
            );  
      
    PARAMETER              VALUE      USAGE  
    
            
              --
            
            
              -------------------- ---------- -----  
            
            
    session_cached_cursors    
            
              20
            
            
              100
            
            
              %
            
              
    open_cursors             
            
              300
            
            
              16
            
            
              %
            
          

当我们执行一条sql语句的时候,我们将会在shared pool产生一个library cache object,cursor就是其中针对于sql语句的一种library cache object.另外我们会在pga有一个cursor的拷贝,同时在客户端会有一个statement handle,这些都被称为cursor,在v$open_cursor里面我们可以看到当前打开的cursor和pga内cached cursor.

session_cached_cursor
这个参数限制了在pga内session cursor cache list的长度,session cursor cache list是一条双向的lru链表,当一个session打算关闭一个cursor时,如果这个cursor的parse count超过3次,那么这个cursor将会被加到session cursor cache list的MRU端.当一个session打算parse一个sql时,它会先去pga内搜索session cursor cache list,如果找到那么会把这个cursor脱离list,然后当关闭的时候再把这个cursor加到MRU 端.session_cached_cursor提供了快速软分析的功能,提供了比soft parse更高的性能.

更新2:

      OPEN_CURSORS是一个十分有趣的参数,经常有DBA发现自己的系统中的OPEN CURSORS十分大。我们看一个例子:
    
      SQL
      
        >
      
      
        select
      
       sid,value 
      
        from
      
       v$sesstat a,v$statname b 
      
        where
      
       a.statistic#
      
        =
      
      b.statistic# 
      
        and
      
       name
      
        =
      
      
        '
      
      
        opened cursors current
      
      
        '
      
      
        order
      
      
        by
      
      
        2
      
      ;

       SID      VALUE


      
        --
      
      
        -------- ----------
      
      
        5430
      
      
        93
      
      
        3527
      
      
        95
      
      
        4055
      
      
        96
      
      
        4090
      
      
        97
      
      
        2012
      
      
        98
      
      
        1819
      
      
        98
      
      
        5349
      
      
        102
      
      
        1684
      
      
        103
      
      
        1741
      
      
        116
      
      
        4308
      
      
        169
      
      
        1970
      
      
        170
      
      
        1369
      
      
        181
      
      
        4208
      
      
        184
      
      
        887
      
      
        214
      
      
        5215
      
      
        214
      
      
        3518
      
      
        214
      
      
        868
      
      
        214
      
      
        1770
      
      
        215
      
      
        4050
      
      
        215
      
      
        1809
      
      
        231
      
      
        3010
      
      
        235
      
      
        762
      
      
        237
      
      
        731
      
      
        471
      
      
        4013
      
      
        1066
      
      
        2648
      
      
        1152
      
      
        2255
      
      
        1172
      
      
        2322
      
      
        2620
      
    
      

我们看到这个系统的 OPEN_CURSORS 参数设置为 3000 ,而会话中当期打开 CURSOR 最大的会话居然达到了 2620 。在一般人的眼里, CURSOR 使用后就关闭了, OPENEDCURSORS 的数量应该不会太多,难道应用程序出现了 CURSOR 泄漏,有些应用使用了 CURSOR 没有关闭?实际上我们对 OPENCURSOR 的概念一直存在误解。认为只有正在 FETCH CURSOR OPEN 状态的,而一旦 FETCH 结束, CLOSECURSOR 后, CURSOR 就处于关闭状态了。因此一个会话中 OPEN 状态的 CURSOR 数量应该很少。事实上不是这样的,某些 CURSOR 在程序中是已经 CLOSE 了,但是 Oracle 为了提高 CURSOR 的性能,会对其进行缓冲,这些缓冲的 CURSOR ,在程序中的关闭只是一个软关闭,事实上,在会话中并未关闭,而是放在一个 CURSOR 缓冲区中。

Oracle9.2.0.5 之前, OPEN_CURSORS 参数的作用是双重的,一方面是限制一个会话打开的 CURSORS 的总量。另外一方面, OPEN_CURSORS 参数也作为 PL/SQLCURSOR 的缓冲。在 PL/SQL 中,如果某个 CURSOR 关闭了,这个 CURSOR 不会马上硬关闭,而是首先保存在 CURSOR 缓冲中。如果这个会话当前打开的 CURSOR 数量还没有达到 OPEN_CURSORS 参数的值,那么就可以先保持 OPEN 状态。如果当前打开的 CURSOR 数量已经达到了 OPEN_CURSORS 参数的限制,那么首先会关闭一个被缓冲的,实际当时并未打开的 CURSOR 。如果缓冲池中的所有 CURSOR 都是实际打开的,那么就会报 ORA-1000 "maximumopencursorsexceeded"

Oracle9.2.0.5 以后, OPEN_CURSORS 参数不再承担 PL/SQL 缓冲的工作 ,PL/SQL 中的 SQL 也可以使用 SESSION_CACHED_CURSORS 的会话缓冲了。这个参数就成为了一个纯粹的限制。

虽然如此, OPEN_CURSORS 参数仍然和 CURSOR 的缓冲机制密切相关,因为这个参数限制了当前某个会话打开 CURSOR 的最大值。设置一个较大的 OPEN_CURSORS 参数,可以避免出现 ORA-1000 ,同时也可以让会话缓冲更多的 CURSOR ,改善 SQL 解析的性能。不过这个参数设置的较大会占用较大的 PGA 空间,消耗一定的物理内存。因此这个参数也不是设置的越大越好,一般的 OLTP 系统中, 1000 3000 就足够了。在共享服务器模式的系统中,这个参数的设置要略微保守一些,因为这个参数越大,占用的 SGA 空间也就越大。

另外要注意的是,从 Oracle9.0 开始,这个参数就已经是动态的了,可以随时动态调整。

【OPEN_CURSORS】oracle参数open_cursors和session_cached_cursor详解!


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论