トラブル10
ディスクにアクセスできなくなった

 ディスクにアクセスできなくなる理由は,メディア自体の損傷のほか,ディスク・コントローラの不具合などいろいろ考えられる。Oracleを構成するファイルの中でも最も重要な「制御ファイル」にディスク障害などによる損傷があった場合,どうなってしまうのか。

図10●制御ファイルの損傷によるトラブルの経緯

 ここで紹介するトラブルは,夜間にバッチ処理を実行している最中にOracleが異常終了する,という形で現れた。後になってアラート・ログを調査した結果,トラブルの原因は制御ファイルの損傷であることが分かった(図10[拡大表示])。

 制御ファイルの損傷自体は,アラート・ログにORA-00210などのエラーが出力される以前のどこかのタイミングで発生している。ORA-00210として制御ファイルの異常を示す警告が出力されたのは,オンライン処理からバッチ処理へと運用を切り替えるタイミングでOracleを再起動した時だ。再起動した後,一応Oracleは稼働を続け,夜中のバッチ処理時にORA-00214が発生してOracleの異常終了というトラブルとなって顕在化した。Oracleを安全に運用するという観点では,ORA-00210の発生を見過ごし,そのままバッチ処理を開始したことが問題である。

 ところで,なぜORA-00210で制御ファイルの損傷が伝えられたにもかかわらず,ORA-00214で異常終了するまでOracleは動いていたのか。これは,たとえ多重化された制御ファイルの一部に異常が生じてもプロセスが制御ファイルにアクセスするまでは稼働できる,というOracleの機構によるものだ。多重化された制御ファイルの一部が損傷した状態で再起動を行うと,前述のORA-00210などのエラーを出力するが,とりあえずOracleは起動を完了する。

 しかし,データ・ファイルへの書き込み(この例ではバッチ処理)を行った際に,「制御ファイルとデータ・ファイルおよびログ・ファイルのバージョンが一致しない」ことを検知し,Oracleの異常停止を引き起こした。実際には,チェックポイント発生時にOracleのバックグラウンド・プロセスであるLGWR(ログ・ライター)*が制御ファイルへの書き込みを行った時点でOracleが異常終了したと考えられる。

図11●多重化した制御ファイルの異常への対処

 LGWRのトレースに記述されていたORA-00214は,制御ファイルへの書き込み時に,多重化された複数の制御ファイル間に整合性が無いことを表している。このような多重化された制御ファイルの1つに異常が生じた場合は,データベースを停止させた状態で,異常のある制御ファイルに正常な制御ファイルを上書きして対処する必要がある。具体的な作業手順は図11[拡大表示]に示した通りである。

 また,ディスク障害などによる損傷から制御ファイルを守るには,制御ファイルの多重化を進め,かつ,それぞれを別ディスク上に配置することによって影響を最小化する必要がある。さらに障害に備え,ある同一時点の整合性を保証するためにデータ・ファイル,制御ファイルの一貫性のあるデータベース全体のバックアップを取得しておくことも重要である。

データ・ブロックの破損を検出する

 データの保全性を高いレベルで求められるシステムでは,データ・ブロック単位で破損を検出し,被害を最小限に食い止めるための仕組みも必要になる。オブジェクトの構造を検証し,データ・ブロックの整合性・破損をチェックするには,本セミナーの第2回で紹介した,“ANALYZE TABLE <name> VALIDATE STRUCTURE CASCADE;”を定期的に実行する方法が一般的である。

 また,DB_VERIFYと呼ぶユーティリティを使ってチェックする方法もある。このユーティリティはOracle8iから追加されたものであり,オフライン状態のデータベースに対してデータ・ファイルの破損の有無を調査する機能を備える。詳しくは「Oracle8i ユーティリティ・ガイド」を参照してほしい。

 また,処理を行う度にブロック破損を検出する方法もある。これは,初期化パラメータにDB_BLOCK_CHECKSUM,DB_BLOCK_CHECKINGを設定することで使用できるようになる。DB_BLOCK_CHECKSUMにTRUEを指定すると,ディスクにデータ・ブロックを書き込む前に,すべてのブロック・ヘッダーにチェックサム(検査用にデータ・ブロックのバイト数から計算された数値)を格納するようになる。次にデータ・ブロックを読み込む際には,このチェックサムを使用してブロックの破損を検出してくれるため,チェック作業を自動化できる。ただし使用にあたっては,マニュアルによるとパフォーマンス上,1~2%程度のオーバーヘッドが生じるとされているので注意が必要だ。

 DB_BLOCK_CHECKINGは,Oracle8iから追加されたチェック機能である。もともとOracleはシステム表領域に対しては,デフォルトで常にブロックのチェックを行っている。DB_BLOCK_CHECKINGにTRUEを指定することによって,ユーザー表領域のデータ・ブロック,および索引ブロックが変更される際にもそれらのブロックがチェックされるようになる。ただし,この機能もパフォーマンス上のオーバーヘッドが発生するため注意して使う必要がある。

☆               ☆               ☆

 全6回を通じて解説してきたように,データベース管理者は様々なトラブルの原因を突き止め,適切に対処しなければならない。これらのトラブルは本来,未然に防ぐことが望ましい。そのための最良の方法は,日々の監視を注意深く行い,それを継続することに尽きると考えている。

(内藤 尚=システムコンサルタント オープンシステム統括部 マネージャー)