[20181220]ORA-1000 "maximum open cursors exceeded".txt
--//链接提到http://www.itpub.net/thread-2107244-1-1.html的ora-1000错误.我自己以前也遇到一例,实际上现在开发也没有解决.
--//实在不想再提交改正报告.
--//当时没有记录,现在重新记录看看.
1.环境:
XXXX> @ ver1
PORT_STRING VERSION BANNER
------------------- -------------- ----------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
XXXX> show parameter open_cursors
NAME TYPE VALUE
------------ ------- ------
open_cursors integer 8000
--//哈哈,没有办法为了规避这个错误,只能设置很大的值.我清楚的记得出现问题时我设置1000(可以动态设置,退出就生效).
--//依旧还是出现问题,只不过次数大大减少,查询dba_outstanding_alerts有时也有警告.
--//注意这个参数表示的是max # cursors per session,而不是整个数据库打开cursors的总数.(我以前在这里理解错误!!)
--//设置很大并不会导致共享内存之类的消耗.
--//在我的测试环境执行:
SYS@book> @ hide open_cursors
NAME DESCRIPTION DEFAULT_VALUE SESSION_VALUE SYSTEM_VALUE
-------------------------- --------------------------------------------- ------------- ------------- ------------
_close_cached_open_cursors close cursors cached by PL/SQL at each commit TRUE FALSE FALSE
open_cursors max # cursors per session FALSE 300 300
XXXX> select * from (select sid,count(*) from V$OPEN_CURSOR group by sid order by 2 desc) where rownum<=5;
SID COUNT(*)
---------- ----------
1357 154
6019 153
2018 152
2019 152
713 152
--//现在是上午,一般到下午就会很多(如果不退出应用程序的话).
--//出现这个问题,只要使用者退出再进入就ok了.
2.分析:
--//随便看一个sid=713.
--//我当时查询select * from V$OPEN_CURSOR where sid=713;发现里面有一些sql语句非常相似.
XXXX> select * from (select sql_text,count(*) from V$OPEN_CURSOR where sid=713 group by sql_text order by 2 desc) where rownum<=2;
SQL_TEXT COUNT(*)
------------------------------------------------------------ ----------
SELECT lis_requisition_info.requisition_state, 66
SELECT lis_requisition_info.requisition_state, 63
--//有两种风格的写法,查询看看这些相似语句是什么?
SELECT A.FORCE_MATCHING_SIGNATURE, COUNT (*)
FROM v$sqlarea a
WHERE sql_text LIKE ' SELECT lis_requisition_info.requisition_state%'
GROUP BY A.FORCE_MATCHING_SIGNATURE;
FORCE_MATCHING_SIGNATURE COUNT(*)
------------------------ ----------
10585972023561820239 464
5952195431604116876 3390
10068562918106072429 1075
3489546227993117356 1261
--//相似的执行语句很多,我已经设置cursor_sharing=force,也就是不应该存在没有使用绑定变量的情况.
--//执行如下:
select SQL_FULLTEXT from v$sqlarea where FORCE_MATCHING_SIGNATURE=3489546227993117356;
--//注我曾经在toad看这些语句感觉都是一样的,toad界面写这些语句已经格式化了.
XXXX> select len from (select sql_fulltext,dbms_lob.getlength(SQL_FULLTEXT) len from
v$sqlarea where FORCE_MATCHING_SIGNATURE=3489546227993117356 order by 2) where rownum<=10;
LEN
----
2379
2379
2380
2380
2381
2381
2382
2382
2383
2383
10 rows selected.
--//我不显示sql_fulltext字段太长,仅仅显示语句的长度,你可以发现长度逐步增加.
3.单独取出语句保存为文件比较看看.
R:\>diff -Nur a1.txt a2.txt
--- a1.txt Thu Dec 20 10:30:59 2018
+++ a2.txt Thu Dec 20 10:31:22 2018
@@ -44,4 +44,4 @@
lis_requisition_info.return_method,
lis_requisition_info.return_accept_remark
FROM lis_requisition_info
- WHERE (receive_time BETWEEN to_date(:"SYS_B_0",:"SYS_B_1") AND to_date(:"SYS_B_2",:"SYS_B_3")) AND (position2 = :"SYS_B_4") AND (receive_dept = :"SYS_B_5")
+ WHERE (receive_time BETWEEN to_date(:"SYS_B_0",:"SYS_B_1") AND to_date(:"SYS_B_2",:"SYS_B_3")) AND (position2 = :"SYS_B_4") AND (receive_dept = :"SYS_B_5")
--//可以看出差别,在WHERE语句前有空格,可以猜测语句在代码中没有关闭光标,并且每次使用拼接sql语句.在where前面都加一个空格.
--//还可以猜测程序代码是相互借鉴的,错误也是一样的类似,查看FORCE_MATCHING_SIGNATURE=5952195431604116876,后面的条件如下:
WHERE (send_time BETWEEN to_date(:"SYS_B_0",:"SYS_B_1") AND to_date(:"SYS_B_2",:"SYS_B_3")) AND (send_person = :"SYS_B_4")
--//实际上这个错误很容易修正,我提交了错误,可惜到现在都没有修正,二期项目是时我再次提交修正报表,还是依旧.
--//我真心不知道开发怎么想的,我曾经跟一些同行有过类似的交流,我感觉开发的惰性在作怪,在他们看来,只要程序代码
--//没有错,就不需要改动.
--//我曾经想过,删除open_cursors的设置,使用缺省值(缺省值=50),这样开发是否会改代码...^_^.
--//我还依稀记得出现错误时,没有任何人检查问题出在哪里,对于使用者也习惯了,程序时不时报出错误是正常的,退出继续使用就ok了.
--//那里知道这样丧失了学习提高的机会,不积跬步何以至千里,不积小胜何以来大胜.
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/267265/viewspace-2285851/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/267265/viewspace-2285851/