「基本からわかる!高性能×高可用性データベースシステムの作り方」indexページ▶▶
データベースのファイルが破損したという障害に備える最も基本的な方法は、バックアップを取得しておくことです。Oracle Databaseは適切な構成でバックアップを取得しておけば、障害の直前までリカバリすることが可能です。また、トランザクションを停止させずにバックアップを取得することが可能です。今回は、なぜそのようなことが可能なのか、バックアップ/リカバリの仕組みから解説します。
1 ファイルの破損
早速ですが、以下のようなエラーに遭遇したことはないでしょうか。
SQL> select count(*) from tab2 where col1=1;
select count(*) from tab2 where col1=1
*
行1でエラーが発生しました。:
ORA-01115: ファイル(ブロック番号)からの読取りI/Oエラーが発生しました。 ORA-01110:
データファイル12: '/u01/app/oracle/oradata/SIDB18A/pdb/users201.dbf'
ORA-27072: ファイルI/Oエラーが発生しました。 Additional
information: 3
Additional information: 65664
これは滅多に起こるものではありませんが、表を格納するデータファイルに破損が検出されたというエラーです。データファイルの永続的な破損であるため、Oracleインスタンスの再起動で回避できるようなものではありません。この障害から復旧させるには、破損したデータファイルをバックアップからリストアし、REDOログによるリカバリが必要になります。
2 バックアップ/リストア/リカバリ
さて、バックアップ/リストア/リカバリとはそもそもどういう操作を指すのでしょうか。

