しばちょう先生の試して納得!DBAへの道 indexページ▶▶

しばちょう先生による技術解説セミナー。
動画、資料を公開中です。

>> 最新のセミナーをチェック

しばちょう先生の試して納得!DBAへの道
第22回 Recovery Managerによる高速差分増分バックアップ

みなさん、こんにちは。 “しばちょう”こと柴田長(しばた つかさ)です。先月の記事では「暑い~」と書いていましたが、わずか一ヵ月でだいぶ涼しくなりましたね。と言う事で(?)、今年もOracle DBA & Developer Day 2013をやります。私も一つセッション枠を頂いてMAAのデータ保護について講演予定ですので、是非ともエントリーして下さいね。

http://www.oracle.co.jp/events/dbadev2013/

さて、前回から引き続き、今回もRecovery Manager(RMAN)をご紹介していきます。前回はRMANによる差分増分バックアップの基礎でしたが、今回はRMANが"必要最低限の時間とH/Wリソースの消費で取得することができる"ことを体験して頂きたいと考えていて、RMANバックアップを高速化する仕組みであるブロック・チェンジ・トラッキング機能をご紹介します。

以下の演習をOracle Database 11g Release 2 Enterprise Editionのデータベースで試してみてください。可能であれば前回の演習で使用した環境をご利用頂けると、ブロック・チェンジ・トラッキング機能の効果を正確に体感できると思います。


1. 前回と全く同じ環境を準備します。(前回検証した環境であれば、本演習1は実施する必要はありません) RMANで非一貫性バックアップを取得するターゲット・データベースに対し、アーカイブ・ログ・モード、および高速リカバリ領域を設定し、1GBの表領域"TBS21"を作成します。その表領域上に512MBの表"TAB21"(第一カラムが主キーでNUMBER型の列名COL1、第二カラムがCHAR(1000)型の列名COL2)を作成して下さい。

$ sqlplus /nolog
SQL> -- 設定
connect / as sysdba
select STATUS from V$INSTANCE ;

STATUS
------------
OPEN

alter database archivelog ;
alter system set DB_RECOVERY_FILE_DEST = '+FRA' ;
alter system set DB_RECOVERY_FILE_DEST_SIZE = 10g ;

SQL> -- 確認
archive log list

SQL> データベース・ログ・モード     アーカイブ・モード
自動アーカイブ                 有効
アーカイブ先                    USE_DB_RECOVERY_FILE_DEST
最も古いオンライン・ログ順序   2
アーカイブする次のログ順序    4
現行のログ順序               4

show parameter db_recovery

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string      +FRA
db_recovery_file_dest_size           big integer 10G

SQL> -- TBS21表領域と、この表領域をデフォルト表領域とするTRYユーザーの作成
create tablespace TBS21 datafile '+DATA(DATAFILE)' size 1g uniform size 4m ;
create user TRY identified by TRY default tablespace TBS21 ;
grant connect, resource, dba to TRY ;

SQL> -- TAB21表の作成とデータ・ローディング
connect TRY/TRY
create table TAB21 (COL1 number NOT NULL, COL2 char(1000)) pctfree 10 ;
insert /*+append */ into TAB21 select LEVEL, 'hoge'||to_char(LEVEL) 
                                  from DUAL connect by LEVEL <= 7 * 128 * 508 ;
commit;
create unique index IDX_TBL21_COL1 on TAB21(COL1) ;
alter table TAB21 add primary key (COL1) using index ;

SQL> -- TRYスキーマ内のセグメント・サイズを確認
set linesize 150
col SEGMENT_NAME for a24
select SEGMENT_TYPE, SEGMENT_NAME, sum(BYTES)/1024/1024
  from USER_SEGMENTS
 group by rollup(SEGMENT_TYPE, SEGMENT_NAME) ;

SEGMENT_TYPE       SEGMENT_NAME             SUM(BYTES)/1024/1024
------------------ ------------------------ --------------------
INDEX              IDX_TBL21_COL1                              8
INDEX                                                          8
TABLE              TAB21                                     512
TABLE                                                        512
                                                             520

はい、完全に前回の演習からのコピペなので問題無いと思います。復習を希望される方は前回の演習1と2の解説部分を参照してみてください。


