Oracle+ストレージコピーでデータロストゼロ
例えば OracleのDataGuard構成を用いて遠隔地データ伝播を行なっているシステムがあり、
「メインサイト被災時のデータロストを最小限にとどめたい」
というBCP要件があったとする。
また、データファイルやREDOログファイルはストレージに格納されていて、
ストレージには独自の遠隔地データ同期機能があり、遠隔地コピー回線は光ファイバなど、
高速な回線を用いれるものとする。
ストレージ装置の遠隔地コピー機能ではファイルの論理性を担保可能であるとする。
また、Oracle DataGuardは、Sync(完全同期)オプションを利用するとOLTPへの性能劣化が
激しいため、Async(非同期)オプションしか利用できないとする。
以上前提からシステム基盤を設計するとき、
「基本的にはOracle DataGuardのAsync構成としたうえで、
ストレージの高速遠隔地コピー機能でオンラインredoログのみを同期して
データロストを最小限に抑える方法が可能ではないか?」
という、
・Oracle DataGuard+ストレージ装置の遠隔地コピー機能の抱合せ設計案
が出てくると思う。
・Primaryインスタンス=DB1
・Standbyインスタンス=DB2
・ASMインスタンスは、+ASM1, +ASM2
・ASM2の dg02 に、PrimaryのOnline REDOログがストレージ装置により同期されている
とする。
障害発生後、Standby側はいわば親を失ったインスタンスであるため、一旦Oracleインスタンスを停止する。
$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on 木 6月 21 13:40:01 2007 Copyright (c) 1982, 2005, Oracle. All rights reserved. Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options に接続されました。 SQL> ^Hshutdown immediate ORA-00600: 内部エラー・コード、引数: [2141],[1219601555],[0],[],[],[],[],[]
↑Primary側に障害発生しているため、正常終了ができないため異常終了させる。
SQL> shutdown abort ORACLEインスタンスがシャットダウンされました。 SQL> startup nomount ORACLEインスタンスが起動しました。 Total System Global Area 2332033024 bytes Fixed Size 1220604 bytes Variable Size 2113929220 bytes Database Buffers 134217728 bytes Redo Buffers 82665472 bytes
nomountで起動したのち、standbyデータベースとして必要なREDO適用を行う(ロールフォワード)。
SQL> alter database mount standby database;
データベースが変更されました。
SQL> recover managed database disconnect;
メディア・リカバリが完了しました。
上記は、Standbyデータベースとして取りこぼしているREDOログを全て適用する意味がある。
この後、一度DBインスタンスを停止したうえで、
ASMインスタンスに接続する。
$ export ORACLE_SID=+ASM2 $ sqlplus / as sysdba SQL> alter disc group dg02 mount; -- 死んだPrimaryから同期されていたオンラインREDOログを格納する -- dg02 をマウントする。 ディスク・グループが変更されました。 SQL> exit
しかし、このままだとDBインスタンスを起動させることができない。
Standby側はStandby用の制御ファイルをもとに起動しているからだ。
SwitchOverの場合は制御ファイルの入れ替えをOracleが保証してくれるが、FailOverの場合は
それができない。
また安易にFailOverすると、ストレージ装置に置かれた最新オンラインREDOの適用が無理で、
データロストが発生してしまう…。
ここで大変悩んだのであるが…。
この方式で起動を行うためには、制御ファイル再作成SQLを特別に用意しておく必要があることに
今日気づいた。
controlファイルのバックアップを使って作成しておいて、インスタンスを起動させる。
※コントロールファイル再作成SQLの例(recreate_ctl.sql)
STARTUP NOMOUNT CREATE CONTROLFILE SET DATABASE "DB1" RESETLOGS FORCE LOGGING ARCHIVELOG MAXLOGFILES 48 MAXLOGMEMBERS 3 MAXDATAFILES 300 MAXINSTANCES 1 MAXLOGHISTORY 1168 LOGFILE GROUP 1 '+DG02/db1/onlinelog/group_1.259.625320425' SIZE 512M, GROUP 2 '+DG02/db1/onlinelog/group_2.260.625320429' SIZE 512M, GROUP 3 '+DG02/db1/onlinelog/group_3.262.625320431' SIZE 512M DATAFILE '+DG01/db1/datafile/system.256.625067395', '+DG01/db1/datafile/sysaux.257.625067415', '+DG01/db1/datafile/undotblsp.258.625067543', '+DG01/db1/datafile/usrdef.260.625067601', '+DG01/db1/datafile/user_tbl.261.625068345', '+DG01/db1/datafile/user_indx.262.625068469' CHARACTER SET JA16EUCTILDE ; ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS; ALTER SYSTEM ARCHIVE LOG ALL; ALTER DATABASE OPEN RESETLOGS; ALTER TABLESPACE TEMP_USER ADD TEMPFILE '+DG01/db1/tempfile/temp_user.259.625067601' SIZE 10240M REUSE AUTOEXTEND OFF;
DATAFILEは、Oracle DataGuard ASYNCにより差分適用されたもの。
LOGFILE の DG02は、ストレージ装置の遠隔地コピーにより高速コピーされたもの。
この2つで極力データロストを最小化するのである!
OracleインスタンスDB2に接続して、制御ファイルを再作成する。
#- 一旦、スタンバイ用制御ファイルを削除
$ rm /oracle/tmp/standby.ctl
$ export ORACLE_SID=DB2
$ sqlplus / as sysdba
SQL> @recreate_ctl.sql
制御ファイルが作成されました。
正常に作成された!!
続いて、最新のオンラインREDOログを適用してロールフォワードする。
ORA-00279: ??44023587(06/21/2007 13:54:13???)??????1????? ORA-00289: ????????????:+DG01 ORA-00280: ??44023587(????1)?????38??????? 14:07:50 ログの指定: {<RET>=suggested | filename | AUTO | CANCEL} +DG02/db1/onlinelog/group_2.265.625769361 ログが適用されました。 メディア・リカバリが完了しました。
障害発生寸前までの論理的に保証されたオンラインREDOログが適用された!!
これだと伝送遅延60ms(東京⇔大阪の場合)くらいのデータロストしか発生しない。
いよいよインスタンス起動。
SQL> alter database open resetlogs; データベースが変更されました。 SQL> connect test/password; SQL> select * from test20070621; PK ---------- 1 2
(擬似)障害発生直前のデータ(ストレージのREDO内にしかない)が伝播されていることを確認。
ううむ、KROWNなどにも書かれていない裏テクだが、
DataGuard機能を用いないクローンデータベース作成手法の応用と呼べるだろう。
しかし、この手法を本家Oracle社がサポートしてくれるか次第だな。。。採用可否は。