一般的にはバックアップとは何らかのファイルのコピーを取得することですが、Oracle Databaseの文脈では主にデータファイルのコピーを取得することを指します。データファイル以外のファイルのコピーを取得することもバックアップと呼びますが、データファイルはサイズが大きいのでコピーに時間がかかり、データベースのバックアップというとその関心はデータファイルのコピーに集中します。
データファイルに障害が発生すると、バックアップからデータファイルを書き戻します。これをリストアと呼びます。しかし、リストアしたデータファイルには、バックアップを取得した時点までの更新しか反映されていません。ですが、Oracle Databaseでは更新情報はREDOログに記録されています。リストアしたデータファイルに対してREDOログに記録されている更新情報を適用していくことをリカバリといいます。リストアとリカバリによって、データファイルを障害直前の状態に戻すことが可能です。
3 物理バックアップと論理バックアップ
データファイルのコピーを取得し、REDOログを適用して障害直前の状態に戻せる一連のバックアップ手法を物理バックアップと呼びます。REDOログにはどのデータブロックのどの場所にどんな変更を加えたかが記録されています。そのため、リカバリの起点となるデータブロックのイメージは物理バックアップによって取得されたものでなければなりません。
これに対し、特定の表や表領域のダンプをOracle Data Pumpで取得することを論理バックアップと呼びます。論理バックアップは別のデータベースにデータを移行するときなどに便利なツールですが、インポートしてもエクスポート元のデータブロックとは同じにはなりません。インポートした箇所にREDOログを適用することはできないため、論理バックアップを取得した時点の状態しか復元できません。そのため、本番システムの設計ではまず物理バックアップを検討してください。
4 RMANとユーザー管理バックアップ
Oracle Databaseでは物理バックアップを取得する方法は2種類あります。1つはOracle Databaseに付属するRecovery Manager(RMAN)というツールです。RMANはOracleインスタンスに接続し、Oracleサーバー・プロセスを生成します。Oracleサーバー・プロセスがデータベースのファイルにアクセスする仕組みを使ってファイルのコピーを取得します。バックアップ運用の第一選択肢はRMANです。
もう1つの方法が、ユーザー管理バックアップと呼ばれる手法です。これは、OSのファイル・コピー・コマンドなどを使用し、Oracleインスタンスが関知しないところでファイルのコピーを取得する方法です。RMAN以外のすべてのファイル・コピー手法はユーザー管理バックアップに分類されます。ストレージ・アレイが持つスナップショット機能などを使用する場合はユーザー管理バックアップです。
ユーザー管理バックアップは、慣れ親しんだOSのツールが使いたいという理由やストレージ機能を使用したいという理由で選択されることがあるのですが、ファイルのコピーを取得する設計の自由度が高すぎるため「リカバリ可能」という前提を満たしていない場合があります。バックアップの運用はリカバリするためにあります。本稿の最後でリカバリに失敗するケースを扱います。
5 オンライン・バックアップ
Oracle Databaseはデータベースを稼働させたままバックアップを取得する方法があります。アプリケーションが更新トランザクションを実行し、オンラインREDOログやデータファイルが書き換えられている最中にも、リカバリ可能なファイルのコピーを取得する方法が存在するのです。不思議に思いませんか?
Oracle Databaseではオンライン・バックアップを取得している最中でも、チェックポイントによってデータファイルが部分的に書き換えられていきます。データファイルの静止点という概念がありません。そのため、取得されたデータファイルのコピーは、オンライン・バックアップを開始した時点のデータファイルの状態でもなく、終了した時点の状態でもありません。オンライン・バックアップで取得されたデータファイルに含まれるデータブロックは、更新トランザクションがCOMMITで確定したものも含まれますし、まだCOMMITされていない変更も含まれています。そのため、オンライン・バックアップは別名、非一貫性バックアップとも呼ばれます。これに対し、OracleインスタンスをSHUTDOWN NORMAL/TRANSACTIONAL/IMMEDIATEで停止させ、すべての更新トランザクションによる変更がCOMMITまたはROLLBACKされた上でチェックポイントがかかることですべてのデータブロックに一貫性がある状態で取得するバックアップを一貫性バックアップと呼びます。SHUTDOWN ABORTで停止させた後に取得するバックアップは、トランザクションが確定しておらず、チェックポイントによるデータファイルへの反映も行われていないため、Oracleインスタンスが停止していたとしてもそれは非一貫性バックアップです。
なぜ非一貫性バックアップがバックアップとして成立するかというと、実はデータファイルのバックアップに一貫性があるかどうかということは重要ではなく、REDOログの適用によるリカバリ後に一貫性が得られればよいのです。つまり、オンライン・バックアップで取得したデータファイルはREDOログを適用することを前提として、非一貫性バックアップを許容しているのです。非一貫性バックアップとリカバリは必須の組み合わせです。そのため、Oracle Databaseでオンライン・バックアップを取得するにはアーカイブ・ログ・モードでないと実行できないようになっています。
今回は主にユーザー管理バックアップについて見ていきます。RMANは次回に解説します。
6 ユーザー管理バックアップでのオンライン・バックアップ
オンライン・バックアップはRMANでもユーザー管理バックアップでも取得することができます。しかしその内部動作は異なります。
データファイルのオンライン・バックアップが行われている最中にも、Oracleインスタンスはデータファイルに対してチェックポイントの書き込みを行います。その最小単位はOracleデータブロックで、多くの場合8KBや16KBで作成されています。
ユーザー管理バックアップの場合、OSのファイル・コピー・コマンドなどのOracleインスタンスが関知しない方法でデータファイルのコピーを取得します。しかし、OSがアトミックに処理できるI/OサイズよりもOracleデータブロックのサイズのほうが大きいため、Oracleデータブロックの読み取りとチェックポイントの書き込みが衝突すると、1つのOracleデータブロックの中でさえ一貫性のないイメージがコピーされてしまうことが起こり得ます。これを分裂ブロック(fractured block)と呼びます。ただし分裂ブロックを意図的に再現させるのは非常に困難です。

Oracleデータブロックは先頭と末尾に更新カウンタであるSystem Change Number(SCN)が記録されており、先頭と末尾のSCNが一致していないことで分裂ブロックが発生したことを検出できます。OracleのREDO情報はOracleデータブロックの中の更新した箇所のみの情報しか記録されていないため、分裂ブロックを含むデータファイルがリストアされ、リカバリしようとしたとき、分裂ブロックへのREDO適用で不都合が生じます。この問題に対処するため、ユーザー管理バックアップでは、オンライン・バックアップを取得する前にホットバックアップ・モードという状態にします。ALTER DATABASE BEGIN BACKUPを実行すると、データベース全体がホットバックアップ・モードになります。このとき、データベース・バッファキャッシュにあるまだ書き戻されていないデータブロックがチェックポイントで書き戻され、この時点のSCNがデータファイル・ヘッダのチェックポイントSCNとして固定されます。このチェックポイントSCN以前の更新はすべてデータファイルに反映されているので、リカバリでREDOを適用するのはこのチェックポイントSCN以降ということがわかります。