2. RMANを使用して、全てデータファイルのレベル0のイメージ・コピー・バックアップを取得してください。

$ export NLS_DATE_FORMAT="YYYY/MM/DD HH24:MI:SS";
$ rman target /
ターゲット・データベース: ORCL (データベースID=1287039091)に接続されました
RMAN>
shutdown immediate ; -- 検証のため実行。本来は不要
startup ;

BACKUP
  INCREMENTAL LEVEL 1
  FOR RECOVER OF COPY WITH TAG 'incr_update'
  DATABASE ;

backupが開始されました(開始時間: 2013/09/24 19:40:14)
リカバリ・カタログのかわりにターゲット・データベース制御ファイルを使用しています
チャネル: ORA_DISK_1が割り当てられました
チャネルORA_DISK_1: SID=39 デバイス・タイプ=DISK
データファイル1の親バックアップまたはコピーが見つかりません
データファイル2の親バックアップまたはコピーが見つかりません
データファイル3の親バックアップまたはコピーが見つかりません
データファイル5の親バックアップまたはコピーが見つかりません
データファイル4の親バックアップまたはコピーが見つかりません
チャネルORA_DISK_1: データファイルのコピーを開始しています
入力データファイル・ファイル番号=00001 名前=+DATA/orcl/datafile/system.258.820462945
出力ファイル名=+FRA/orcl/datafile/system.269.827005217 タグ=INCR_UPDATE レコードID=86 スタンプ
=827005233
チャネルORA_DISK_1: データファイルのコピーが終了しました。経過時間: 00:00:25
チャネルORA_DISK_1: データファイルのコピーを開始しています
入力データファイル・ファイル番号=00002 名前=+DATA/orcl/datafile/sysaux.259.820462945
出力ファイル名=+FRA/orcl/datafile/sysaux.279.827005241 タグ=INCR_UPDATE レコードID=87 スタンプ
=827005257
チャネルORA_DISK_1: データファイルのコピーが終了しました。経過時間: 00:00:25
チャネルORA_DISK_1: データファイルのコピーを開始しています
入力データファイル・ファイル番号=00003 名前=+DATA/orcl/datafile/undotbs1.267.820462947
出力ファイル名=+FRA/orcl/datafile/undotbs1.265.827005267 タグ=INCR_UPDATE レコードID=88 スタンプ
=827005282
チャネルORA_DISK_1: データファイルのコピーが終了しました。経過時間: 00:00:25
チャネルORA_DISK_1: データファイルのコピーを開始しています
入力データファイル・ファイル番号=00005 名前=+DATA/orcl/datafile/tbs21.257.824073659
出力ファイル名=+FRA/orcl/datafile/tbs21.313.827005293 タグ=INCR_UPDATE レコードID=89 スタンプ
=827005307
チャネルORA_DISK_1: データファイルのコピーが終了しました。経過時間: 00:00:25
チャネルORA_DISK_1: データファイルのコピーを開始しています
入力データファイル・ファイル番号=00004 名前=+DATA/orcl/datafile/users.264.820462947
出力ファイル名=+FRA/orcl/datafile/users.291.827005317 タグ=INCR_UPDATE レコードID=90 スタンプ
=827005319
チャネルORA_DISK_1: データファイルのコピーが終了しました。経過時間: 00:00:03
backupが完了しました(完了時間: 2013/09/24 19:42:00)

Control File and SPFILE Autobackupが開始されました(開始時間: 2013/09/24 19:42:00)
ピース・ハンドル=+FRA/orcl/autobackup/2013_09_24/s_827005321.280.827005321 コメント=NONE
Control File and SPFILE Autobackupが完了しました(完了時間: 2013/09/24 19:42:04)

はい、この演習も前回の復習ですね。差分増分バックアップの起点ともなるべきLevel0のイメージ・コピー・バックアップを取得しています。このバックアップ・コマンドはLevel0とLevel1の各バックアップで共通使用できる為に通常運用ジョブに組み込む際に条件分岐が不要となりますから、意外と重宝する部分だと思います。

