Oracle接続エラー(ORA-12528,ORA-214,ORA-12154,ORA-01122)対応の備忘録

# はじめに
仕事では運用チームに属している。お客様からWindows Server 2008R2サーバーが動作しなくなり、焦げ臭いがするとの報告があった。どうやらコンデンサまわりがやられているようでマザーボードの交換となった。

無事、マザーボードの交換を終えてWindows Server 2008R2サーバー自体は動作するようになったものの、データベースのOracle11g にて「ORA-12528」エラーが発生してデータベースに接続できない状態となってしまった。

# ORA-12528
ORA-12528：TNS:リスナー: 該当するインスタンスはすべて、新規接続をブロックしています。

このエラーコードで検索すると、Windowsの場合はサービス自体を再起動すると直るとの情報を見つけてサービスを再起動したが状況は変わらない。他にもリスナーがリロードされてないとの情報を見つけ「$ LSNRCTL RELOAD」としてリロードするも変わらず。

そもそも、下記コマンドで接続できずにORA-12528エラーとなってしまう。

```bat
sqlplus sys/<パスワード>@<接続記述子> AS SYSDBA
``` 

そこで、Oracle Databaseアラートログを見てみると、「ORA-214」エラーが出ていた。
アラートログの出力先は、Oracle Databaseのバージョンにより異なります。
・10gR2 以前
　$ORACLE_BASE/admin/DB/bdump/alert_(SID).log
・11gR1 以降
　$ADR_HOME/diag/rdbms/DB/(SID)/trace/alert_(SID).log

``` bat:alert_(SID).log
alter database mount exclusive
ORA-214 signalled during: alter database mount exclusive...
```

# ORA-214
ORA-00214:制御ファイル'string'バージョンstringがファイル'string'バージョンstringと矛盾しています。

>使用した制御ファイル、データファイル/ログ・ファイル、およびREDOログ・ファイルのバージョンが一致していない場合に発生します。

oradim.log(デフォルトでは$ADR_HOME/database/)を見ます。

``` bat:oradim.log
D:\oracle\product\11.2.0\db_1\bin\oradim.exe -startup -sid (SID) -usrpwd *  -log oradim.log -nocheck 0 
ORA-00214: 制御ファイル
'D:\ORACLE\FAST_RECOVERY_AREA\(SID)\CONTROL02.CTL' バージョン 512406 
'F:\ORACLE\PRODUCT\11.2.0\WH\(SID)\CONTROL01.CTL' バージョン 512401と矛盾しています
```
※実際は日本語が「?」で文字化けていたので、記事上では訂正してあります。

## 制御ファイルとは
制御ファイルは、データベースの構成情報と、データベースに矛盾がない状態を維持するための下記の情報が記録されています。

* データベース名
* データ・ファイルやREDOログ・ファイルの名前と場所
* 現行のREDOログ・ファイルのログ順序番号
* チェックポイント情報
* データベース作成時のタイム・スタンプなど

制御ファイルは最低1つ存在すればOracleは稼働するが、1つしかない場合に障害に遭うとデータベースはオープンできなくなるため、迅速にリカバリするために制御ファイルを異なるディスクに多重化しておく。Oracleでは最大8つまで多重化できる。

