忘れかけのIT備忘録

今まで学んできた知識や小技、なるほど!と思ったことをメモするブログです。

RACのインスタンスリカバリ

今回はRACインスタンスリカバリについて調査しました。

シングルインスタンスRACインスタンスリカバリの仕組みは一緒です。
シングルインスタンスの場合、インスタンスリカバリのみですが、RACの場合、インスタンスリカバリとクラッシュリカバリがあります。
RACインスタンスリカバリとクラッシュリカバリはインスタンス障害パターンによってリカバリ方法とリカバリタイミングが異なります。

RACインスタンスリカバリ
【発生パターン】一部のインスタンス破損
リカバリタイミング】インスタンス障害発生後、いずれかの残存インスタンスによって実行される

RACのクラッシュリカバリ
【発生パターン】全インスタンス破損
リカバリタイミング】インスタンス障害発生後、再起動したいずれかのインスタンスによって実行される

■検証パターン
①片インスタンスだけ異常停止
②両インスタンス異常停止

■検証
①片インスタンスだけ異常停止
ノード1のインスタンスを異常停止(abort)後、各ノードのDBアラートログを確認します

【検証手順】
1. ノード1のインスタンスを異常停止
2. 各ノードでDBアラートログ確認

【検証結果】
インスタンスリカバリしたインスタンスのDBアラートログにインスタンスリカバリの内容が出力されていました

【作業ログ】
1. ノード1のインスタンスを異常停止
#ノード1
[oracle@node1 ~]$ srvctl stop instance -db orcl -i orcl1 -o abort

2. 各ノードでDBアラートログ確認
#ノード1
[oracle@node1 ~]# cat /u01/app/oracle/diag/rdbms/orcl/orcl1/trace/alert_orcl1.log 
インスタンスリカバリの内容は出力なし

#ノード2
[oracle@node2 ~]# cat /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/alert_orcl2.log 
Beginning instance recovery of 1 threads
 parallel recovery started with 3 processes
Mon Oct 10 14:38:07 2022
 Submitted all GCS remote-cache requests
 Fix write in gcs resources
Mon Oct 10 14:38:07 2022
Started redo scan
Mon Oct 10 14:38:07 2022
Reconfiguration complete (total time 0.1 secs)
Mon Oct 10 14:38:07 2022
Completed redo scan
 read 629 KB redo, 214 data blocks need recovery
* validated domain 0, flags = 0x0
Mon Oct 10 14:38:07 2022
Started redo application at
 Thread 1: logseq 13, block 3
Mon Oct 10 14:38:07 2022
Recovery of Online Redo Log: Thread 1 Group 2 Seq 13 Reading mem 0
  Mem# 0: +DATA/ORCL/ONLINELOG/group_2.296.1116201873
  Mem# 1: +FRA/ORCL/ONLINELOG/group_2.265.1116201873
Mon Oct 10 14:38:07 2022
Completed redo application of 0.50MB
Mon Oct 10 14:38:08 2022
Completed instance recovery at
 Thread 1: logseq 13, block 1262, scn 6702312
 144 data blocks read, 217 data blocks written, 629 redo k-bytes read

②両インスタンス異常停止
両ノードのインスタンスを異常停止(abort)後、各ノードのDBアラートログを確認します

【検証手順】
1. 両ノードのインスタンスを異常停止
2. 各ノードでDBアラートログ確認

【検証結果】
クラッシュリカバリしたインスタンスのDBアラートログにクラッシュリカバリの内容が出力されていました

【作業ログ】
1. 両ノードのインスタンスを異常停止

#ノード1
[oracle@node1 ~]$ srvctl stop instance -db orcl -i orcl1 -o abort

#ノード2
[oracle@node2 ~]$ srvctl stop instance -db orcl -i orcl2 -o abort

2. 各ノードでDBアラートログ確認
#ノード1
[oracle@node1 ~]# cat /u01/app/oracle/diag/rdbms/orcl/orcl1/trace/alert_orcl1.log 
Beginning crash recovery of 1 threads
 parallel recovery started with 3 processes
Mon Oct 10 14:52:02 2022
Started redo scan
Mon Oct 10 14:52:02 2022
Completed redo scan
 read 3097 KB redo, 602 data blocks need recovery
Mon Oct 10 14:52:02 2022
Started redo application at
 Thread 1: logseq 24, block 1761
Mon Oct 10 14:52:02 2022
Recovery of Online Redo Log: Thread 1 Group 2 Seq 24 Reading mem 0
  Mem# 0: +DATA/ORCL/ONLINELOG/group_2.283.1116113957
  Mem# 1: +FRA/ORCL/ONLINELOG/group_2.258.1116113957
