ページ復元の実行

 このトピックは、完全復旧モデルまたは一括ログ復旧モデルを使用する SQL Server データベースに適用されます。ページ復元は、読み取り/書き込みファイル グループでのみサポートされます。

ページ復元の目的は、データベース全体を復元することなく 1 つ以上の損傷したページを復元することです。通常、復元候補のページは、そのページにアクセスする際に発生したエラーによって、"問題あり" に設定されています。問題ありに設定されているページは、msdb データベースの suspect_pages テーブルで特定できます。

注意

すべてのページ エラーが復元を必要とするわけではありません。セカンダリ インデックスなど、キャッシュされたデータで発生する問題は、データを再計算することで解決される可能性があります。たとえば、データベース管理者がセカンダリ インデックスを削除して再構築した場合、破損したデータは修正されていますが、suspect_pages テーブルにはそのことが記録されません。

複数のデータベース ページを直ちに復元することが可能です。ログ ファイル バックアップは、復元されるページが含まれているすべてのデータベース ファイルに適用されます。ファイル復元と同様に、ロールフォワード セットは 1 つのログ再実行パスで進められます。

ページ復元の目的は、損傷した個々のページを修復することです。少数のページに関する復元と復旧は、ファイルの復元を行うより高速に実行でき、復元処理中にオフラインになるデータ量が少なくなる場合があります。ただし、1 つのファイル内の多数のページを復元しなければならない場合は、ファイル全体を復元する方が効率的です。たとえば、デバイス上の多くのページが損傷している場合は、デバイスの故障が差し迫っていることを示している可能性があるので、できれば別の場所にファイルを復元し、デバイスを修復することを検討します。

ページ復元のシナリオ

SQL Server 2005 以降のバージョンのすべてのエディションでは、データベースがオフラインのときにページ復元を実行できます (オフライン ページ復元)。SQL Server 2005 Enterprise Edition 以降のバージョンでは、ページ復元中にデータベースがオンラインであれば、データベースをオンラインにしたままページ復元を実行できます。データベースがオンラインのときに実行する復元と復旧を、オンライン ページ復元といいます。

これらのページ復元のシナリオは次のとおりです。

  • オフライン ページ復元

    SQL Server 2005 Standard、SQL Server 2005 Express Edition、および SQL Server 2005 Workgroup 以降のバージョンでは、オフライン復元のみがサポートされます。SQL Server 2005 Enterprise Edition 以降のバージョンでは、データベースが既にオフラインになっていれば、オフライン復元が使用されます。オフライン ページ復元では、損傷したページの復元中はデータベースがオフラインです。データベースは、復元シーケンスの最後にオンラインになります。

    正常にページ復元を完了するには、データベースとの一貫性が保たれている状態になるようにページを復旧する必要があります。また、最新の完全復元または差分復元にチェーンが途切れていないログ バックアップを適用し、ページを含むファイル グループに現在のログ ファイルの状態を反映する必要があります。

  • オンライン ページ復元

    SQL Server 2005 Enterprise Edition 以降のバージョンでは、条件を満たしていれば、ページ復元が自動的にオンラインで実行されます。ほとんどの場合、ページを復元しているファイル グループを含むデータベースをオンラインにしたまま、損傷したページを復元できます。オンライン ページ復元は、特に、ハードウェア エラーが原因で損傷したページに有効です。

    場合によっては、損傷したページをオフラインで復元することも必要です。たとえば、特定の重要なページが損傷したことが原因で、データベースを起動できない可能性がある場合などです。このような場合は、オフライン復元を使用する必要があります。

    注意

    オンライン復元ではメタデータの更新が行われますが、重要なページが含まれている場合はこの更新に失敗する可能性があります。オンライン復元に失敗した場合は、復元をオフラインで実行する必要があります。