また、前回はご紹介していない部分を一点だけ説明しておくと、「RMANを起動する前に、NLS_DATE_FORMAT環境変数を設定しておくと便利ですよ」という、おそらく意外と知られていないワザです。RMANが出力する日時はデフォルトで年月日までしか表示されない為、バックアップにどの程度の時間を要したのかを把握するには少々面倒なのですが、今回のワザを施しておけばスマートに時分秒まで出力させることができるので、RMANが大幅に進化したような錯覚を受けるでしょう。。。

ちなみに、上記の回答例では私のデータベース全体のイメージ・コピー・バックアップに1分46秒(開始時間: 2013/09/24 19:40:14から完了時間: 2013/09/24 19:42:00)を費やしていることが一瞬で把握できますね!


そして、これまた復習となりますがレベル0のイメージ・コピー・バックアップが、データファイルと同じサイズであること、さらにはレベル0のバックアップ取得時にRMANがどの程度のI/Oを投げたのかを確認しておきましょう。

$ sqlplus /nolog
connect / as sysdba
set linesize 150 pages 5000

SQL> -- レベル0バックアップとデータファイルのサイズ比較
col DATAFILE_NAME for a48
col BKUPFILE_NAME for a48
select A.FILE#, 
       A.NAME as "DATAFILE_NAME", A.BYTES/1024/1024        as "DATAFILE_SIZE(MB)",
       B.NAME as "BKUPFILE_NAME", B.OUTPUT_BYTES/1024/1024 as "BKUPFILE_SIZE(MB)"
  from V$DATAFILE "A", V$BACKUP_COPY_DETAILS "B"
 where A.FILE# = B.FILE#
 order by 1 ;

FILE# DATAFILE_NAME                               DF_SIZE(MB) BKUPFILE_NAME                              BKUP_SIZE(MB)
----- ------------------------------------------- ----------- ------------------------------------------ -------------
    1 +DATA/orcl/datafile/system.258.820462945           1024 +FRA/orcl/datafile/system.269.827005217       1024.00781
    2 +DATA/orcl/datafile/sysaux.259.820462945           1024 +FRA/orcl/datafile/sysaux.279.827005241       1024.00781
    3 +DATA/orcl/datafile/undotbs1.267.820462947         1024 +FRA/orcl/datafile/undotbs1.265.827005267     1024.00781
    4 +DATA/orcl/datafile/users.264.820462947           23.75 +FRA/orcl/datafile/users.291.827005317        23.7578125
    5 +DATA/orcl/datafile/tbs21.257.824073659            1024 +FRA/orcl/datafile/tbs21.313.827005293        1024.00781


SQL> -- レベル0バックアップ取得時のI/O量を確認
select FILETYPE_NAME, SMALL_READ_MEGABYTES, LARGE_READ_MEGABYTES, 
        SMALL_WRITE_MEGABYTES, LARGE_WRITE_MEGABYTES
  from V$IOSTAT_FUNCTION_DETAIL
 where FUNCTION_NAME = 'RMAN' ;

FILETYPE_NAME                SMALL_READ_MEGABYTES LARGE_READ_MEGABYTES SMALL_WRITE_MEGABYTES LARGE_WRITE_MEGABYTES
---------------------------- -------------------- -------------------- --------------------- ---------------------
Control File                                   10                   19                     3                     9
Data File                                       0                 4120                     0                     0
Other                                           0                    0                     0                     0
Data File Copy                                  0                    0                     0                  4120
Other                                           0                    0                     0                     0
Other                                           0                    0                     0                    10

上記回答例の一つ目はDF_SIZE(MB)がデータファイルのサイズであり、BKUP_SIZE(MB)がそれらのレベル0バックアップのサイズを示しています。端数が少し気になりますが、ほぼ同じサイズであることが確認できますね。

よって、二つ目のSQL(V$IOSTAT_FUNCTION_DETAILビュー)で確認している通り、データファイルの読み込み量は4120MB(Data FileのLARGE_READ_MEGABYTESより)であり、それをそのままバックアップとして書き込んで(Data File CopyのLARGE_WRITE_MEGABYTES)いますね。

つまり、Level0のイメージ・コピー・バックアップは、データファイルのブロックを全部読んで、それらをイメージ・コピー・バックアップとして全部書き込んでいると言う事ですね。

