対応バージョン
対応バージョン: Oracle Database 11.2 – 12.1
更新履歴
| 日付 | 更新概要 |
|---|---|
| 2015/02/15 | 記事公開 |
ORA-1000はOPEN_CURSORSの設定値不足やアプリケーションのカーソル操作の誤りなどで発生するエラーです。
カーソルとはSELECT文などの処理に関する情報を格納するSQLのプライベート領域を示すポインタとして使われるものです。
(例えばカーソル名 CUR_A というものがあった場合、プログラム上でCUR_Aを指定することによって、CUR_Aに定義されているSQL文の取得結果などを操作することができます。)
エラーメッセージ
ORA-01000 maximum open cursors exceeded.
発生原因
ORA-1000はカーソルオープンした数が、初期化パラメータOPEN_CURSORSの設定値を超えた場合に発生するエラーです。
データベース全体ではなく、1セッションでオープンが可能なカーソルの数である点に注意してください。
また、アプリケーションによって明示的に指定したカーソルだけでなく、内部的に発行されるディクショナリ操作などのSELECT文などにもカーソルが割り当てられます。(暗黙的カーソル)
発生要因例
よくあるのはプログラムのコードバグにより、カーソルのクローズをしていない場合や、プログラムの実装上多量のカーソルを開く必要がある場合に発生します。
同じセッションを使用して定期的にSQLを発行している場合や、コネクションプールによる実行時に顕在化することが多いです。
対処方法
基本的には初期化パラメータOPEN_CURSORSの値の妥当性の確認、対象のSQLを判別後プログラムのコード見直しを行います。
初期化パラメータのOPEN_CURSORSの値を大きくすることで対処可能ではありますが、カーソルを閉じ忘れており、カーソル数が増えていくようなコードバグの場合、メモリ領域の使用量が増えるだけで、いつか同じ問題が発生するなどの弊害が予想されます。
OPEN_CURSORSのデフォルト値は50です。
Oracle Database 11gR2におけるOPEN_CURSORSのOracle推奨値は500です。
推奨値については以下を参照ください。
https://docs.oracle.com/cd/E16338_01/server.112/b56312/build_db.htm#g23930
Oracle? Databaseパフォーマンス・チューニング・ガイド
11gリリース2 (11.2)
B56312-06
4 パフォーマンスを考慮したデータベースの構成
4.1 初期インスタンス構成のパフォーマンスの考慮事項
4.1.1 初期化パラメータ
対処例
OPEN_CURSORSの増加の対処例
SPFILEを使用している場合の変更
SQL*Plusにログイン後、以下のコマンドを実行します。
$ sqlplus / as sysdba
SQL> show parameter spfile
-- 上記にて使用している SPFILE のパスが出力される場合は SPFILE を使用しています。
SQL> set line 120 pages 1000 trim on
SQL> col name for a15
SQL> col value for a20
SQL> col sid for a10
-- 現在値の確認
SQL> select INST_ID, NAME, VALUE from gv$parameter where name in ('open_cursors');
-- SPFILE の内容の確認
SQL> select SID, NAME, VALUE from v$spparameter where name in ('open_cursors');
-- 値の変更
SQL> ALTER SYSTEM SET OPEN_CURSORS = <変更後の値> SCOPE=BOTH;
-- 現在値が変更されていることの確認
SQL> select INST_ID, NAME, VALUE from gv$parameter where name in ('open_cursors');
-- SPFILE の内容が更新されていることの確認(再起動時に同じ値が使用されることを確認)
SQL> select SID, NAME, VALUE from v$spparameter where name in ('open_cursors');PFILEを使用した変更については、以下を参照してください。
SPFILEとPFILEの概要と操作
エラー原因の確認と値の検討
カーソル数不足による異常終了では、アラートログに以下のようなメッセージが出力されます。
SQL*Plus等のクライアントなどで実行していたアプリケーションにORA-1000のエラーが戻されます。
再現性の確認
まずは再現性の確認が簡単な場合のアプローチです。
再実行して再現するか確認してください。再実行して再現しない場合は、カーソルをクローズしていないバグである可能性が高いです。
毎回再現する場合は、OPEN_CURSORSの値が推奨値(500)程度、少なくとも200以上であることを確認してください。メモリリソースの消費が増える可能性がある為、むやみに増加することは好ましくないですが、システムとして少なすぎると判断できる場合は値の増加による解決を試みてください。
対応に緊急性がある場合はメモリ量が十分に確保できていることを確認してOPEN_CURSORSの値を増加してください。
OPEN_CURSORSの値を増やした場合でも、実際にカーソルが使用されるまでメモリの消費はありません。
対象SQLとプログラムの判断
エラー対象となっているSQLを確認します。
OPEN_CURSORSに設定した値まで使用しているセッションとSQLを確認します。
確認した結果、エラーを発生している対象のアプリケーションを特定し、妥当な対応策(アプリケーションの改修か、OPEN_CURSORSの増加)を決定します。
現在カーソルを多く使用しているSQLを確認する。
NUM_CURSORSが現在使用しているカーソルの数です。
$ sqlplus / as sysdba
SQL> set line 120 pages 1000 trim on
SQL> col user_name for a25
SQL> col INST_ID for 9999
SQL> select inst_id, count(1) num_cursors, user_name, sql_id, sql_text from gv$open_cursor
2 group by inst_id, user_name, sql_id, sql_text
3 order by num_cursors;現在カーソルを多く使用しているセッションIDを確認する
OPEN_CURSORSの数だけ使用しているセッションを特定します。
$ sqlplus / as sysdba
SQL> set line 120 pages 1000 trim on
SQL> select inst_id, count(1) num_cursors, sid from gv$open_cursor
2 group by inst_id, sid order by num_cursors;使用しているプログラムを確認する
上記で出力したSID(セッションID)で対象を絞って出力してください。
SQL> set line 120 pages 1000 trim on
SQL> col username for a15
SQL> col machine for a30
SQL> col program for a30
SQL> col logon_time for a20
SQL> select s.inst_id, s.sid "SID", s.username "USERNAME", s.machine "MACHINE", s.program "PROGRAM",
2 to_char(s.logon_time, 'yy/mm/dd hh24:mi:ss') "LOGON_TIME"
3 from gv$session s, gv$process p
4 where s.paddr = p.addr
5 and s.inst_id = p.inst_id
6 and s.sid = [確認したいSID(セッションID)]
7 order by s.username, s.machine, s.program;