ページ復元では、SQL Server 2005 以降のバージョンのページ レベルのエラー報告 (ページ チェックサムを含む) および追跡の機能を活用することができます。チェックサムや破損した書き込みによって壊れていることが検出されたページ (損傷したページ) は、RESTORE ステートメントでそのページを指定することによって復元できます。ページ復元の目的は、少数の損傷したページを復元することです。RESTORE ステートメントで指定した各ページは、指定したバックアップ セットのページに差し替えられます。復元されたページは、データベースと一貫性のある状態に戻す必要があります。復元されるのは、明示的に指定したページのみです。

ページ復元の制限事項

復元できるのはデータベース ページのみです。ページ復元を使用して、次のものを復元することはできません。

  • トランザクション ログ

  • アロケーション ページ。これには、グローバル アロケーション マップ (GAM) ページ、共有グローバル アロケーション マップ (SGAM) ページ、およびページ空き容量 (PFS) ページなどが含まれます。詳細については、「エクステント割り当てと空き領域の管理」を参照してください。

  • すべてのデータ ファイルのページ 0 (ファイルのブート ページ)

  • ページ 1:9 (データベースのブート ページ)

  • フルテキスト カタログ

ある特定のページを復元できない場合は、データベース、ファイル、またはファイル グループの既存の完全バックアップを使用する必要があります。

注意

復元するページが、メタデータ ページなど特殊なページの場合、オンライン ページ復元は失敗します。このような場合は、オフライン ページ復元を実行してください。

ページ復元の要件

ページ復元の要件は次のとおりです。

  • データベースで完全復旧モデルまたは一括ログ復旧モデルを使用している必要があります。一括ログ復旧モデルを使用している場合は、いくつかの問題があります。詳細については、次のセクションを参照してください。

  • 読み取り専用ファイル グループのページは復元できません。ファイル グループでページ復元を実行している場合、同時にファイル グループを読み取り専用にしようとすると失敗します。

  • 復元シーケンスは、完全バックアップ、ファイル バックアップ、またはファイル グループ バックアップから開始する必要があります。

  • ページ復元には、現在のログ ファイルまでの中断されていないログ バックアップが必要であり、現在のログ ファイルでページが最新の状態になるように、すべてのログ バックアップを適用する必要があります。

  • ファイル復元シーケンスと同様に、各復元手順ではロールフォワード セットにさらにページを追加できます。

  • データベース バックアップとページ復元を同時に実行することはできません。

一括ログ復旧モデルとページ復元

データベースで一括ログ復旧モデルを使用している場合、ページ復元には次の追加条件があります。

  • オフライン データはログに記録されないため、ファイル グループまたはページのデータがオフラインであるときにバックアップを行うと、一括ログ データで問題が発生します。オフライン ページが原因で、ログのバックアップが失敗する可能性があります。この場合、最新のバックアップへの復元を実行する場合よりもデータ損失の可能性が低い、DBCC REPAIR の使用を検討します。

  • 一括ログ データベースのログ バックアップで不正なページが検出された場合は、WITH CONTINUE_AFTER_ERROR が指定されていないと失敗します。

  • ページ復元は、一般的に一括ログ復旧では使用できません。

    ページ復元の実行で推奨されるのは、データベースを完全復旧モデルに設定し、ログ バックアップを試行する方法です。ログ バックアップが成功した場合は、ページ復元を開始できます。ログ バックアップが失敗した場合は、前回のログ バックアップ以降の作業をあきらめるか、REPAIR_ALLOW_DATA_LOSS オプションを指定して DBCC を実行してみる必要があります。

ページ復元の基本的な構文

RESTORE DATABASE ステートメントでページを指定するには、ページを含むファイルのファイル ID とページのページ ID が必要です。必須の構文は次のとおりです。

RESTORE DATABASE database_name

   PAGE ='file:page [ ,...n ]' [ ,...n ]

   FROM <backup_device> [ ,...n ]

WITH NORECOVERY

