技術ブログ
目次
渡部です。この記事は、JPOUG Advent Calendar 2019 の1日目の記事です。 この記事では、RMANの優れた点をまとめつつ、RMANへの愛を語ってみたいと思います 🙂
RMANは、データベース運用において最も重要なバックアップと復旧のためのツールであり、Oracle Databaseに標準添付されています。 基本的な機能であれば、Oracle DatabaseのすべてのEditionで使用できます。(一部の機能はEnterprise Edition限定です)
データベースにはデータが格納されます。 格納されるデータは、そのシステム固有のものですから、データが失われると基本的に取り戻すことはできません。 このため、繰り返しになりますがデータベース運用においては、バックアップと復旧が最も重要です。
RMANを使えば、バックアップと復旧をシンプルなコマンド実行で簡単に実行できます。具体的には、
以下にデータベース全体のバックアップを実行したときのコマンド実行結果を示します。
$ rman target /
Recovery Manager: Release 19.0.0.0.0 - Production on Sun Dec 1 16:57:48 2019
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
connected to target database: J30 (DBID=4174331218)
RMAN> backup database;
Starting backup at 01-DEC-19
using channel ORA_DISK_1
channel ORA_DISK_1: starting full datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00001 name=/u01/app/oracle/oradata/J30/system01.dbf
input datafile file number=00003 name=/u01/app/oracle/oradata/J30/sysaux01.dbf
input datafile file number=00004 name=/u01/app/oracle/oradata/J30/undotbs01.dbf
input datafile file number=00007 name=/u01/app/oracle/oradata/J30/users01.dbf
channel ORA_DISK_1: starting piece 1 at 01-DEC-19
channel ORA_DISK_1: finished piece 1 at 01-DEC-19
piece handle=/u01/app/oracle/fast_recovery_area/J30/backupset/2019_12_01/o1_mf_nnndf_TAG20191201T165802_gy6wncht_.bkp tag=TAG20191201T165802 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:25
Finished backup at 01-DEC-19
Starting Control File and SPFILE Autobackup at 01-DEC-19
piece handle=/u01/app/oracle/fast_recovery_area/J30/autobackup/2019_12_01/o1_mf_s_1025888308_gy6wo4vv_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 01-DEC-19
さらにデータベース全体をリストア+リカバリしたときのコマンド実行結果を以下に示します。
$ rman target /
Recovery Manager: Release 19.0.0.0.0 - Production on Sun Dec 1 17:03:01 2019
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
connected to target database (not started)
RMAN> startup mount
Oracle instance started
database mounted
Total System Global Area 1610609200 bytes
Fixed Size 8897072 bytes
Variable Size 889192448 bytes
Database Buffers 704643072 bytes
Redo Buffers 7876608 bytes
RMAN> restore database;
Starting restore at 01-DEC-19
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=253 device type=DISK
channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00001 to /u01/app/oracle/oradata/J30/system01.dbf
channel ORA_DISK_1: restoring datafile 00003 to /u01/app/oracle/oradata/J30/sysaux01.dbf
channel ORA_DISK_1: restoring datafile 00004 to /u01/app/oracle/oradata/J30/undotbs01.dbf
channel ORA_DISK_1: restoring datafile 00007 to /u01/app/oracle/oradata/J30/users01.dbf
channel ORA_DISK_1: reading from backup piece /u01/app/oracle/fast_recovery_area/J30/backupset/2019_12_01/o1_mf_nnndf_TAG20191201T165802_gy6wncht_.bkp
channel ORA_DISK_1: piece handle=/u01/app/oracle/fast_recovery_area/J30/backupset/2019_12_01/o1_mf_nnndf_TAG20191201T165802_gy6wncht_.bkp tag=TAG20191201T165802
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:01:05
Finished restore at 01-DEC-19
RMAN> recover database;
Starting recover at 01-DEC-19
using channel ORA_DISK_1
starting media recovery
media recovery complete, elapsed time: 00:00:01
Finished recover at 01-DEC-19
RMAN>
すこし誇張気味ではありますが、基本的には3つのコマンド(backup database, recover, restore)を覚えておけば、 どこの環境の、どんなOracleデータベースであってもバックアップと復旧ができるわけです! RMANすごい!
バックアップは定期的に取得するものであるため、運用を継続していくとバックアップファイルがどんどん増えてゆきます。アーカイブログファイルも同様にどんどん増えてゆきます。このため、古いバックアップやアーカイブログファイルは適宜削除する必要があります。
RMANには、保存ポリシーを設定して、古いバックアップやアーカイブログファイルを自動的に判定し、簡単に削除する仕組みがあります。システムの要件に応じてRMAN保存ポリシーを設定しておけば、あとは定期的にバックアップを取得するだけで、古いバックアップは自動的に削除されます。とても運用が簡単になります。
保存ポリシーは、冗長性またはリカバリ期間のいずれかの方法で指定できます。
保存するバックアップファイルの世代数を指定します。指定された世代数のバックアップに加えて、そのバックアップを用いてリカバリを行うために必要なアーカイブログファイルが保存対象となります。
以下の図では、毎日0:00にバックアップを取得するデータベースで、冗長性を2と設定した場合に、どのバックアップおよびアーカイブログファイルが必要と判断されるかを示しています。
デフォルトでは保存ポリシーは冗長性で、冗長数が1です。すなわち、直近のバックアップ1つと、そのバックアップ取得後に出力されたアーカイブログファイルが保存対象となります。
過去N日間について、その範囲内の任意の時点に復旧できるようバックアップを保存します。N日をリカバリ期間として指定します。
以下の図では、毎日0:00にバックアップを取得するデータベースで、リカバリ期間を1日と設定した場合に、どのバックアップおよびアーカイブログファイルが必要と判断されるかを示しています。
近年のトレンドとして、データベースに保管されるデータ量が増えたり、システムの対象領域が広がった結果、 大きなサイズのデータベースが増えています。 当然ですが、サイズが大きくなったとしても、データベースは適切にバックアップする必要があります。 Oracle Databaseはサイズが大きいデータベースをバックアップするためのざまざまな機能が用意されています。
RMANの増分バックアップは前回のバックアップから更新されたデータブロックだけをバックアップするバックアップ方法です。更新されたデータブロックのみをバックアップするため、データベース全体をバックアップするよりも大幅にバックアップファイルのサイズを削減できます。
差分増分バックアップは、最後に実行された増分バックアップ以降に更新されたブロックだけをバックアップする増分バックアップです。増分の基準は「最後に実行された増分バックアップ」です。
差分増分バックアップは、レベル0の増分バックアップによる全体バックアップと、レベル1の差分増分バックアップによる差分増分バックアップを組み合わせて実行します。1週間に1回全体バックアップを実行し、それ以外の日は差分増分バックアップを実行するなどが考えられます。
累積増分バックアップは、最後に実行されたレベル0バックアップ以降に更新されたすべてのブロックがバックアップ対象となります。
増分バックアップを用いると、バックアップファイルのサイズを削減することができますが、バックアップ時間を短縮することはできません。それは、更新されたブロックを抽出するために、データファイル全体にアクセスしているからです。
バックアップ時間を短縮するには、高速増分バックアップを使用します。高速増分バックアップは、更新されたブロックがデータファイルのどこにあるかをブロックチェンジトラッキングファイルでトラッキング(追跡)しておくことで、データファイル全体にアクセスすることなく、更新されたブロックを抽出できるようにする仕組みです
増分バックアップはバックアップ保存に必要なディスク領域を削減できる優れた機能ですが、復旧作業において、増分を適用する処理が必要なため、適用すべき増分が多いと復旧時間が長くなる問題があります。増分更新バックアップを用いると、この問題を解決できます。
増分更新バックアップは、全体バックアップ(レベル0の増分バックアップ)に対して差分バックアップ(レベル1の差分増分または累積増分バックアップ)をあらかじめ適用しておくことで、更新されたイメージコピー形式の全体バックアップを作成しておく方法です。障害発生時の復旧作業において、増分を適用する必要がないため、復旧に要する時間を短縮できます。この方法をオラクルは推奨バックアップ計画と呼んでいます。
増分更新バックアップはRECOVERコマンドとBACKUPコマンドを組み合わせて実現されるバックアップ運用の方法です。増分更新バックアップというバックアップファイルの種類があるわけではありません。
汎用のファイル圧縮のアルゴリズムを用いてバックアップファイルを圧縮する圧縮方法です。圧縮処理を実行するためCPUリソースが消費されますが、バックアップファイルのサイズを縮小し、必要なストレージ領域を減らすことができます。
また、未使用ブロックの圧縮も使用されます。これは、使用されていないブロックをバックアップ対象から除外することで、バックアップファイルのサイズを縮小する圧縮機能です。
デフォルトでは、バックアップは1つのチャネルを用いてシリアルで実行されます。複数のチャネルを用いてバックアップをパラレルで実行すると、ストレージ装置のI/O帯域に余裕がある場合、バックアップを高速化できます。
大きなサイズのデータファイルがある場合、そのデータファイルを並列にバックアップしたいことがあります。通常のパラレルバックアップでは並列処理の単位がファイルであるため、1つのファイルを並列でバックアップできません。
マルチセクションバックアップを使うと、1つのデータファイルを並列でバックアップできるようになります。この機能は、BIGFILE表領域のような1つのデータファイルが大きくなりがちなケースで非常に有用です。
データベース自体を暗号化することは重要なセキュリティ対処策ですが、データベースのバックアップの暗号化も重要です。バックアップはテープメディアや取り外し可能な外付けディスクに格納される場合があり、これらのメディアは外部に持ち出しやすいためです。
データリカバリアドバイザを利用することで、作業ミスの防止および復旧までの時間短縮を実現できます。 ログファイルやエラーメッセージを参考に各種コマンドを使用することでデータベースファイルやデータブロックの破損からの復旧が可能ですが、そもそも復旧作業は頻繁に行うような作業ではありませんので、復旧までに時間を要する場合が多いです。また、不慣れな作業を実行する中で作業ミスが発生することも十分に考えられます。
データリカバリアドバイザを利用すると、ファイル消失やブロック破損などの検出済み破損の表示、破損修復スクリプトの生成、修復作業の実行を自動化できます。また、データリカバリアドバイザは、いくつかの復旧手順の中から最適と判断したリカバリ方法を提示します。
# この時点で検出されている障害を表示
RMAN> LIST FAILURE;
データベース・ロール: PRIMARY
データベース障害のリスト
=========================
障害ID 優先度ステータス 検出時間 サマリー
------ -------- --------- -------- -------
262 HIGH OPEN 18-01-17 SYSTEM以外のデータファイルが1つ以上見つかりません
202 HIGH OPEN 18-01-17 データファイル6: '/u01/app/oracle/oradata/orcl/users01.dbf'には破損したブロックが1つ以上含まれています
# 障害を分析し、修復オプションを決定
RMAN> ADVISE FAILURE;
データベース・ロール: PRIMARY
データベース障害のリスト
=========================
障害ID 優先度ステータス 検出時間 サマリー
------ -------- --------- -------- -------
262 HIGH OPEN 18-01-17 SYSTEM以外のデータファイルが1つ以上見つかりません
202 HIGH OPEN 18-01-17 データファイル6: '/u01/app/oracle/oradata/orcl/users01.dbf'には破損したブロックが1つ以上含まれています
自動修復オプションを分析中です。これには少し時間がかかる場合があります
チャネル: ORA_DISK_1が割り当てられました
チャネルORA_DISK_1: SID=22 デバイス・タイプ=DISK
自動修復オプションの分析が完了しました
必須の手動アクション
========================
使用可能な手動アクションがありません
オプションの手動アクション
=======================
1. 意図せずにファイル/u01/app/oracle/oradata/orcl/users01.dbfの名前の変更または移動が行われていた場合リストアします
自動修復オプション
========================
オプション 修復 説明
------ ------------------
1 データファイル6をリストアおよびリカバリします
計画: 修復には、データが損失しない完全なメディア・リカバリが含まれます
修復スクリプト: /u01/app/oracle/diag/rdbms/orcl/orcl/hm/reco_3115036620.hm
# データリカバリアドバイザが推奨する復旧手順を確認
RMAN> REPAIR FAILURE PREVIEW;
計画: 修復には、データが損失しない完全なメディア・リカバリが含まれます
修復スクリプト: /u01/app/oracle/diag/rdbms/orcl/orcl/hm/reco_3115036620.hm
修復スクリプトの内容:
# restore and recover datafile
restore ( datafile 6 );
recover datafile 6;
sql 'alter database datafile 6 online';
# データリカバリアドバイザが推奨する復旧手順を実行
RMAN> REPAIR FAILURE;
計画: 修復には、データが損失しない完全なメディア・リカバリが含まれます
修復スクリプト: /u01/app/oracle/diag/rdbms/orcl/orcl/hm/reco_3115036620.hm
修復スクリプトの内容:
# restore and recover datafile
restore ( datafile 6 );
recover datafile 6;
sql 'alter database datafile 6 online';
この修復を実行しますか(YESまたはNOを入力してください)。 YES
修復スクリプトを実行しています
restoreが開始されました(開始時間: 18-01-17)
チャネルORA_DISK_1の使用
チャネルORA_DISK_1: データファイル・バックアップ・セットのリストアを開始しています
チャネルORA_DISK_1: バックアップ・セットからリストアするデータファイルを指定しています
チャネルORA_DISK_1: データファイル00006を/u01/app/oracle/oradata/orcl/users01.dbfにリストアしています
チャネルORA_DISK_1: バックアップ・ピース/u01/app/oracle/fast_recovery_area/ORCL/backupset/2018_01_16/o1_mf_nnndf_TAG20180116T155906_f5v8ot8q_.bkpから読取り中です
チャネルORA_DISK_1: ピース・ハンドル=/u01/app/oracle/fast_recovery_area/ORCL/backupset/2018_01_16/o1_mf_nnndf_TAG20180116T155906_f5v8ot8q_.bkp タグ=TAG20180116T155906
チャネルORA_DISK_1: バックアップ・ピース1がリストアされました
チャネルORA_DISK_1: リストアが完了しました。経過時間: 00:00:01
restoreが完了しました(完了時間: 18-01-17)
recoverが開始されました(開始時間: 18-01-17)
チャネルORA_DISK_1の使用
メディア・リカバリを開始しています
スレッド1 (順序9)のアーカイブ・ログは、ファイル/u01/app/oracle/fast_recovery_area/ORCL/archivelog/2018_01_16/o1_mf_1_9_f5vhrqkw_.arcとしてディスクに存在します
スレッド1 (順序10)のアーカイブ・ログは、ファイル/u01/app/oracle/fast_recovery_area/ORCL/archivelog/2018_01_17/o1_mf_1_10_f5xhb85l_.arcとしてディスクに存在します
スレッド1 (順序11)のアーカイブ・ログは、ファイル/u01/app/oracle/fast_recovery_area/ORCL/archivelog/2018_01_17/o1_mf_1_11_f5xqvoml_.arcとしてディスクに存在します
アーカイブ・ログ・ファイル名=/u01/app/oracle/fast_recovery_area/ORCL/archivelog/2018_01_16/o1_mf_1_9_f5vhrqkw_.arc スレッド=1 順序=9
メディア・リカバリが完了しました。経過時間: 00:00:00
recoverが完了しました(完了時間: 18-01-17)
SQL文: alter database datafile 6 online
障害の修復が完了しました
データベースをオープンしますか(YESまたはNOを入力してください)。 YES
データベースがオープンしました。
# すべての障害が修復されているかを確認
RMAN> LIST FAILURE;
データベース・ロール: PRIMARY
指定に一致する障害が見つかりません
フラッシュバックデータベースを使うと、データベース全体を過去の状態に戻すことができます。不完全リカバリよりも高速に実行できる利点がありますが、別途フラッシュバックログが必要です。この節では、フラッシュバックデータベースの特徴と、フラッシュバックロギングの有効化を用いたフラッシュバックデータベースについて説明します。
誤ってTRUNCATE TABLEを実行してデータを失った表を復元するため、時刻を指定してフラッシュバックデータベースを実行する例を示します。
# 誤ってTRUNCATE TABLEを実行した後。これから表を復元する。
RMAN> SELECT count(*) FROM scott.emp;
COUNT(*)
----------
0
# MOUNTモードで再起動
RMAN> SHUTDOWN IMMEDIATE
データベースがクローズしました
データベースがディスマウントされました。
Oracleインスタンスがシャットダウンしました
RMAN> STARTUP MOUNT
ターゲット・データベースに接続しました(起動していません)。
Oracleインスタンスが起動しました
データベースがマウントされました。
(略)
# 誤削除実行前の日時を指定してフラッシュデータベースを実行
RMAN> FLASHBACK DATABASE TO TIME "TO_DATE('2018/02/19 16:56:50','YY/MM/DD HH24:MI:SS')";
flashbackが開始されました(開始時間: 18-02-19)
チャネル: ORA_DISK_1が割り当てられました
チャネルORA_DISK_1: SID=22 デバイス・タイプ=DISK
メディア・リカバリを開始しています
メディア・リカバリが完了しました。経過時間: 00:00:01
flashbackが完了しました(完了時間: 18-02-19)
# 一旦読み取り専用モードでオープンし、誤削除実行前の状態に戻っているか確認
RMAN> ALTER DATABASE OPEN READ ONLY;
文が処理されました
RMAN> SELECT count(*) FROM scott.emp;
COUNT(*)
----------
12
# インスタンスを停止して、あらためてRESETLOGSオプション付きでOPEN
RMAN> SHUTDOWN IMMEDIATE
データベースがクローズしました
データベースがディスマウントされました。
Oracleインスタンスがシャットダウンしました
RMAN> STARTUP MOUNT
ターゲット・データベースに接続しました(起動していません)。
Oracleインスタンスが起動しました
データベースがマウントされました。
(略)
RMAN> ALTER DATABASE OPEN RESETLOGS;
文が処理されました
表リカバリは過去のある時点の表を復元できるOracle Database 12cからの新機能です。
ソースデータベース(表を復元したいデータベース)でRECOVER TABLEを実行すると、RMANはソースデータベースのバックアップとオンラインログファイル、 アーカイブログファイルを用いて、復元ターゲット日時の状態の補助インスタンスを作成します。そして、リカバリ対象表を補助インスタンスからエクスポートし、ソースデータベースへインポートすることで、復元ターゲット日時の状態の表を復元します(検証してみると、実際には2つの補助インスタンスが起動するようですが、機能説明の観点では説明不要なので割愛します)。RECOVER TABLE実行時の動作イメージを以下の図に示します。
なお、補助インスタンスの作成や、インポート、エクスポートはRECOVER TABLE実行の中で自動的に行われ、別途コマンドなどを実行する必要はありません。
トランスポータブル表領域は、異なるデータベース間で高速にデータを転送する方法です。データを含むデータファイルそのものをコピーしてデータを転送するため、データの量が非常に多い場合、一旦データをダンプファイルにエクスポートしてからインポートする方法に比べて、データを高速に転送できます。
トランスポータブル表領域には2つの方法があります。
データポンプ・トランスポータブル表領域は、転送対象の表領域を読み取り専用にする必要があるため、転送対象の表領域への更新処理が一時的にできなくなります。
RMANトランスポータブル表領域は、転送対象の表領域を読み取り専用にする必要がありません。その代わりに、ソースデータベースにおけるデータファイルおよびメタデータ作成のため、補助インスタンスが作成され、バックアップとアーカイブログファイルを用いてリカバリ処理が実行されます。このため処理負荷が発生します。また、作業用のディスク領域も必要です。
RMANのDUPLICATEコマンドを使用することで、既存のデータベースをコピーした複製データベースを簡単に作成できます。構造やデータがまったく同じ複製データベースは、アプリケーションの開発/テストなどに使用できます。
バックアップベースの複製では、ソースデータベースのバックアップを元にデータベースを複製します。あらかじめデータベースのバックアップが取得されている必要があります。
アクティブデータベースでは、データファイルやアーカイブログファイルは直接ソースデータベースから複製先ホストにコピーされます。
ご紹介したように、RMANには多彩なバックアップ方法や復旧方法に加えて、データ転送やデータベース複製に関する機能があります。RMANは凄いツールです! みなさん、もっとRMANを使いましょう!