初回のバックアップであれば我慢できますが、毎日このようなバックアップは非効率ですよね。と言うもの、データファイルのブロックは、毎日全部更新されるでしょうか?データベースの特性にも寄りけりですが、一般的には"されません"よね。新規レコードの挿入や、一部の既存レコードが更や/削除されますが、ほとんどのレコードは参照しかされません。よって、ある一日を考えた場合、データファイル全体と比較すれば更新されているブロックは数~10%程度が私の経験値です。

そして、この更新されたブロックが差分(増分)であり、前回ご紹介したRMANの差分増分バックアップは、この差分(増分)ブロックだけをレベル1バックアップとして取得する方法ですね。

前回の記事で説明が不足していたかもと思い、このタイミングで改めて解説してみました。申し訳ないです。。。


3. 増分バックアップを高速化することを目的に、ブロック・チェンジ・トラッキングを有効にして下さい。。

$ sqlplus / as sysdba
SQL> -- 現時点の設定の確認
col FILENAME for a48
select * from V$BLOCK_CHANGE_TRACKING ;

STATUS     FILENAME                                              BYTES
---------- ------------------------------------------------ ----------
DISABLE


SQL> -- 有効化
alter database enable BLOCK CHANGE TRACKING using file '+FRA(CHANGETRACKING)' reuse ;


SQL> -- 設定の確認
select * from V$BLOCK_CHANGE_TRACKING ;

STATUS     FILENAME                                              BYTES
---------- ------------------------------------------------ ----------
ENABLED    +FRA/orcl/changetracking/ctf.282.827005385         11599872

SQL> -- オマジナイ
alter system checkpoint ;
alter system switch logfile ;

さて、今回の主題であるブロック・チェンジ・トラッキングを有効化しています。有効化する方法は、SQL文を一つ実行するだけでOKです。そして、有効化されているか否かの確認は、V$BLOCK_CHANGE_TRACKINGビューという非常に覚えやすいビューを参照すれば良いだけです。

チェンジ・トラッキング・ファイルはバイナリ・ファイルであり、REDOレコードの生成時に変更されたブロックをビットマップで記録します。サイズはデータベースのサイズ及びRedoのスレッドの数に比例しますが、データベースの更新頻度とは無関係です。ブロック・チェンジ・トラッキングを有効にした場合、RMANはチェンジ・トラッキング・ファイルを使用して、変更されたブロックを識別できるようになります。これにより、データファイル内の全てのブロックを読み取る必要が無くなり、従来の増分バックアップよりも高速なバックアップを実現することが出来るのです。

本当か?と言う事で、早速試してみたいー。という気持ちなれたらシメタものです。その好奇心が自己のスキルを向上させる糧となるのですから。


4. 差分データを生成する為、TAB21表内の150MB分(TBS21表領域の約15%)のブロックをUPDATE文にて更新してください。

$ sqlplus /nolog
SQL> -- UPDATE対象量の確認
connect TRY/TRY
select count(distinct(dbms_rowid.rowid_block_number(ROWID))) * 8 / 1024 as "UPDATED_MB"
  from TAB21
 where COL1 < 7 * 128 * 150 ;

UPDATED_MB
----------
       150

SQL> -- 150MB分を更新
update TAB21 set COL2='updated' where COL1 < 7 * 128 * 150 ;
commit ; 

前回の復習ばかりでスイマセン。とは言え、更新量を制御する便利なスキルですから、是非復習しておいてくださいね。


5. レベル1の差分増分バックアップを取得して下さい。(ブロック・チェンジ・トラッキングを有効化した後の1回目)

$ export NLS_DATE_FORMAT="YYYY/MM/DD HH24:MI:SS";
$ rman target /
ターゲット・データベース: ORCL (データベースID=1287039091)に接続されました
RMAN>
shutdown immediate ;  -- 検証のため実行。本来は不要
startup ;

BACKUP
  INCREMENTAL LEVEL 1
  FOR RECOVER OF COPY WITH TAG 'incr_update'
  DATABASE ;