Mon Oct 10 14:52:02 2022
Completed redo application of 2.22MB
Mon Oct 10 14:52:02 2022
Completed crash recovery at
 Thread 1: logseq 24, block 7955, scn 6906663
 602 data blocks read, 602 data blocks written, 3097 redo k-bytes read

#ノード2
[oracle@node2 ~]# cat /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/alert_orcl2.log 
★クラッシュリカバリの内容は出力なし

リカバリの解説に戻ります。
シングルインスタンスインスタンスリカバリRACのクラッシュリカバリは同じ仕組みです。(データブロックのみリカバリ)
RACインスタンスリカバリはグローバルリソースのリカバリによってGCSとGESの再マスタリング後、データブロックがリカバリされます。
RACインスタンスリカバリを解説する前にシングルインスタンスインスタンスリカバリを復習してみます。

インスタンスリカバリの発生条件
インスタンスが異常終了した場合、インスタンス再起動時、REDOログファイルを読込み、データファイルに書き込まれていないデータブロックがある(厳密にはデータファイルヘッダーのSCNと制御ファイルのSCNに差分がある)と発生します。
チェックポイントから障害発生直前までの間に生成されたREDOデータがデータファイルに書き込まれていない場合、インスタンスリカバリが発生します。

(例) 「A」を「B」にUPDATE中にインスタンス障害発生

インスタンスリカバリの仕組み
インスタンス再起動した際、最初にv$datafileビューのLAST_CHANGE#列を見てインスタンスの停止状況を把握します。
インスタンスが異常終了した場合、v$databaseビューのCHECKPOINT_CHANGE#列(前回のチェックポイント時点のSCN)をベースにインスタンスリカバリします。

【補足】
チェックポイント時、該当時点のSCNが制御ファイルと該当データファイルに書き込まれます。(チェックポイントSCN)
インスタンスリカバリは、チェックポイントSCNによってリカバリの開始地点が判断されます。
インスタンスを正常停止した場合、停止前の最後のSCNがv$datafileビューのLAST_CHANGE#列に書き込まれます。
ただし、インスタンスを異常停止した場合、LAST_CHANGE#列がNULLになります。
つまり、v$datafileビューのLAST_CHANGE#列を見ることでインスタンスの正常停止/異常停止が分かります。

(例) チェックポイントSCNが書き込まれるタイミング

次にRACインスタンスリカバリを解説します。

①障害検出
インスタンス障害の場合、残存インスタンスで障害が検出される
ノード障害の場合、ノード間のメンバーシップの修正が必要なため、CSSDによるクラスタ再構成も実行される

②リソース再構成
LMONがGRD内のリソースマスター情報を再構築する(GCSとGESの再マスタリング)
再マスタリング開始後はすべてのクライアント処理が一時停止する
※一時停止のため、セッション切断ではない

リカバリ対象ブロック検出
リカバリが必要なデータブロックをSMONが識別する(1st pass log read)
REDOログファイルを読込み、データファイルに書き込まれていないデータブロックを検出する

リカバリ対象ブロック取得
リカバリが必要なブロックをSMONプロセスが取得する
残存インスタンスにパストイメージがある場合、パストイメージを使用してリカバリする
残存インスタンスにパストイメージがない場合、データファイルからデータブロックを読込んでリカバリする
リカバリ対象となるデータブロック取得が完了すると一時停止していたクライアント処理は再開され、他のデータブロックは使用可能になる

⑤ロールフォワード
SMONプロセスによってREDOグレコードがデータブロックに適用される(2nd pass log read)
障害が発生したスレッドのREDOログファイルが再度読込まれる
ロールフォワードが完了したデータブロックは使用可能になる

ロールバック
SMONプロセスまたはデータブロックにアクセスしたサーバープロセスによって、コミットされていないトランザクションロールバック(UNDOデータ適用)される
すべてのロールバックが完了するとインスタンスリカバリ完了となる

RACインスタンスリカバリは残存インスタンスにパストイメージがある場合、パストイメージを使ってリカバリします。
パストイメージは、キャッシュ・フュージョンで最新バージョンのブロックをリクエスターに送信した際、リソースホルダーのブロックの状態です。
インスタンスリカバリに備えて保持される使用済みバッファです。
最新バージョンを持つインスタンスが破損した場合、パストイメージを開始地点にすれば高速にリカバリできます。
なお、パストイメージの破棄タイミングは最新バージョンのデータブロックがデータファイルへ書き込まれた時です。

■参考資料
オラクルマスター教科書 Oracle Expert RAC 11gR2