ホットバックアップ・モードでは、更新が発生したデータブロック全体のイメージをREDOログに記録します。リカバリするときは、REDOログに記録されたデータブロック全体のイメージを上書きします。これによって、分裂ブロックが発生したとしても、REDOログに記録された一貫性のあるデータブロックのイメージでリカバリすることができます。通常モードでは変更した箇所のみREDOログに記録されますが、ホットバックアップ・モードは生成されるREDOログの量が増えます。ホットバックアップは更新があまり発生していない時間帯に実行しましょう、と言われているのはこのためです。
これに対し、RMANでのオンライン・バックアップでは、Oracleサーバー・プロセスがデータブロックを読み取ります。この読み取りとデータベース・ライター(DBWR)プロセスによるチェックポイントの書き込みはOracleインスタンスが適切に排他制御するため、分裂ブロックは発生しません。そのため、RMANではホットバックアップ・モードにはしません。
6.1 オンラインREDOログと制御ファイルのバックアップ
ここまで、データファイルのオンライン・バックアップは非一貫性バックアップを許容することを説明しました。Oracleのデータベースを構成するファイルはまだほかにもあります。オンラインREDOログと制御ファイルです。これらのファイルも常に部分的に更新されています。データファイルのリカバリはREDOログと制御ファイルの情報を使用することで、データファイルの非一貫性バックアップを許容しています。しかし、オンラインREDOログと制御ファイル自体には「リカバリ」する仕組みがないため、一貫性を持ったイメージを作成する必要があります。
オンラインREDOログの一貫性のあるバックアップを作成するには、アーカイブREDOログにコピーさせるという方法を取ります。アーカイブREDOログはコピーが完了するとそれ以上変更されることはありません。REDOログ情報のバックアップはアーカイブREDOログ・ファイルのコピーを取得することで行います。オンラインREDOログ・ファイルをOSのファイル・コピー・コマンドなどでコピーを取得してはいけません。
制御ファイルの一貫性のあるバックアップを作成するには、Oracleインスタンスに専用のコマンドを発行します。すると、制御ファイルのスナップショット・イメージが作成されます。制御ファイルにはデータベースのファイル構造が記録されているため、データファイルのバックアップを取得するときだけでなく、ファイル構造に変更があったとき、つまりデータファイルやオンラインREDOログ・ファイルの追加が行われたときにも制御ファイルのバックアップを取得することを検討してください。
データファイルとREDOログ、そして制御ファイルのバックアップはどのような順序で取得するのでしょうか。