参照：[制御ファイルとREDOログ・ファイルの管理](http://www.atmarkit.co.jp/ait/articles/0408/27/news103.html)

## 復元方法
制御ファイルのバージョンが違っているとのことなので、バージョンを一致させる。
ORA-00214: controlfile path1\CONTROL01.CTL version <version No1> inconsistent with file path2\CONTROL02.CTL version <version No2> 

``` bat
move path2\CONTROL02.CTL path2\CONTROL02.CTL.bkup 
copy path1\CONTROL01.CTL path2\CONTROL02.CTL 
```

デフォルトの高速リカバリ領域(FAST_RECOVERY_AREA)にあるCONTROL02.CTLのバージョン512406がCONTROL01.CTLのバージョン512401より大きいので、CONTROL02.CTLのバックアップを取った上で、CONTROL01.CTLをCONTROL02.CTLとして上書きコピーします。これでバージョン512401に統一されます。

## 実対応
この記事は後で調べた上で書いているわけで、当時の復元方法としては丸ごとフルバックアップしたところから、CONTROL02.CTLとCONTROL01.CTLを両方コピーしたのです。

これでSYSユーザーでデータベースが接続できるようになったものの、通常ユーザーではORA-12154エラーで接続できませんでした。

# ORA-12154
ORA-12154:TNS: 指定された接続識別子を解決できませんでした

>tnsnames.ora構成ファイルに指定されたネット・サービス名を検出できないことを示すエラーです。一般的に、接続の際に使用した接続文字列が、tnsnames.ora から読み込めなかった場合に発生します。

tnsnames.ora や listener.oraの設定を見たが特におかしいところはないので、先程と同様にOracle Databaseアラートログを見てみると、下記のエラーが出ていました。

``` bat:alert_(SID).log
Errors in file D:\ORACLE\diag\rdbms\(SID)\(SID)\trace\(SID)_ora_7640.trc:
ORA-01122: データベース・ファイル1の照合検査でエラーが発生しました。
ORA-01110: データファイル1: 'F:\ORACLE\PRODUCT\11.2.0\WH\(SID)\SYSTEM01.DBF'
ORA-01207: ファイルは制御ファイルよりも新しいものです - 古い制御ファイル
ORA-1122 signalled during: alter database open...
```
※実際は日本語が「?」で文字化けていたので、記事上では訂正してあります。

# ORA-01122,ORA-01110,ORA-01207
ORA-01122: データベース・ファイル1の照合検査でエラーが発生しました。
ORA-01110: データファイル1: '(DBFファイルのパス)'
ORA-01207: ファイルは制御ファイルよりも新しいものです - 古い制御ファイル

データファイル「SYSTEM01.DBF」が破損しているようです、ORA-01207を見ると制御ファイルが古いということで、先程の対応としてフルバックアップ先から制御ファイルを置き換えたので、バージョンが合わなくなったと思われます。

よって対応としてフルバックアップ先からデータファイル「SYSTEM01.DBF」を置き換えました。
これにより接続することが出来るようになりました。

# 最後に
今回は知識が足りなく早急の復旧が望まれていたため、手っ取り早く1日前のフルバックアップ先から制御ファイルを置き換える対応を行ってデータベース復旧させたが、いい方法ではない。
あと、表面上のORAエラーに惑わされずに、アラートログを見て別のORAエラーが出てないか確認すること。リスナーログ(listener.log)はファイルサイズが大きい上にエラー内容はアラートログでこと足りるのであまり見る必要は無い。

次に同じことが発生した場合に正しい知識でデータベース復旧させる必要がある。
Oracle 11gR2以降なら「データリカバリアドバイザ」を利用することが出来る。
参照：[データファイル障害を復旧する（RMAN編）](http://sakusakuit.blog.fc2.com/blog-entry-160.html)

他にも「recover database using backup controlfile」コマンドがある。
参照：[制御ファイル障害からのリカバリ手順](http://d.hatena.ne.jp/yohei-a/20100106/1262740380)

必要なアーカイブログとオンラインREDOログが揃ってさえすれば、そのままリカバリはできるので、落ち着いて対応すること。

# その他参照
* [ORA-12528（Oracle起動エラー）](https://www51.atwiki.jp/tak_is/pages/52.html)
* [Oracle/エラー ORA-12528](http://wikiwiki.jp/miobottega/?Oracle%2F%A5%A8%A5%E9%A1%BC)
* [Q ORA-00214 が出力される場合の対処](http://tooljp.com/database/Oracle/faq/6616C2F32D844DA649257C4E00651D89.html)
* [Oracle 起動に関するエラー ORA-12154](https://www.shift-the-oracle.com/oerrs/ora-12154.html)
* [Oracle データベースの復旧](http://srgia.com/docs/RecoveringOracle-j.html)
* [起こってほしくはないけれど](http://blog.livedoor.jp/salva3/archives/28323043.html)