Oracle参数open_cursors和session_cached_cursor详解

简介:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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语句。

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

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%

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十分大。我们看一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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使用后就关闭了,OPENED CURSORS的数量应该不会太多,难道应用程序出现了CURSOR泄漏,有些应用使用了CURSOR没有关闭?实际上我们对OPEN CURSOR的概念一直存在误解。认为只有正在FETCHCURSOROPEN状态的,而一旦FETCH结束,CLOSE CURSOR后,CURSOR就处于关闭状态了。因此一个会话中OPEN状态的CURSOR数量应该很少。事实上不是这样的,某些CURSOR在程序中是已经CLOSE了,但是Oracle 为了提高CURSOR的性能,会对其进行缓冲,这些缓冲的CURSOR,在程序中的关闭只是一个软关闭,事实上,在会话中并未关闭,而是放在一个CURSOR缓冲区中。

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

Oracle  9.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系统中,10003000就足够了。在共享服务器模式的系统中,这个参数的设置要略微保守一些,因为这个参数越大,占用的SGA空间也就越大。

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











本文转自 客居天涯 51CTO博客,原文链接:http://blog.51cto.com/tiany/1547551,如需转载请自行联系原作者
目录
相关文章
|
SQL 运维 Oracle
Oracle 超时设置2:设置实例级参数
Oracle超时设置系列的第二篇文章,设置实例级参数
490 0
|
29天前
|
存储 SQL Oracle
【Oracle】玩转Oracle数据库(二):体系结构、存储结构与各类参数
【Oracle】玩转Oracle数据库(二):体系结构、存储结构与各类参数
42 7
|
4月前
|
SQL Oracle 关系型数据库
oracle查询数据库参数sql语句
oracle查询数据库参数sql语句
|
12月前
|
Oracle 关系型数据库
|
12月前
|
缓存 Oracle 关系型数据库
Oracle中控制commit的三个参数 commit_write, commit_logging和 commit_wait
Oracle中控制commit的动作有三个参数 commit_write, commit_logging和 commit_wait,按重要性分别说明如下
142 0
|
12月前
|
Oracle 前端开发 关系型数据库
使用隐含参数_disable_logging分析oracle写redo logfile的性能
oracle有一个隐含参数_disable_logging可以禁止日志的生成,这个参数当然不能在生产库使用,但我们可以将其因为与测试,例如,如果我们怀疑数据库写redo logfile存在性能问题,我们可以将这个参数设置为true,禁止写日志,看看oracle的性能提高了多少。
|
12月前
|
Oracle 关系型数据库
Oracle中filesystemio_options 和 disk_asynch_io 参数的设置
参考文档Doc ID 1987437.1 filesystemio_options参数,中间是这个参数的配置值。
174 0
|
Oracle 关系型数据库 数据挖掘
|
Oracle 关系型数据库 数据库
oracle学习35-rman备份-参数文件spfile损坏恢复
oracle学习35-rman备份-参数文件spfile损坏恢复
98 0