データファイルのオンライン・バックアップはREDOログでリカバリすることが前提であると説明しました。データファイルのコピー中に生成されたREDOログ情報はリカバリに必須です。しかし、そのREDOログ情報はデータファイルのコピーが完了した直後にはまだオンラインREDOログ・ファイル上にあります。そのため、データファイルのコピーが完了しホットバックアップ・モードを解除した後にオンラインREDOログをアーカイブし、REDOログ情報のバックアップを取得します。
生成されたアーカイブREDOログ・ファイルの情報は制御ファイルにも記録されます。そのため、オンラインREDOログをアーカイブした後に制御ファイルのバックアップを取得します。
RMANでデータファイルとアーカイブREDOログのバックアップを取得するときはこの順序で取られます。
7 ユーザー管理バックアップでのリストア/リカバリ
冒頭で提示したデータファイルの障害からリストア/リカバリする手順を見ていきましょう。
この障害はddコマンドでデータファイルを上書きすることでデータブロックを破壊しました。
$ dd if=/dev/zero of=/u01/app/oracle/oradata/SIDB18A/pdb/users201.dbf bs=8k count=1 seek=131
障害が検出されるのは、Oracleのプロセスが破損した領域にアクセスしたときです。該当データブロックがデータベース・バッファキャッシュにあると、SQLの実行はデータファイルにはアクセスしません。そのため、データベース・バッファキャッシュをフラッシュしてからこのデータブロックにアクセスするSQLを実行します。
SQL> ALTER SYSTEM FLUSH BUFFER_CACHE; システムが変更されました。
SQL> select col1 from tab2 where col1=1;
select col1 from tab2 where col1=1
*
行1でエラーが発生しました。:
ORA-01115: ファイル(ブロック番号)からの読取りI/Oエラーが発生しました。 ORA-01110:
データファイル12: '/u01/app/oracle/oradata/SIDB18A/pdb/users201.dbf'
ORA-27072: ファイルI/Oエラーが発生しました。 Additional
information: 3
Additional information: 65664
データファイルの障害が検出されると、実行しようとしたSQLにエラーが返りますが、Oracleインスタンスのアラートファイルにも記録されます。
2018-08-17T10:41:40.749418+09:00
Errors in file /u01/app/oracle/diag/rdbms/sidb18a/sidb18a/trace/sidb18a_mz00_20461.trc:
ORA-01110: データファイル12: '/u01/app/oracle/oradata/SIDB18A/pdb/users201.dbf'
ORA-01200: 実ファイル・サイズ70160が正しいサイズ70160ブロックより小さくなっています。
Checker run found 1 new persistent data failures
問題を起こしたSQLはコンテナ・データベース構成の「pdb」という名前のプラガブル・データベースで実行されていたのですが、pdbのデータファイル番号12のファイル(/u01/app/oracle/oradata/SIDB18A/pdb/users201.dbf)に問題があることがわかります。
リストア/リカバリの操作をするにはSYSDBAもしくはSYSBACKUP権限でログインします。
$ sqlplus / as sysbackup
該当データファイルをバックアップからリストアするためには、まずOFFLINEにする必要があります。特定のプラガブル・データベースのデータファイルをOFFLINEにするには、そのプラガブル・データベースに移動して実行します。
SQL> ALTER SESSION SET CONTAINER=pdb; セッションが変更されました。 SQL> ALTER DATABASE DATAFILE 12 OFFLINE; データベースが変更されました。
データファイルをOFFLINEにした後、バックアップからリストアします。ユーザー管理バックアップでバックアップを取得したので、リストアもOSのコマンドです。
$ cp /u01/app/oracle/usermanagedbackup/SIDB18A/pdb/users201.dbf /u01/app/oracle/oradata/SIDB18A/pdb/users201.dbf
リストアが完了したのち、リカバリを実行します。
SQL> RECOVER AUTOMATIC DATAFILE 12; メディア・リカバリが完了しました。
リカバリが完了したら、該当データファイルをONLINEにします。
SQL> ALTER DATABASE DATAFILE 12 ONLINE; データベースが変更されました。
データファイルをONLINEにできたら、該当領域にアクセスするSQLは実行可能です。
SQL> select count(*) from tab2 where col1=1;
COUNT(*)
----------
1
以上がユーザー管理バックアップでのデータファイル破損からのリストア/リカバリの手順です。
実際に障害が発生した場合は、障害個所の特定と復旧方法の決定に人間の判断が入るので、そこに時間がかかります。RMANでも同様の手順となるのですが、RMANにはデータ・リカバリ・アドバイザという機能があり、障害ファイルの特定から該当ファイルのONLINEまでを自動化する仕組みがあります。すべての構成でデータ・リカバリ・アドバイザが使用できるわけではないのですが、この機能が使用できるケースでは最も時間がかかる人間の判断を短縮することが可能です。
8 ストレージ機能を使用したバックアップ
ストレージ・アレイにはスナップショットなどのファイルのコピーを補助する機能を持つものがあります。Oracle Databaseはユーザー管理バックアップでこれらの機能を使用したバックアップを取得することが可能です。ホットバックアップ・モード中は生成されるREDOログが増加するため、なるべく短時間で済ますことが望まれます。ストレージが持つスナップショット機能などを使用すると、ホットバックアップ・モードの時間を短くすることが可能です。

