<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-13  評論-28  文章-63  trackbacks-0

    診斷查詢
    以下 SQL 查詢有助于診斷 ORA-01000 問題。要執(zhí)行這些查詢,需要以管理員身份登錄數(shù)據(jù)庫,或獲得數(shù)據(jù)庫管理員從那些 v$ 視圖中進行選擇的授權(quán)。

    1. 檢查數(shù)據(jù)庫中的 OPEN_CURSORS 參數(shù)值。
    Oracle 使用 init.ora 中的初始化參數(shù) OPEN_CURSORS 指定一個會話一次最多可以擁有的游標數(shù)。缺省值為 50。遺憾的是,此缺省值通常對 WebLogic Server 這樣的系統(tǒng)來說過小。要獲得數(shù)據(jù)庫中 OPEN_CURSORS 參數(shù)的值,可以使用以下查詢:
    SQL> show parameter open_cursors;

    NAME TYPE VALUE
    ------------------------------------ ----------- ---------------
    open_cursors integer 1000


    重要的是將 OPEN_CURSORS 的值設(shè)置得足夠大,以避免應用程序用盡所有打開的游標。應用程序不同,該值也不同。即便會話打開的游標數(shù)未達 OPEN_CURSORS 指定的數(shù)量(即設(shè)置的值高于實際需要的值),也不會增加系統(tǒng)開銷。

    2. 獲取打開的游標數(shù)
    下面的查詢按降序顯示用戶“SCOTT”為每個會話打開的游標數(shù)。
    SQL> select o.sid, osuser, machine, count(*) num_curs
    2 from v$open_cursor o, v$session s
    3 where user_name = 'SCOTT' and o.sid=s.sid
    4 group by o.sid, osuser, machine
    5 order by num_curs desc;
    SID OSUSER MACHINE NUM_CURS
    -----------------------------------------------------
    217 m1 1000
    96 m2 10
    411 m3 10
    50 test 9

    在 WebLogic Server 中使用連接池時,此查詢中的 user_name 應為用于創(chuàng)建連接池的 user_name(假定是從連接池得到連接)。該查詢結(jié)果還給出了計算機名稱。請在查詢結(jié)果中找出打開游標數(shù)量大的 SID 和運行 WebLogic Server 的計算機的名稱。

    請注意,v$open_cursor 可以跟蹤會話中 PARSEDNOT CLOSED 的動態(tài)游標(使用 dbms_sql.open_cursor() 打開的游標)。它不會跟蹤未經(jīng)分析(但已打開)的動態(tài)游標。在應用程序中使用動態(tài)游標并不常見。本模式的前提是未使用動態(tài)游標。

    3. 獲取為游標執(zhí)行的 SQL。使用在以上查詢結(jié)果中找到的 SID 運行下面的查詢:

    SQL> select q.sql_text
    2 from v$open_cursor o, v$sql q
    3 where q.hash_value=o.hash_value and o.sid = 217;

    SQL_TEXT
    ------------------------------------------------------------------------------------------------------------------------
    select * from empdemo where empid='212'
    select * from empdemo where empid='321'
    select * from empdemo where empid='947'
    select * from empdemo where empid='527'
    ...


    結(jié)果將顯示正在連接上執(zhí)行的查詢。它提供了一個入手點,讓您可以反向跟蹤到打開游標的來源。返回頁首

    常見成因及解決辦法
    下面是查找問題成因及可能的解決辦法的步驟。

    代碼慣例
    此問題的最常見成因是未正常關(guān)閉 JDBC 對象。使用
    診斷查詢中第三個查詢的結(jié)果在應用程序代碼中反向跟蹤,確保將所有 JDBC 對象都正常關(guān)閉。BEA 建議在 finally 塊中顯式關(guān)閉 Connection、Statement 和 ResultSet 等 JDBC 對象,以確保無論是在正常還是異常情況下都將所有 JDBC 對象關(guān)閉。下面是一個常規(guī)示例:

    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;

    try {
    conn = getConnection(); //Method getConnection will return a JDBC Connection
    stmt = conn.createStatement();
    rs = stmt.executeQuery("select * from empdemo");
    // do work
    } catch (Exception e) {
    // handle any exceptions
    } finally {
    try {
    if(rs != null)
    rs.close();
    } catch (SQLException rse) {}
    try {
    if(stmt != null)
    stmt.close();
    } catch (SQLException sse) {}
    try {
    if(conn != null)
    conn.close();
    } catch (SQLException cse) {}
    }


    請避免采用任何放棄 JDBC 對象的代碼慣例。下面的代碼慣例在每個循環(huán)迭代中都獲得一個新的 Connection、Statement 和 ResultSet,但它沒有關(guān)閉每個迭代的 JDBC 對象。因此,它會導致 JDBC 對象泄漏。

    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;
    String[] queries = new String[10];
    //Define queries

    try {
    for(int i = 0; i < 10; i++) {
    conn = getConnection();
    stmt = conn.createStatement();
    rs = stmt.executeQuery(queries[i]);
    // do work
    }
    } catch (Exception e) {
    // handle any exceptions
    } finally {
    try {
    if(rs != null)
    rs.close();
    } catch (SQLException rse) {}
    try {
    if(stmt != null)
    stmt.close();
    } catch (SQLException sse) {}
    try {
    if(conn != null)
    conn.close();
    } catch (SQLException cse) {}
    }


    盡管根據(jù) JDBC 規(guī)范的規(guī)定,關(guān)閉 Connection 時正常情況下也會將 Statement 和 ResultSet 關(guān)閉,但好的做法是:如果在一個 Connection 對象上創(chuàng)建了多個 Statement,則在使用完 Statement 和 ResultSet 后立即顯式將它們關(guān)閉。如果未立即顯式關(guān)閉 Statement 和 ResultSet,游標可能會積聚并在關(guān)閉 Connection 前超過數(shù)據(jù)庫允許的最大數(shù)量。例如,在以下代碼片斷中,正常情況下通過 finally 塊關(guān)閉 Connection 時,也會將 ResultSet 和 Statement 關(guān)閉。不過,此代碼片斷在一個連接上創(chuàng)建了多個 Statement 和 ResultSet。因此在循環(huán)完成前,可能已發(fā)生“超出最多允許打開的游標數(shù)”問題。


    Connection conn = null;

    try{
    conn = getConnection();

    for(int i = 0; i < NUM_STMT; i++) {
    Statement stmt = null;
    ResultSet rs = null;

    stmt = conn.createStatement();
    rs = stmt.executeQuery(/*some query*/);
    //do work
    }
    } catch(SQLException e) {
    // handle any exceptions
    } finally {
    try{
    if(conn != null)
    conn.close();
    } catch(SQLException ignor) {}
    }




    返回頁首

    語句緩存
    為提高性能,WebLogic Server 提供了一種功能,讓您可以在使用連接池時將預處理語句和可調(diào)用語句載入緩存。當 WebLogic Server 將預處理語句或可調(diào)用語句載入緩存時,在許多情況下,DBMS 將為每個打開的語句都保留游標。因此,語句緩存可能是“超出最多允許打開的游標數(shù)”問題的成因。“語句緩存大小”屬性決定在每個連接池實例中為每個連接緩存的預處理和可調(diào)用語句的總數(shù)。如果緩存的語句過多,可能會導致超過數(shù)據(jù)庫服務(wù)器上打開游標數(shù)的上限。

    請注意,各版本 WebLogic Server 的缺省語句緩存大小是有差異的。示例:

    要確定“超出最多允許打開的游標數(shù)”問題是否與語句緩存有關(guān),可以通過將語句緩存大小設(shè)置為 0 將此功能關(guān)閉或減少緩存大小,再確認是否仍會出現(xiàn)錯誤。如果在減少緩存大小后問題沒有發(fā)生,則說明連接池原有的語句緩存過大或 DBMS 中打開游標數(shù)的上限過低。可能需要考慮調(diào)整其中的一個值。如果發(fā)現(xiàn)連接上打開的游標數(shù)持續(xù)增加,但在將語句緩存大小設(shè)置為 0 后沒有出現(xiàn)這種現(xiàn)象,則可能說明存在游標泄漏問題。這可能是由使用的 JDBC 驅(qū)動程序所致,也可能是 WebLogic Server 本身的一個錯誤。請嘗試使用其它 JDBC 驅(qū)動程序。如果使用其它 JDBC 驅(qū)動程序后仍發(fā)生同樣的問題,請將此問題報告給 BEA,這樣支持工程師可以對問題做進一步探查,以確定該問題是否為 WebLogic Server 自身的一個錯誤。

    返回頁首

    數(shù)據(jù)庫驅(qū)動程序
    “超出最多允許打開的游標數(shù)”問題的另一個可能成因是 JDBC 驅(qū)動程序有問題。為分清問題是驅(qū)動程序問題還是 WebLogic 連接池問題,如果有可重現(xiàn)的測試案例,可以嘗試執(zhí)行以下步驟。

    1. 直接從驅(qū)動程序獲取連接。
    在測試案例中,繞過 WebLogic 連接池直接從驅(qū)動程序獲取 JDBC 連接。但請不要關(guān)閉連接,只需讓它們以數(shù)組或某種其它結(jié)構(gòu)形式保持打開狀態(tài),然后確認游標泄漏是否仍然存在。不關(guān)閉連接是因為要模擬使用連接池時的行為。使用連接池時,connection.close() 并未真正地關(guān)閉物理連接,而是將連接返回到池中。

    2. 嘗試使用其它 JDBC 驅(qū)動程序。
    可以嘗試使用其它供應商的 JDBC 驅(qū)動程序或升級版的驅(qū)動程序,然后確認問題是否仍然存在。可以使用元數(shù)據(jù)來驗證所使用的驅(qū)動程序是否正確。示例代碼與下面的類似:

    Connection conn = getConnection();
    DatabaseMetaData dmd = conn.getMetaData();
    System.out.println("JDBC Driver Name is " + dmd.getDriverName());
    System.out.println("JDBC Driver Version is " + dmd.getDriverVersion());

    3. XA 驅(qū)動程序錯誤
    如果使用的是 Oracle XA 驅(qū)動程序,并且數(shù)據(jù)庫中出現(xiàn)了大量類似“SELECT count (*) FROM SYS.DBA_PENDING_TRANSACTIONS”的查詢,則可能是 Oracle XA 驅(qū)動程序存在游標泄漏問題。在有關(guān) MetaLink 的案例 3151681 中有對此問題的描述,并且版本 10.1.0.2 中已修正了該問題。
    此外,在使用 XA 驅(qū)動程序時,請確保按在
    http://e-docs.bea.com/wls/docs81/jta/thirdpartytx.html#1075181 (English) 中所述,在 Database Server 上啟用 XA(例如,grant select on dba_pending_transactions to public)。

    如果問題是 JDBC 驅(qū)動程序問題,但又不得不使用該驅(qū)動程序,一種以變通方式解決游標泄漏問題的方法是不時重設(shè) WebLogic 連接池,或收縮連接池。有關(guān)重設(shè)或收縮連接池的方法,請參閱 WebLogic 文檔(如果是 8.1 版本,該文檔位于 http://e-docs.bea.com/wls/docs81/ConsoleHelp/domain_jdbcconnectionpool_control.html (Enlish))。

    posted on 2008-01-22 13:20 七匹狼 閱讀(1180) 評論(1)  編輯  收藏 所屬分類: oracle

    評論:
    # re: 探查“ORA-01000:超出最多允許打開的游標數(shù)” 2009-07-29 14:37 | ZengJerry
    謝謝  回復  更多評論
      
    主站蜘蛛池模板: 中国一级特黄的片子免费| 久久精品国产亚洲AV嫖农村妇女| 免费观看男人免费桶女人视频| 亚洲黄色免费观看| 免费在线视频你懂的| 最好看的中文字幕2019免费| 日韩精品人妻系列无码专区免费| 无码av免费一区二区三区| 久久精品国产这里是免费| 免费不卡在线观看AV| 69精品免费视频| 在线视频观看免费视频18| 免费做爰猛烈吃奶摸视频在线观看 | 在线观看国产区亚洲一区成人| 亚洲欧洲久久久精品| 国产亚洲成归v人片在线观看 | 黄页网站在线观看免费高清| 18勿入网站免费永久| 久久WWW免费人成人片| 在线免费观看一区二区三区| 免费v片在线观看无遮挡| 亚洲午夜福利精品无码| 亚洲精品少妇30p| 久久久久亚洲Av无码专| 色婷五月综激情亚洲综合| 色窝窝亚洲AV网在线观看| 一级做a爰黑人又硬又粗免费看51社区国产精品视| 老妇激情毛片免费| 国内精品免费久久影院| 免费无码又爽又刺激高潮视频| 中国人xxxxx69免费视频| 好吊妞在线成人免费| 免费一级一片一毛片| 久久亚洲2019中文字幕| 婷婷精品国产亚洲AV麻豆不片 | 亚洲国产精品一区二区九九| 狠狠亚洲婷婷综合色香五月排名 | 国产成人免费永久播放视频平台| 亚洲欧洲自拍拍偷精品 美利坚| 亚洲av永久无码精品国产精品| 亚洲精品在线网站|