backupが開始されました(開始時間: 2013/09/24 19:44:41)
リカバリ・カタログのかわりにターゲット・データベース制御ファイルを使用しています
チャネル: ORA_DISK_1が割り当てられました
チャネルORA_DISK_1: SID=44 デバイス・タイプ=DISK
チャネルORA_DISK_1: 増分レベル1のデータファイル・バックアップ・セットを開始しています
チャネルORA_DISK_1: バックアップ・セットにデータファイルを指定しています
入力データファイル・ファイル番号=00001 名前=+DATA/orcl/datafile/system.258.820462945
入力データファイル・ファイル番号=00002 名前=+DATA/orcl/datafile/sysaux.259.820462945
入力データファイル・ファイル番号=00003 名前=+DATA/orcl/datafile/undotbs1.267.820462947
入力データファイル・ファイル番号=00005 名前=+DATA/orcl/datafile/tbs21.257.824073659
入力データファイル・ファイル番号=00004 名前=+DATA/orcl/datafile/users.264.820462947
チャネルORA_DISK_1: ピース1(2013/09/24 19:44:43)を起動します
チャネルORA_DISK_1: ピース1(2013/09/24 19:45:28)が完了しました
ピース・ハンドル=+FRA/orcl/backupset/2013_09_24/nnndn1_incr_update_0.294.827005483 タグ
=INCR_UPDATE コメント=NONE
チャネルORA_DISK_1: バックアップ・セットが完了しました。経過時間: 00:00:45
backupが完了しました(完了時間: 2013/09/24 19:45:28)

Control File and SPFILE Autobackupが開始されました(開始時間: 2013/09/24 19:45:28)
ピース・ハンドル=+FRA/orcl/autobackup/2013_09_24/s_827005528.312.827005529 コメント=NONE
Control File and SPFILE Autobackupが完了しました(完了時間: 2013/09/24 19:45:31)

上記は、演習3でブロック・チェンジ・トラッキング機能を有効化し、演習4で約150MBの差分データを生成した後のLevel1増分バックアップを実行した結果です。

増分バックアップですからイメージ・コピー形式ではなく、バックアップ・セット形式でバックアップが保持されますから、下から6行目当たりの出力「チャネルORA_DISK_1: バックアップ・セットが完了しました。経過時間: 00:00:45」より、45秒間で全データファイルのLevel1増分バックアップが取得出来たことになります。この時間は確かに、データファイルをそのままコピーするLevel0のイメージ・コピー・バックアップを取得した時間(1分46秒)の半分以下まで短縮されていますが、ブロック・チェンジ・トラッキング機能の効果なのでしょうか?


と言う事で、この演習5で実行したLevel1増分バックアップにおいて作成されたバックアップのサイズと、チェンジ・トラッキング・ファイルが使用されたか否かを確認してみます。

$ sqlplus /nolog
SQL> connect / as sysdba
set linesize 150 pages 5000
alter session set NLS_DATE_FORMAT='YYYY/MM/DD HH24:MI:SS' ;

SQL> -- レベル1のバックアップのサイズを確認
select FILE#, INCREMENTAL_LEVEL, COMPLETION_TIME, BLOCK_SIZE, DATAFILE_BLOCKS, 
       BLOCKS, BLOCKS_READ, USED_CHANGE_TRACKING
  from V$BACKUP_DATAFILE
 where INCREMENTAL_LEVEL > 0
ORDER BY FILE#;

     FILE# INCREMENTAL_LEVEL COMPLETION_TIME     BLOCK_SIZE DATAFILE_BLOCKS     BLOCKS BLOCKS_READ USE
---------- ----------------- ------------------- ---------- --------------- ---------- ----------- ---
         1                 1 2013/09/24 19:45:19       8192          131072         28      131072 NO
         2                 1 2013/09/24 19:45:19       8192          131072         22      131072 NO
         3                 1 2013/09/24 19:45:19       8192          131072      21150      131072 NO
         4                 1 2013/09/24 19:44:45       8192            3040          1        3040 NO
         5                 1 2013/09/24 19:45:19       8192          131072      19202      131072 NO
         

SQL> -- レベル1バックアップ取得時のI/O量を確認
select FILETYPE_NAME, SMALL_READ_MEGABYTES, LARGE_READ_MEGABYTES, 
SMALL_WRITE_MEGABYTES, LARGE_WRITE_MEGABYTES
  from V$IOSTAT_FUNCTION_DETAIL
 where FUNCTION_NAME = 'RMAN' ;

