[20181220]ORA-1000 "maximum open cursors exceeded".txt

lfree發表於2018-12-20

[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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章