关于V$OPEN_CURSOR

在之前的一次讨论中,有同行指出V$OPEN_CURSOR中列出的不是OPEN CURSOR而是SESSION CACHED CURSOR,原因是在一次ORA-01000(maximum open cursors exceeded)事故中他没有从V$OPEN_CURSOR中找到大量的打开游标。 对于这个问题,我们可以利用JAVA程序做一个演示来说明,以下为JAVA代码:
package javaapplication2;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.jdbc.*;
import java.sql.*;public class Main {public static void main(String[] args) throws SQLException {try {Class.forName("oracle.jdbc.driver.OracleDriver");}catch(Exception e ){}Connection cnn1=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:G11R2", "maclean", "maclean");// Connection m[]=new Connection[2000];Connection myconn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:G11R2", "maclean", "maclean");Statement stat1=myconn.createStatement();ResultSet rst1=stat1.executeQuery("select * from v$version");while(rst1.next()){System.out.println(rst1.getString(1));}rst1=stat1.executeQuery("select distinct sid from v$mystat");while (rst1.next()){System.out.println("MY SID IS "+rst1.getString(1));}PreparedStatement s[]=new PreparedStatement[2000];PreparedStatement p;//ResultSet r[]=new ResultSet[2000];int i=0;while(i<2000){//  m[i]=DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.121:1521:G10R2", "maclean", "maclean");//s[i]=m[i].createStatement();//m[i].setAutoCommit(false);//s[i].execute("insert into testjava values(1)");p=myconn.prepareStatement("select /* FIND_ME_OPPO */ * from dual");p.execute();try {Thread.sleep(200);} catch (InterruptedException ex) {Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);}i++;System.out.println(i+" cursor is ok !");}}
}
以上JAVA代码会打个一个数据库会话,并在循环中不断以prepareStatement对象执行SQL语句,且我们不使用close()方法关闭prepareStatement所打开的游标,实际上这是很多JDBC应用产生ORA-01000问题的主要原因,开发人员在使用prepareStatement时不知道要使用close()方法以回收OPEN CURSOR资源。 注意这里在使用JDBC API时的表现(可能是目前最流行应用形式)和PL/SQL中的游标是存在区别的,在PL/SQL使用close cursor语句并不会真正意义上关闭游标。出于性能的考量,PL/SQL中的游标将被缓存以备将来使用,同时Oracle会维护一张cursor的LRU列表,但如果当本会话的游标数量即将达到open_cursors参数所定义的上限数量时,老的游标将被真正意义上close,以便open后来者。
The following is a technical explanation provided by Oracle Development:  The server caches cursors opened by the PL/SQL engine.  Each time a cursor is closed, it is really moved to an Least Recently Used (LRU) list of open cursors and left open.  This is done as a performance improvement by saving a 'round_trip' from Client to Server each time a cursor is opened.   Note that no optimization occurs.  In other words, the cursor caching code does not check to see if a particular query already has a cursor open; it simply creates another one.  This is done until OPEN_CURSORS is reached.  If you have OPEN_CURSORS cached as open, however, then if an identical query occurs, the server reuses the cached cursor.
可以通过以下语句来了解系统中真正意义上的打开着的游标:
select sum(a.value), b.name
from v$sesstat a, v$statname b
where a.statistic# = b.statistic#
and b.name = 'opened cursors current'
group by b.name;
编译并尝试运行以上程序:
compile:
Created dir: C:\Users\Maclean Liu\Documents\NetBeansProjects\JavaApplication2\dist
Copy libraries to C:\Users\Maclean Liu\Documents\NetBeansProjects\JavaApplication2\dist\lib.
Building jar: C:\Users\Maclean Liu\Documents\NetBeansProjects\JavaApplication2\dist\JavaApplication2.jar
To run this application from the command line without Ant, try:
java -jar "C:\Users\Maclean Liu\Documents\NetBeansProjects\JavaApplication2\dist\JavaApplication2.jar"
jar:
成功生成(总时间:0 秒)java -jar "C:\Users\Maclean Liu\Documents\NetBeansProjects\JavaApplication2\dist\JavaApplication2.jar"
MY SID IS 392
1 cursor is ok !
2 cursor is ok !
......................以上程序打开的会话为392,我们来观察392会话的CURSOR情况:SQL> select * from v$version;BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE    11.2.0.2.0      Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - ProductionSQL> select * from global_name;GLOBAL_NAME
--------------------------------------------------------------------------------
www.oracledatabase12g.comselect sql_text, cursor_type, count(*)from v$open_cursorwhere sid = 392group by sql_text, cursor_typeorder by 3 desc
/SQL_TEXT                                                     CURSOR_TYPE                                          COUNT(*)
------------------------------------------------------------ -------------------------------------------------- ----------
select /* FIND_ME_OPPO */ * from dual                        OPEN                                                     1279
select * from v$version                                      OPEN                                                        1
select privilege# from sysauth$ where (grantee#=:1 or grante DICTIONARY LOOKUP CURSOR CACHED                             1
select distinct sid from v$mystat                            OPEN                                                        1
insert into sys.aud$( sessionid,entryid,statement,ntimestamp OPEN-RECURSIVE                                              1
select /*+ connect_by_filtering */ privilege#,level from sys DICTIONARY LOOKUP CURSOR CACHED                             1可以看到"select /* FIND_ME_OPPO */ * from dual"语句在V$OPEN_CURSOR中存在1279条记录,
且CURSOR TYPE均为OPEN
注意V$OPEN_CURSOR视图中的CURSOR_TYPE列直到11g release 2中才出现,如果该列在9i/10g中就有的话那么可能就不会造成那么多misunderstand了,实际上V$OPEN_CURSOR中的记录来源于X$KGLLK:
SQL> select view_definition2    from v$fixed_view_definition3   where view_name = 'GV$OPEN_CURSOR';VIEW_DEFINITION
--------------------------------------------------------------------------------
select inst_id,kgllkuse,kgllksnm,user_name,kglhdpar,kglnahsh,kgllksqlid,kglnaobj,kgllkest,decode(kgllkexc, 0, to_number(NULL), kgllkexc),kgllkctp                                              -- CURSOR_TYPE
  from x$kgllkwhere kglhdnsp = 0and kglhdpar != kgllkhdlKGLHDPAR!=KGLLKHDL 该条件排除了父游标,所以V$OPEN_CURSOR列出的均是child cursor
KGLHDNSP ==> NAME SPACE =0 SQL> select distinct kgllkctp from X$kgllk;KGLLKCTP
----------------------------------------------------------------
SESSION CURSOR CACHED
PL/SQL CURSOR CACHED
OPEN
OPEN-RECURSIVE
DICTIONARY LOOKUP CURSOR CACHED
BUNDLE DICTIONARY LOOKUP CACHED
以上是六种CURSOR_TYPE,可以看到SESSION CURSOR CACHED和PL/SQL CURSOR CACHED也在其中:
SQL> select kgllkmod, kgllkctp, count(*)2    from X$KGLLK3   where KGLHDNSP = 04   group by kgllkmod, kgllkctp;KGLLKMOD KGLLKCTP                                                           COUNT(*)
---------- ---------------------------------------------------------------- ----------1 SESSION CURSOR CACHED                                                    321 DICTIONARY LOOKUP CURSOR CACHED                                          961 OPEN-RECURSIVE                                                           421 PL/SQL CURSOR CACHED                                                     191 OPEN                                                                    216
注意不管是何种CURSOR_TYPE,本质上都是child cursor上的library cache lock,KGLLKMOD=1即这些library cache lock的lock mode均是NULL,也就是breakable parse lock。
Null (N): special for session persistency  Null locks are special and are only acquired on executable objects (child cursors, procedures, functions, and packages) A broken null lock means the meta-data has changed. Null locks are special. They are acquired on objects that are to be executed (child cursor, procedure, function, package, or type body) and they are used to maintain an interest on an object for a long period of time (session persistency), and to detect if the object becomes invalid. Null locks can be broken at any time. This is used as a mechanism to notify a session that an executable object is no longer valid. If a null lock is broken, and thus the object is invalidated, it is an indication to the user who was holding the null lock that the object needs to be recompiled. A Null lock is acquired during the parse phase of SQL statement execution and is held as long as the shared SQL area for that statement remains in the shared pool. A null lock does not prevent any DDL operation, and can be broken to allow conflicting DDL operations, hence the term breakable parse lock. A Null lock on an object is broken when there is an exclusive pin on the object. A null lock on a read-only object is broken where there is an exclusive pin on any of the parent objects it depends on.  
因为CURSOR_TYPE(kgllkctp)列的出现我们在11.2中能够很方便地分辨OPEN CUROSR和SESSION CURSOR CACHED,但如果是在9i/10g/11gr1中则无法通过V$OPEN_CURSOR或X$KGLLK找出哪些是打开游标,另一些是会话缓存游标? 实际上Oracle Support在10g中已经意识到了这个问题,Metalink Note<Bug 7375227 - V$OPEN_CURSOR contains both open cursors and session cached cursors [ID 7375227.8]>说明了该问题:
Bug 7375227  V$OPEN_CURSOR contains both open cursors and session cached cursorsThis note gives a brief overview of bug 7375227.The content was last updated on: 10-JUL-2009Click here for details of each of the sections below.
Affects:Product (Component)	Oracle Server (Rdbms)Range of versions believed to be affected	Versions >= 10.2.0.1 but < 11.2Versions confirmed as being affected	10.2.0.3 Platforms affected	Generic (all / most platforms affected)Fixed:This issue is fixed in	11.2 (Future Release) Symptoms:Related To:Code Improvement(None Specified)V$OPEN_CURSOR DescriptionView V$OPEN_CURSOR contains both open cursors and session cached cursors andbefore this fix there was no way to distinguish them.This fix adds new column CURSOR_TYPE to V$OPEN_CURSOR which distinguishesbetween open cursors and cursors in the session cache. Values are:SYSTEM - recursive sql cursorsPL/SQL - for open pl/sql cursorsKNT CACHED, KKS CACHED, PL/SQL CACHED, KQD CACHED, KQD BUNDLE CACHED, KXCC CACHED - for cached cursors
Cursor Sharing的相关诊断事件:
[oracle@rh2 ~]$ oerr ora 10270
10270, 00000, "Debug shared cursors"
// *Cause: Enables debugging code in shared cursor management modules
// *Action:alter session set events '10270 trace name context forever, level 10';[oracle@rh2 ~]$ oerr ora 10277
10277, 00000, "Cursor sharing (or not) related event (used for testing)"
// *Cause:
// *Action:alter session set events '10277 trace name context forever, level 1';alter session set events  'immediate trace name library_cache level 10';

转载于:https://www.cnblogs.com/macleanoracle/archive/2013/03/19/2967818.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL中常用的的时间跟日期函数

GETDATE函数&#xff1a; 用途&#xff1a;前系统日期、时间 举例&#xff1a;select getdate() Dateadd函数&#xff1a; 用途&#xff1a;在向指定日期加上一段时间的基础上&#xff0c;返回新的 datetime值&#xff1a; 举例&#xff1a;向日期加上2天&#xff0c;select d…

软件工程导论课程主页 :12-13-2

关于课程 教师&#xff1a;徐强 — 喜欢和享受编程的人。 学生&#xff1a;热爱编程的同学。 40名同学是&#xff1a; 白炳博 陈祥男 何 毓 李 坤 毛荣景 王立华 吴嘉烽 虞邦瑞毕 生 丁佳楠 蒋 冰 梁高升 彭 宏 …

chmod修改权限

1.创建一个新文件 touch file_name 注意&#xff1a;linux没有文件拓展名的概念&#xff0c;创建时是什么样的就是什么样的&#xff01;&#xff01;&#xff01; 2.查看权限 d:代表是一个目录 -&#xff1a;普通文件 r&#xff1a;读权限 w&#xff1a;写/修改的权限 x…

python学习之 字符串前'r'的用法

6.4.3 原始字符串操作符( r/R ) 关于原始字符串的目的&#xff0c;在 Python1.5 里面已经有说明&#xff0c;是为了对付那些在字符串中出现的特殊字符(下面的小节会介绍这些特殊字符)。在原始字符串里&#xff0c;所有的字符都是直接按照字面的意思来使用&#xff0c;没有转义特…

chown 和chgrp 软链接

1.修改文件所属主&#xff1a;chown -R -h owner file_name -R&#xff1a;对该目录下属所有子目录进行同样的操作 -h &#xff1a;修改符号链接文件的属主十不影响链接的使用 eg&#xff1a;chown paper project 文件project的所有权限都给了paper这个人 2.修改文件的…

初始化--代码

public class A{public static int X; //1static A(){X B.Y 1; //2 找B.Y时就会执行YA.X1;}}public class B{public static int Y A.X 1;static B(){}} 调用A.X B.Y,调用时&#xff0c;几乎同时执行类内部的静态数据成员&#xff0c;结果X0,Y1,再调用静态构造函数&a…

WebConfig Authorization 节点

授权的目的是确定是否应该授予某个标识对给定资源请求的访问权限类型。有两种基本方式来授予对给定资源的访问权限&#xff1a; 文件授权文件授权由 FileAuthorizationModule 执行&#xff0c;它在使用 Windows 身份验证时处于活动状态。它执行 .aspx 或 .asmx 处 理程序文件的…

Oracle buffer状态深入剖析

这篇文章是参考甲骨论老相老师的教学视频:http://v.youku.com/v_show/id_XMzkyMjA4NDM2.html所做学习笔记1. 什么是buffer之前提过很多次啦&#xff0c; 其实在oracle数据文件中最小的单位就是block, 而用户读取block数据时&#xff0c;oracle就会将block的数据放入缓存&#x…

java整数类型

1.整数数据在java中有三种表达形式&#xff1a;八进制&#xff0c;十进制&#xff0c;十六进制 2.整数类型的取值范围&#xff1a; 数据类型 内存的空间&#xff08;8位等于1字节&#xff09; 取值范围 byte&#xff1a; 8 …

目录与文件的相关操作

绝对路径与相对路径 绝对路径&#xff1a;路径写法一定是由根目录写起&#xff0c;例如&#xff1a;/home/zhangj这个目录。相对路径&#xff1a;不是由/写起&#xff0c;例如由&#xff1a;/home/zhangj要到/home/lostfound下面时&#xff0c;可以写成cd ../lostfound&#xf…

第二章 findxargs

1.find pathname -options [-print - exec/-ok] find 命令格式 2.pathname :目录的路径 3.-print : 将匹配的文件以标准方式输出 4.-exec :对匹配的文件执行该参数的shell命令形式为command space {} space\; 例如&#xff1a;find . -name 1 -exec cat {} \ ; 找到名字是…

数据库使用

1.启动数据库服务器 win r services.msc 找到mysql 右键启动 以管理员身份运行cmd 2.启动: net start mysql 3.关闭&#xff1a;net stop mysql 4.登录&#xff1a; mysql -h ip -P 端口 -u 用户名 -p C:\Windows\system32>mysql -h localhost -P 3306 -u root -p E…