FILETYPE_NAME                SMALL_READ_MEGABYTES LARGE_READ_MEGABYTES SMALL_WRITE_MEGABYTES LARGE_WRITE_MEGABYTES
---------------------------- -------------------- -------------------- --------------------- ---------------------
Control File                                    5                   19                     2                     9
Data File                                       0                 4120                     0                     0
Other                                           0                    0                     0                     0
Data File Incremental Backup                    0                    0                     0                   316
Other                                           0                    0                     0                     0
Other                                           0                    2                     0                     0
Other                                           0                    0                     0                    10

まず、一つ目のSQL(V$BACKUP_DATAFILE)からは、各データファイルのFILE番号に対応するLevel1バックアップの情報を確認することが出来ます。

例えば、150MBの差分データを生成させたFILE#5のLevel1バックアップは、19:45:19に作成され(=COMPLETION_TIME列)、元のデータファイルのブロック数が131,072個(=DATAFILE_BLOCKS列)にも関わらず、Level1バックアップのブロック数は19,202個(=BLOCKS)であることが確認出来ます。BLOCK_SIZE=8192Bytesなので、19,202個 = 約150MBですから、Level1バックアップは見事に差分データだけで構成されていると言えますね。

ただし、このLevel1バックアップを作成する為に元のデータファイルから読み込んだブロック数(BLOCKS_READ列)は131,072個であり、これは元のデータファイルのブロック数と一致するので、どうやらデータファイルのブロックを全部読み込んだのではないか?と言う疑惑が出てきますね。これは演習3の解説部でブロック・チェンジ・トラッキング機能を説明した「データファイル内の全てのブロックを読み取る必要が無くなり」と言う記述に合致しません。そこで登場するのが「USED_CHANGE_TRACKING列」であり、各バックアップを作成する際にチェンジ・トラッキング・ファイルを使用したか否かを「YES or NO」で確認することが出来るのです。非常に便利な列なので、絶対に覚えておいてくださいね。そして残念ながら、今回のLevel1増分バックアップは「NO」と表示されているので、チェンジ・トラッキング・ファイルを使用していないことになります。また、2つ目のSQL(V$IOSTAT_FUNCTION_DETAILビュー)の実行において、元のデータファイルの読み込み量は4120MBにも関わらず、差分バックアップとしての書込み量(Data File Incremental BackupのLARGE_WRITE_MEGABYTES)は316MBとなっていることからも同様の現象を解説することが出来ます。つまり、1分46秒から45秒へバックアップ時間が短縮した効果は、従来からある(前回の記事で体験して頂いた)増分バックアップそのものの効果となります。

(補足:ここでのバックアップ時間はあくまで私の検証環境での数字であり、理解を補助する目的の為に掲載させて頂いています。。実行する環境や設定によって効果は異なりますのでご注意ください)


頭の中が混乱状態になりそうですが、注目すべき点は「ブロック・チェンジ・トラッキング機能を有効化したにも関わらず、チェンジ・トラッキング・ファイルを使用した高速な増分バックアップになっていない?」という事です。この謎については次の演習6で解説させて頂きます。


6. 同じ差分データを生成し、再度レベル1の差分増分バックアップを取得して下さい。(ブロック・チェンジ・トラッキングを有効化した後の2回目)

$ sqlplus /nolog
connect TRY/TRY
SQL> -- 150MB分を更新
update TAB21 set COL2='updated' where COL1 < 7 * 128 * 150 ;
commit ;


$ export NLS_DATE_FORMAT="YYYY/MM/DD HH24:MI:SS";
$ rman target /
ターゲット・データベース: ORCL (データベースID=1287039091)に接続されました
RMAN>
shutdown immediate ;  -- 検証のため実行。本来は不要
startup ;

BACKUP
  INCREMENTAL LEVEL 1
  FOR RECOVER OF COPY WITH TAG 'incr_update'
  DATABASE ;

