Active Data Guard の検証 その2(ABR 検証編)

GW ボケやらセミナーやらで、すっかり更新が遅れてしまいました (^^;q
今回は、Automatic Block Repair(ABR)機能を確認します。

前回の blog にも書きましたが、この機能は先日参加した IOUG のセッションの中で自分が最も興味を持った機能で、データベースファイルのブロック障害が発生した場合に Standby Database 側の正常なブロックを利用してリカバリしてくれるという機能です。
メディア障害と言われるファイルレベルでの障害は意外と発生しないものですが、ブロック障害には何度も遭遇したことがあります。
これが自動で復旧してくれるなんて素敵♪

まずは、ABR が機能しないケース(Active Data Guard を動作させない)でブロック障害を発生させてみます。

【Standby】

管理リカバリモードを停止します。

SQL> alter database recover managed standby database cancel;

データベースが変更されました。

SQL> select database_role,open_mode from v$database;

DATABASE_ROLE      OPEN_MODE
------------------ ---------------------
PHYSICAL STANDBY   READ ONLY

【Primary】

ブロック障害を発生させる表(scott.emp を利用)が格納されているデータファイルID、ブロックID等を確認します。

SQL> select * from scott.emp;

 EMPNO ENAME      JOB          MGR HIREDATE    SAL  COMM  DEPTNO
------ ---------- ---------- ----- -------- ------ ----- -------
  7782 CLARK      MANAGER     7839 81-06-09   2450            10
  7499 ALLEN      SALESMAN    7698 81-02-20   1600   300      30
  7369 SMITH      CLERK       7902 80-12-17    800            20
  7844 TURNER     SALESMAN    7698 81-09-08   1500     0      30
  7902 FORD       ANALYST     7566 81-12-03   3000            20
  7698 BLAKE      MANAGER     7839 81-05-01   2850            30
  7934 MILLER     CLERK       7782 82-01-23   1300            10
  7900 JAMES      CLERK       7698 81-12-03    950            30
  7654 MARTIN     SALESMAN    7698 81-09-28   1250  1400      30
  7521 WARD       SALESMAN    7698 81-02-22   1250   500      30
  7839 KING       PRESIDENT        81-11-17   5000            10
  7566 JONES      MANAGER     7839 81-04-02   2975            20

12行が選択されました。

SQL> select segment_name,extent_id,file_id,block_id,blocks
     from dba_extents
     where segment_name = 'EMP';

SEGMENT_NAME     EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
--------------- ---------- ---------- ---------- ----------
EMP                      0          4        128          8

SQL> select file#,name from v$datafile where file#=4;

     FILE# NAME
---------- ---------------------------------------------------------------
         4 /u01/app/oracle/oradata/DG112/datafile/users01.dbf

上記の結果から次のことを確認しました。

・EMP 表は物理ファイル /u01/app/oracle/oradata/DG112/datafile/users01.dbf に格納
・block_id 128 から 8 ブロック分を利用している

次に dd コマンドを利用して物理ファイル users01.dbf の該当ブロックを壊します。

$ cd /u01/app/oracle/oradata/DG112/datafile
$ dd if=system01.dbf of=users01.dbf bs=8192 seek=128 count=8
8+0 records in
8+0 records out
65536 bytes (66 kB) copied, 0.000381 seconds, 172 MB/s

ここでは、SYSTEM 表領域のデータファイルの内容を USERS 表領域のデータファイルに書き込むことで壊しています。
dd コマンドで指定している値の意味は以下の通りです。

if -> 入力ファイル
of -> 出力ファイル(破損させるファイル)
bs -> Oracle ブロックサイズ
seek -> 書き込みを行う先頭ブロック(dba_extents で確認した block_id)
count -> seek に指定したブロックから何ブロック書き込むか(dba_extents で確認した blocks)

これで EMP 表のデータが格納されているブロックが壊れた筈です。
この状態で EMP 表を参照してみます。

SQL> select * from scott.emp;

EMPNO ENAME      JOB          MGR HIREDATE    SAL  COMM  DEPTNO
------ ---------- ---------- ----- -------- ------ ----- -------
7782 CLARK      MANAGER     7839 81-06-09   2450            10
7499 ALLEN      SALESMAN    7698 81-02-20   1600   300      30
7369 SMITH      CLERK       7902 80-12-17    800            20
7844 TURNER     SALESMAN    7698 81-09-08   1500     0      30
7902 FORD       ANALYST     7566 81-12-03   3000            20
7698 BLAKE      MANAGER     7839 81-05-01   2850            30
7934 MILLER     CLERK       7782 82-01-23   1300            10
7900 JAMES      CLERK       7698 81-12-03    950            30
7654 MARTIN     SALESMAN    7698 81-09-28   1250  1400      30
7521 WARD       SALESMAN    7698 81-02-22   1250   500      30
7839 KING       PRESIDENT        81-11-17   5000            10
7566 JONES      MANAGER     7839 81-04-02   2975            20

12行が選択されました。

おっと・・・
バッファキャッシュに残っていたので、まだ参照できました。
バッファキャッシュをクリアし、もう一度参照してみます。

SQL> alter system flush buffer_cache;

システムが変更されました。

SQL> select * from scott.emp;
select * from scott.emp
*
行1でエラーが発生しました。:
ORA-01578:
Oracleデータ・ブロックに障害が発生しました(ファイル番号4、ブロック番号131) 
ORA-01110: データファイル4:'/u01/app/oracle/oradata/DG112/datafile/users01.dbf'

はい、ちゃんと壊れてくれました ^^
では、いよいよ ABR を確認してみます。

【Standby】

管理リカバリモードを開始します。

SQL> alter database recover managed standby database
     using current logfile disconnect from session;

データベースが変更されました。

SQL> select database_role,open_mode from v$database;

DATABASE_ROLE      OPEN_MODE
------------------ ---------------------
PHYSICAL STANDBY   READ ONLY WITH APPLY

【Primary】

バッファキャッシュには、ブロック障害時の情報が残っているので、再度バッファキャッシュをクリアしてから参照します。

SQL> alter system flush buffer_cache;

システムが変更されました。

SQL> select * from scott.emp;

 EMPNO ENAME      JOB          MGR HIREDATE    SAL  COMM  DEPTNO
------ ---------- ---------- ----- -------- ------ ----- -------
  7782 CLARK      MANAGER     7839 81-06-09   2450            10
  7499 ALLEN      SALESMAN    7698 81-02-20   1600   300      30
  7369 SMITH      CLERK       7902 80-12-17    800            20
  7844 TURNER     SALESMAN    7698 81-09-08   1500     0      30
  7902 FORD       ANALYST     7566 81-12-03   3000            20
  7698 BLAKE      MANAGER     7839 81-05-01   2850            30
  7934 MILLER     CLERK       7782 82-01-23   1300            10
  7900 JAMES      CLERK       7698 81-12-03    950            30
  7654 MARTIN     SALESMAN    7698 81-09-28   1250  1400      30
  7521 WARD       SALESMAN    7698 81-02-22   1250   500      30
  7839 KING       PRESIDENT        81-11-17   5000            10
  7566 JONES      MANAGER     7839 81-04-02   2975            20

12行が選択されました。

バッチリ参照できました!!
この時のアラートログからは、
“Automatic block media recovery successful for (file# X, block# XXX)”
という出力が確認できます。

Hex dump of (file 4, block 131) in trace file /u01/app/oracle/diag/rdbms/dg112/dg112/trace/dg112_ora_6943.trc
Corrupt block relative dba: 0x01000083 (file 4, block 131)
Bad header found during buffer read
Data in bad block:
type: 30 format: 2 rdba: 0x00400003
last change scn: 0x0000.0030424f seq: 0x1 flg: 0x04
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0x424f1e01
check value in block header: 0xb0ec
computed block checksum: 0x0
Reading datafile '/u01/app/oracle/oradata/DG112/datafile/users01.dbf' for corruption at rdba: 0x01000083 (file 4, block 131)
Reread (file 4, block 131) found same corrupt data (no logical check)
Starting background process ABMR
Mon May 30 16:28:07 2011
ABMR started with pid=25, OS id=7137
Automatic block media recovery service is active.
Automatic block media recovery requested for (file# 4, block# 131)
Mon May 30 16:28:08 2011
Automatic block media recovery successful for (file# 4, block# 131)
Automatic block media recovery successful for (file# 4, block# 131)
WARNING: AutoBMR fixed mismatched on-disk single block 400003 with in-mem rdba 1000083.

うーん、素晴らしい!!
ABR の確認が出来たので、個人的にはもう満足してしまいましたが、折角 Active Data Guard の環境を作ったので他にも検証しないと・・・
次回、何しようかな。。。