ORA-00600。
(最近更新されてないけど)Oracleの技術情報が豊富な Shift-The-Oracle さんでは、以下の様に解説されています。
サポートに問い合わせるか、その機能や使用方法をやめる。の二択であると言っても過言ではない。
ORA-00600 - オラクル・Oracle エラー FAQ
また、 Archive Redo Blog さんのところでは以下のように解説されています。
内部エラーというのは、文字通りOracleの内部で発生したエラーで、メッセージが定義されていないものがすべてこのコードで返されるというわけです。
[Oracle] ORA-00600エラーへの対処方法
エラーコードが同じであっても全然別物だったりするってことですね。
斯様に恐ろしいエラーなんですが、うちとこでも発生しました。こんな感じの。
ORA-00600: 内部エラー・コード、引数: [qernsRowP],・・・
発生した原因のひとつは直前に行ったインデックスってのはすぐ分かったんですが、さすがにインデックス張っただけでエラーが発生するとは思えないので、原因の特定を若干行いました。
結果分かったことは以下のようなものです。
テーブルの形はこんな感じ。
create table MEMBER (
USER_ID number(10) not null,
NAME varchar(50 char) not null,
primary key( USER_ID )
)
- 言語ソート JAPANESE_M_CI を使うと発生する。
業務上の理由から、辞書順のソートと比較が必要なため、JAPANESE_M_CI に設定しています。
具体的にはログオントリガで NLS_SORT を JAPANESE_M_CI に、NLS_COMP を LINGUISTIC に ALTER SESSION しています。
- PK かつ FK(外部参照制約)と文字列カラムへの複合インデックスを張ると発生する。
USER_ID と NAMEに対して張っています。
実際には PK や FKであるかどうかは関係ないかもしれませんが、文字列カラムへの単体のインデックスを張るだけでは発生しませんでした。
- 複合インデックスを張っているカラムを SELECT し、distinct をかけたインラインビューに対して rownum するクエリを発行すると発生する。
具体的には以下のようなクエリです。
select *
from (
select distinct USER_ID,NAME
from MEMBER
order by NAME
)
where rownum <= 10
distinctをつけなかったり、インラインビューになっている中のクエリだけで実行した場合には発生しませんでした。
もしかしたら order by も影響しているかもしれません。
これらの条件をすべて満たした環境下で発生しました。
NLS_SORT や NLS_COMP の設定を行っているログイントリガを無効化したり、インデックスをはずしたり、エラーが発生するクエリの中身を書き換えたり、どれかひとつの条件を満たさないようにすると起きなくなります。
また、ややこしいことに、再現性は100%ではなく、50%程度。
業務上よく実行されるクエリなのですぐに問題発生に気づきましたが、エラーが起こらずすんなり意図した結果が出ることもあれば、エラーが発生して落ちることもあり。
サポート直行といわれる ORA-00600 の情報はネット上でもほとんど見つからないので、原因を特定することすら困難だったりするようです。
サポートで解決した情報は外部に公開できませんし。
うちとこはサポート契約していないので、とりあえず要因のひとつになっているインデックスをあきらめました。
そこまで固執する必要があるインデックスじゃなかったのでこの解決策自体はいいんですが、ちょっとインデックス張るのが怖くなりましたね・・・。