自動復旧について
ここでは障害発生後の再起動で実施する自動復旧処理について記述します。
DBMSの基本的な知識を前提としています。
ここで使用する用語について、以下にその意味を記載しておきます。
- データベースが壊れる
-
データベースを構成するファイルの内容に異常があり、バックアップから戻す以外に回復する手段がないことです。
自動復旧で回復できる場合は、ここでは壊れているとは呼びません。
- 正常終了
-
プロセスが、正常に動作している状態から必要な終了処理を実行したのちに終了することです。
- 異常終了
-
正常終了以外のプロセスの終了です。
- 例外
-
プロセスが、実行中に何らかの異常を検知したときになる状態です。
何らかの異常には以下を含みます。
- 1. 実行環境の異常
- 例:メモリの確保に失敗した, ディスク容量が不足した。
- 2. プログラムの異常
- 例:不正なアドレスを参照した。
- チェックポイント
-
定期的に動作するデーモンスレッドにより、バッファ上のデータの一部がデータベースを構成するファイルにフラッシュされる処理です。
- 版
-
DoqueDBはOracleやSQL Serverのようなページ単位のロックではなく、MVCC(Multi Version Concurrency
Control)とタプル単位のロックにより、トランザクションごとに指定されるアイソレーションレベルを実現しています。
版とは、MVCCにより作られる、ある時点におけるデータベースの仮想的なコピーのことをいいます。
版はVERSION.SYDというファイルに格納され、データベースを構成する各ファイルに対して作成されます。
- 論理ログ
-
データベースに対する操作の内容を、SQL文単位あるいは処理対象レコード単位に記録するファイルです。
OracleのREDOログファイル、SQL Serverのトランザクションログと似たようなものです。
- 物理ログ
-
ある時点のデータベースイメージです。
版のうち特定の条件を満たすものを物理ログとして用います。
DoqueDBが行う自動復旧、は以下のような処理です。
OracleやSQL Serverが行う自動復旧をご存知なら、同様の処理と考えてください。
いつ:異常終了した後にプロセスを再度起動したときに、
誰が:DoqueDBのプログラムが自動的に
何を:データベースを
どうする:使用可能な状態にします。
前述のとおり、DoqueDBが自動復旧を行うのはプロセスが異常終了したときです。
以下でその具体的なケースを挙げます。
DoqueDBではプロセスが致命的な異常状態になったときに、データベースが壊われるような状態にならないように、発生以後のデータベース操作を一切行わなくなります。
致命的な異常状態には以下のようなものがあります。
- 予期せぬ例外が発生した。
- トランザクションのロールバックに失敗した。
- その他何らかのエラー処理が失敗した。
- 自動復旧処理が失敗した。
予期せぬ例外とは、例外のうちプログラムの中で発生を想定していない箇所で発生するものをいいます。
用語定義で例外の例に挙げたもののうちでは「不正なアドレス参照」が相当します。
つまり、1.のケースは残念ながらプログラムに不具合があることを意味します。
メモリーの確保失敗とディスク容量の不足は、発生を想定した実装がなされているので1.のケースには該当しません。
ただし、これらの例外がロールバックやエラー処理で発生すると、2.や3.のケースに該当することになります。
この場合は実行環境の問題と捉えられます。
自動復旧処理が失敗するのは、ディスク容量が不足しているのでない限り、データベースが壊れている可能性がいちばん高いと考えられます。
ディスク容量が不足している場合は、容量を空けてから再度自動復旧を試みれば回復します。
データベースが壊れている場合は、バックアップから戻す以外に回復の手段はありません。
データベースが壊れるのは、ディスクのハード的な障害でなければ、プログラムの不具合の可能性があります。
いずれにせよ、この状態になると、データベース操作を行おうとしても「Database is not available」または「Server is not available」という例外が発生して操作できません。
この状態になっていることは、ログに「Database is not available」(特定のデータベースのみ利用不可)または「Server is not
available」(システム全体が利用不可)という文字列が出力されているかをチェックすることで確認できます。
「Not available」な状態は正常に動作している状態ではないので、このプロセスの終了は異常終了であり、終了後の再起動で自動復旧が行われることになります。
DoqueDBプロセスは、正常終了した場合に終了処理の中で論理ログにその旨を記録します。
終了処理が行われずにプロセスが終了した場合、次のプロセスの起動時に前回異常終了したと判断され、自動復旧が行われます。
終了処理が行われないのは以下のようなケースが考えられます。
- サーバーホストの急な停止
- 急な電源断、OSの異常動作、ハードの異常などによりプロセスが動作しているサーバー自体が急に停止した場合です。
- 終了処理のタイムアウト
- OSシャットダウン時にOSがすべてのサービスを停止しようとしましたが、サービスプロセスの終了処理に時間がかかったため、タイムアウトによりプロセスが強制終了された場合です。
[補足]
PCの再起動により復旧したとの報告をいただくケースがありますが、無闇に再起動すると終了処理のタイムアウトにより、不必要に自動復旧処理を行うことになりかねません。
また、復旧処理には時間がかかる場合があるため、短い間隔でPCの再起動を繰り返すと、無意味に復旧処理を繰り返すことになります。
ログに「Not available」の出力を確認したら、サービスコントロールマネージャーを用いてサービスの再起動を行ったほうが安全です。
自動復旧処理は以下のような手順で行われます。(付随的な細かい処理は割愛します。)
- サービス起動時に論理ログの最後尾に「正常終了した」という記録があるか調べます。
⇒ 記録があれば何もしません。
⇒ 記録がなければ以下の処理を行います。
- 論理ログを最後からスキャンして、整合性の取れたデータがファイルにフラッシュされている時点(最後から2つ目のチェックポイント処理)を求めます。
- 物理ログを使用して、データベースイメージを2.で求めた時点に戻します。
- 論理ログをスキャンして、2.で求めた時点に実行中のトランザクションで異常終了時までにコミットされなかったものの中で実行された更新操作を取り消します。(UNDO)
- 論理ログをスキャンして、2.で求めた時点に実行中のトランザクションで異常終了時までにコミットされたものの中で実行された更新操作を再実行します。(REDO)
上記手順の結果、異常終了時までにコミットされていたトランザクションが実行された状態に回復します。
自動復旧が正常に実行されたかどうかは、ログに「Database recovered」と出力されたことで確認できます。
自動復旧処理は、サービスの起動時に(必要なら)暗黙のうちに実行されます。
復旧処理が完了するまでは、サービスが「開始中」のままで利用可能な状態にならないため、復旧処理に時間のかかる場合は注意が必要です。
以下で自動復旧処理に時間がかかるケースについて記します。
- 大量のデータベースがある場合
-
自動復旧はデータベースごとに順番に実行されます。
仮に自動復旧が必要ないデータベースであっても、必要かどうかを判定するために論理ログが検査されるため、数百程度のデータベースがあると、自動復旧に数分程度の時間がかかる場合があります。
- 大量の更新操作を実施後1時間以内に異常終了した場合
-
上記の手順で分かるように、UNDO、REDOの必要な更新操作が多ければ、それだけ復旧処理に時間がかかります。
使用環境にもよりますが、やはり数分程度の時間がかかる場合があります。
- 実行時間が長かったSQL文の実行後1時間以内に異常終了した場合
-
もっとも注意が必要なのはこのケースです。
-
用語定義にあるように、チェックポイント処理は定期ジョブとして動作します。
しかし、整合性を保つために、SQL文を処理するあいだは終了までチェックポイント処理は行われません。
したがって、実行に時間のかかるSQL文が実行されると、そのSQL文が終了するまでの長い時間チェックポイント処理が発生しないことになります。
-
このことは、時間のかかるSQL文を実行した直後に異常終了すると、そのSQL文が実行される前の時点からREDOの処理が行われることを意味します。
たとえば、全文索引の作成直後に異常終了すると、自動復旧において全文索引の作成にかかったのと同程度の時間(数十分の場合もある)がかかります。
-
このような場合を防ぐために、時間のかかる更新操作や索引作成を行ったあとにはcheckpoint文を実行してください。
checkpoint文は定期ジョブで行われるチェックポイント処理を強制的に実施させるためのSQL文です。
SQL> checkpoint;
DoqueDBの状態は、ログファイルを確認することである程度把握することができます。
ログファイルは以下の場所に出力されます。
<インストールパス>/log/syslog.csv
重要な出力について以下に記します。
- [INFO] Checkpoint occurred
-
チェックポイント処理が行われたことを示します。
- [INFO] Server terminated
-
正常終了したことを示します。
- [INFO] Database recovered
-
自動復旧処理が行われ、成功したことを示します。
- [INFO] Server initialized
-
サーバーが処理を受け付ける状態になったことを示します。
- [ERR] Recovering database ‘DB1’ failed.
-
データベースの自動復旧に失敗したことを示します。
[補足]
このログが出ていても、他のデータベースの復旧に成功した場合は”Database recovered”のログがこのあとに出力されます。
この場合、復旧に失敗したデータベースは使用できませんが、他のデータベースは使用できます。
- [ERR] Database ‘DB1' is not available
[ERR] Server is not available
-
前述のように、これらの出力があったときは一切の問い合わせを受け付けない状態になっているため、サービスの停止および再開が必要です。
- [ERR] Database 'DB1' may be corrupted
-
データベースを構成するファイルに整合性がなくなっていることを示します。
データベースが壊れている可能性が高いと考えられます。
自動復旧を試みたあとに再度この出力が出たときは、壊れていると判断すべきです。
- [ERR] Data in bad page XXXX of file YYYY
-
データベースを構成するファイルのうち、ファイルYYYYのページXXXXの内容が不正な状態を示します。
データベースが壊れている可能性が高いと考えられます。
自動復旧を試みたあとに再度この出力が出たときは、壊れていると判断すべきです。
- [ERR] Not enough space on the disk
-
ディスク容量の不足を示します。
- [ERR] Can’t allocate memory
-
メモリー確保に失敗したことを示します。
- [ERR] Unexpected exception
-
予期しない例外が発生したことを意味します。
プログラムの不具合の可能性が高いと考えられます。
多くの場合、データベースは壊れておらず、自動復旧で回復します。
Copyright (c) 2023 Ricoh Company, Ltd. All rights reserved.