データファイルのスナップショットを取る前にホットバックアップ・モードにします。Oracle Databaseはホットバックアップ・モードによってI/Oを止めずにデータファイルのバックアップを取得することが可能ですが、ストレージによってはI/Oを停止させたほうが良いものがあります。そのためのSQLがALTER SYSTEM SUSPENDです。このSQLを実行するとデータファイルと制御ファイルへのI/Oが停止します。I/Oを停止させている時間は短いことを想定しているため、スナップショットなどの機能を使用することを想定しています。
データファイルのスナップショットを取得したら、停止させていたI/OをALTER SYSTEM RESUMEによって再開させ、ホットバックアップ・モードを終了させます。データファイルをOSのファイル・コピー・コマンドでコピーする時間よりも、スナップショットを取得する時間のほうが短いことが期待できます。そのため、ファイル・コピー・コマンドの場合よりもホットバックアップ・モードの時間を短くすることができます。
データファイルのスナップショットが完了したら、スナップショット・ボリュームからデータファイルのコピーを取得します。このコピーには長時間かかっても問題ありません。
8.1 スナップショット機能と組み合わせるときの注意点
スナップショットなどの機能と組み合わせるときにも注意点があります。ホットバックアップ・モードで一貫性のないファイルのコピーが許されるのはデータファイルのみであることに注意してください。そのため、スナップショットを取得するボリュームにはデータファイルのみを格納してください。
また、スナップショットはボリュームの過去のイメージを提供する機能ですが、ストレージ・デバイスとしてはデータベース本体のボリュームとハードウェアを共有しています。そのため、ストレージ・デバイスの障害が発生するとデータベース本体とスナップショットの両方に影響が及ぶ可能性があります。データベースのバックアップ/リカバリはストレージ・サブシステムの障害も想定すべきです。スナップショットを取得した時点でバックアップが完了したことにせず、そこから別のデバイスへファイルのコピーを行うことを検討してください。
9 リカバリに失敗するケース
ユーザー管理バックアップは「ファイルをコピーする」という方法の設計の自由度が高すぎるため、リカバリできない方法でファイルのコピーを運用してしまっている場合があります。以降ではリカバリに失敗するケースを見ていきます。
9.1 ボリューム追加の考慮漏れ
データベースを新しく構築し、運用を開始したその時点では正しくリカバリできるバックアップ設計になっていたとします。
データベースのサイズが成長し、新しくストレージ・ボリュームを追加することはよくあることです。しかし、追加したボリュームに配置されたデータファイルがバックアップ対象から漏れている場合があります。なぜそういうことが起こるかというと、ファイルのコピーを取得するバックアップ・スクリプトがファイルシステムの特定のディレクトリ以下を指している場合や、特定のボリュームを指している場合があるからです。ボリュームを追加した場合はバックアップ・スクリプトを再考する必要があります。
RMANの場合、backupコマンドを発行するたびにその時点のバックアップ対象のファイルが探索されます。そのため、ボリュームを追加したとしてもバックアップ対象のファイルが漏れることはありません。
9.2 REDOログの欠損
データファイルをリカバリするためには、バックアップを取得した時点からのすべてのREDOログ情報が必要です。1つの欠損も許されません。
アーカイブREDOログはアーカイブ・ログ・モードである限り生成され続けます。そのため、いつかはアーカイブREDOログを削除するという運用が必要になります。しかし、少なくとも最後にデータベースのフルバックアップを取得したところからのアーカイブREDOログは保存しておかなければなりません。
もう1つの事故になりやすいケースは、オンラインREDOログ・ファイルのコピーを取得している場合です。OracleインスタンスをSHUTDOWN すると技術的にはオンラインREDOログ・ファイルのコピーを取得することも可能です。しかし、オンラインREDOログ・ファイルは循環して最新のREDOログ情報が上書きされていきます。オンラインREDOログ・ファイルを古いファイルでリストアしてしまうと、それは最新のREDOログ情報を喪失してしまうことになります。オンラインREDOログのバックアップを取得するには、ALTER SYSTEM ARCHIVE LOG CURRENTを発行してアーカイブREDOログにコピーし、アーカイブREDOログのバックアップを取るようにしてください。
9.3 REDOログをスナップショット・ボリュームに含めた
スナップショットを取得するボリュームにオンラインREDOログやアーカイブREDOログが含まれている場合を想定します。スナップショット・ボリュームからはデータファイルのみを別のデバイスにコピーしているとします。データファイルのみをコピーしているのでREDOログ・ファイルの一貫性などどうでもいいはずです。何が起こるでしょうか?
もし、データファイルに障害が発生したとき、運用チームは別デバイスにコピーした「データファイル」から適切にリストアしてくれるでしょうか。スナップショットがあるのなら、スナップショット・イメージをリストアしようとする人が必ず現れます。スナップショット・イメージは過去のボリュームのイメージであるため、REDOログを含んだ「ボリューム」をリストアするとREDOログの欠損が発生します。
今回はバックアップ/リストア/リカバリの基本とユーザー管理バックアップについて解説しました。ストレージ機能を組み合わせるにはユーザー管理バックアップを使用しますが、リカバリ可能という前提を満すにはかなり注意深いバックアップ設計が必要です。
次回はRMANを解説する予定です。Oracle Databaseの内部構造を把握しているツールはユーザー管理バックアップと比較して何ができるのでしょうか。