PAGE オプションのパラメータの詳細については、「RESTORE の引数 (Transact-SQL)」を参照してください。RESTORE DATABASE の構文の詳細については、「RESTORE (Transact-SQL)」を参照してください。

ページ復元の手順

ページ復元の基本的な手順は次のとおりです。

  1. 復元する損傷したページのページ ID を取得します。チェックサムまたは破損した書き込みのエラーによってページ ID が返され、ページを指定するために必要な情報が提供されます。損傷したページのページ ID を検索するには、次のいずれかのソースを使用します。

    ページ ID のソース

    トピック

    msdb..suspect_pages

    suspect_pages テーブルの理解と管理

    エラー ログ

    SQL Server エラー ログの表示

    イベント トレース

    イベントの監視

    DBCC

    DBCC (Transact-SQL)

    WMI プロバイダ

    WMI Provider for Server Events の概念

  2. 損傷したページが含まれている、データベースの完全バックアップ、ファイル バックアップ、またはファイル グループ バックアップを使用して、ページ復元を開始します。RESTORE DATABASE ステートメントで PAGE 句を使用して、復元する全ページのページ ID の一覧を指定します。

    PAGE ='file:page [ ,...n ]'

  3. 最新の差分バックアップを適用します。

  4. 後続のログ バックアップを適用します。

  5. 復元されたページの最終 LSN を含むデータベースの新しいログ バックアップ (最後に復元されたページがオフラインになった時点までのログ バックアップ) を作成します。この最終 LSN が、再実行ターゲット LSN になります。最終 LSN は、復元シーケンス内の最初の復元の一環として設定されます。損傷したページを含むファイルのオンラインのロールフォワードは、再実行ターゲット LSN で停止することができます。ファイルの現在の再実行ターゲット LSN は、sys.master_filesredo_target_lsn 列で確認できます。詳細については、「sys.master_files (Transact-SQL)」を参照してください。

  6. 新しいログ バックアップを復元します。この新しいログ バックアップを適用すると、ページ復元が完了し、ページが使用可能な状態になります。

注意

この復元シーケンスは、ファイル復元シーケンスと似ています。実際、ページ復元とファイル復元は、どちらも同じ復元シーケンスで実行することができます。

次の例では、NORECOVERY を指定して、ファイル B の 4 つの損傷したページを復元します。次に、NORECOVERY を使用して 2 つのログ バックアップを適用してから、RECOVERY を使用してログ末尾のバックアップを復元します。

重要な注意事項重要

破れたページにデータベースの重要なメタデータが格納されている場合、オフライン ページ復元シーケンスを実行する必要が生じる場合があります。オフライン復元を実行するには、WITH NORECOVERY を指定してトランザクション ログをバックアップする必要があります。

次の例では、オンライン復元を実行します。この例では、ファイル B のファイル ID が 1 で、損傷したページのページ ID は 57、202、916、および 1016 です。

RESTORE DATABASE <database> PAGE='1:57, 1:202, 1:916, 1:1016'
   FROM <file_backup_of_file_B> 
   WITH NORECOVERY;
RESTORE LOG <database> FROM <log_backup> 
   WITH NORECOVERY;
RESTORE LOG <database> FROM <log_backup> 
   WITH NORECOVERY; 
BACKUP LOG <database> TO <new_log_backup> 
RESTORE LOG <database> FROM <new_log_backup> WITH RECOVERY;
GO

RESTORE DATABASE <database> PAGE='1:57, 1:202, 1:916, 1:1016'
   FROM <file_backup_of_file_B> 
   WITH NORECOVERY;
RESTORE LOG <database> FROM <log_backup> 
   WITH NORECOVERY;
RESTORE LOG <database> FROM <log_backup> 
   WITH NORECOVERY; 
BACKUP LOG <database> TO <new_log_backup> 
RESTORE LOG <database> FROM <new_log_backup> WITH RECOVERY;
GO