backupが開始されました(開始時間: 2013/09/24 19:47:50)
リカバリ・カタログのかわりにターゲット・データベース制御ファイルを使用しています
チャネル: ORA_DISK_1が割り当てられました
チャネルORA_DISK_1: SID=46 デバイス・タイプ=DISK
チャネルORA_DISK_1: 増分レベル1のデータファイル・バックアップ・セットを開始しています
チャネルORA_DISK_1: バックアップ・セットにデータファイルを指定しています
入力データファイル・ファイル番号=00001 名前=+DATA/orcl/datafile/system.258.820462945
入力データファイル・ファイル番号=00002 名前=+DATA/orcl/datafile/sysaux.259.820462945
入力データファイル・ファイル番号=00003 名前=+DATA/orcl/datafile/undotbs1.267.820462947
入力データファイル・ファイル番号=00005 名前=+DATA/orcl/datafile/tbs21.257.824073659
入力データファイル・ファイル番号=00004 名前=+DATA/orcl/datafile/users.264.820462947
チャネルORA_DISK_1: ピース1(2013/09/24 19:47:52)を起動します
チャネルORA_DISK_1: ピース1(2013/09/24 19:48:07)が完了しました
ピース・ハンドル=+FRA/orcl/backupset/2013_09_24/nnndn1_incr_update_0.310.827005673 タグ
=INCR_UPDATE コメント=NONE
チャネルORA_DISK_1: バックアップ・セットが完了しました。経過時間: 00:00:15
backupが完了しました(完了時間: 2013/09/24 19:48:07)

Control File and SPFILE Autobackupが開始されました(開始時間: 2013/09/24 19:48:07)
ピース・ハンドル=+FRA/orcl/autobackup/2013_09_24/s_827005687.309.827005689 コメント=NONE
Control File and SPFILE Autobackupが完了しました(完了時間: 2013/09/24 19:48:10)

おや?と思って頂ければ嬉しい限りです。演習4と5を繰り返しただけですが、バックアップ時間が15秒へ短縮しているではないですか。これはチェンジ・トラッキング・ファイルを使用したような雰囲気が漂っていますね。と言う事で、先ほどと同じように、V$BACKUP_DATAFILEビューのUSED_CHANGE_TRACKING列を確認してみましょう。

$ sqlplus /nolog
SQL> connect / as sysdba
set linesize 150 pages 5000
alter session set NLS_DATE_FORMAT='YYYY/MM/DD HH24:MI:SS' ;

SQL> -- レベル1のバックアップのサイズとブロック・チェンジ・トラッキングの使用状況を確認
select FILE#, INCREMENTAL_LEVEL, COMPLETION_TIME, BLOCK_SIZE, DATAFILE_BLOCKS,
       BLOCKS, BLOCKS_READ, USED_CHANGE_TRACKING
  from V$BACKUP_DATAFILE
 where INCREMENTAL_LEVEL > 0
ORDER BY 3,1;

     FILE# INCREMENTAL_LEVEL COMPLETION_TIME     BLOCK_SIZE DATAFILE_BLOCKS     BLOCKS BLOCKS_READ USE
---------- ----------------- ------------------- ---------- --------------- ---------- ----------- ---
         4                 1 2013/09/24 19:44:45       8192            3040          1        3040 NO
         1                 1 2013/09/24 19:45:19       8192          131072         28      131072 NO
         2                 1 2013/09/24 19:45:19       8192          131072         22      131072 NO
         3                 1 2013/09/24 19:45:19       8192          131072      21150      131072 NO
         5                 1 2013/09/24 19:45:19       8192          131072      19202      131072 NO
         4                 1 2013/09/24 19:47:53       8192            3040          1           1 YES
         1                 1 2013/09/24 19:47:54       8192          131072         28          89 YES
         2                 1 2013/09/24 19:47:54       8192          131072         52         269 YES
         3                 1 2013/09/24 19:47:59       8192          131072      20445       20663 YES
         5                 1 2013/09/24 19:47:59       8192          131072      19202       19253 YES


SQL> -- ブロック・チェンジ・トラッキングを使用したレベル1バックアップ取得時のI/O量を確認
select FILETYPE_NAME, SMALL_READ_MEGABYTES, LARGE_READ_MEGABYTES, 
       SMALL_WRITE_MEGABYTES, LARGE_WRITE_MEGABYTES
  from V$IOSTAT_FUNCTION_DETAIL
 where FUNCTION_NAME = 'RMAN' ;

FILETYPE_NAME                SMALL_READ_MEGABYTES LARGE_READ_MEGABYTES SMALL_WRITE_MEGABYTES LARGE_WRITE_MEGABYTES
---------------------------- -------------------- -------------------- --------------------- ---------------------
Control File                                    5                   19                     2                     9
Data File                                       2                  313                     0                     0
Other                                           0                    0                     0                     0
Data File Incremental Backup                    0                    0                     0                   310
Other                                           0                    0                     0                     0
Other                                           0                    2                     0                     0
Other                                           0                    0                     0                    10

バッチリですね!2回目に実行したLevel1増分バックアップで生成されたバックアップ(COMPLETION_TIME列が19時47分台のレコード)のUSERD_CHANGE_TRACKING列が全て「YES」になっていることから、チェンジ・トラッキン グ・ファイルを使用した高速な増分バックアップが実行できていると確認できます。

さらに、これらのバックアップを作成する為に元のデータファイルから読み込んだブロック数(BLOCKS_READ列)も、圧倒的に小さな数に変化しています。例えば、FILE#5の1回目のバックアップ(COMPLETION_TIME列が19時45分台)では、元のデータファイルのブロック数と同じ数の131,072個でしたが、2回目のバックアップでは19,253個 = 約150MBとなっているので、更新したブロックのみに限定した読み込みに変化していることが明確に理解できますね。V$IOSTAT_FUNCTION_DETAILビューにおいても、元の全データファイルからの読み込み量が313MBまで小さくなっています。素晴らしい!


ちなみに、ブロック・チェンジ・トラッキング機能を有効化した後の1回目の増分バックアップにおいて、チェンジ・トラッキング・ファイルが使用されなかった件ですが、実はそれほど難しいことではないのです。なぜならば、増分バックアップとは前回のバックアップから変更があったブロックをバックアップする仕組みであることを理解した上で、今回のブロック・チェンジ・トラッキング機能を有効化したタイミングを見直してみてください。演習3で有効化していますが、その時は既にLevel0のバックアップの取得が完了していますね。このタイミングです。

Level0のバックアップ完了後からブロック・チェンジ・トラッキング機能の有効化するまでの間、ユーザーからSQLを投げていなかったとしても、SYSTEM表領域やSYSAUX表領域、UNDO表領域等のブロックは内部SQLによって更新されています。有効化する前なので、これらの更新ブロックは、チェンジ・トラッキング・ファイル上に更新されたことが記録されていないことになります。よって、有効化した直後の増分バックアップではチェンジ・トラッキング・ファイルを使用しても全ての差分ブロックをバックアップすることが出来ないので、結果的にチェンジ・トラッキング・ファイルを使用しないことを選択しているのですね。

さてさて、いかがでしたでしょうか?

ブロック・チェンジ・トラッキング機能を有効化することで差分バックアップ時に「データファイル内の全てのブロックを読み取る必要が無くなり」、「更新されたブロックのみに絞り込む = 必要最小限の時間とH/Wリソースの消費に抑えたバックアップが可能」となることが納得して頂けたかと思います。実際に、数TB~数十TBクラスのデータベースにおいてもブロック・チェンジ・トラッキング機能を使用したRMANの高速増分バックアップは採用されています。もちろん、RMANバックアップの採用を決める要素は高速化だけでは無いと思いますので、次回以降は「確実に復旧できるバックアップとは?」に注目してRMANをご紹介していければと考えています。

ちなみに、これからOracle Master Platinumの実技試験に挑戦される方は、絶対に今回ご紹介した高速増分バックアップをマスターしておいた方が良いです。いつデータベースが壊れるか分かりませんからバックアップの取得が必須です。このバックアップ時間を短縮できれば試験にかけられる時間が増えますから合格の確率もあがってくること間違い無いです。既に受験された方であれば激しく同意して頂けると思います。

今回も体験して頂きまして、ありがとうございました。次回もよろしくお願い致します。

しばちょう先生の試して納得!DBAへの道 indexページ▶▶