データベース スナップショットの機能

データベース スナップショットは、スナップショットの作成時点におけるソース データベースからコミットされていないトランザクションを除去した状態を、読み取り専用の静的ビューとして表現したものです。スナップショットの作成後、データベース エンジンにより復旧が実行されるため、新しく作成したデータベース スナップショットではコミットされていないトランザクションがロールバックされます (データベース内のトランザクションは影響を受けません)。

データベース スナップショットはソース データベースに依存します。データベースのスナップショットは、データベースと同じサーバー インスタンス上に格納する必要があります。さらに、データベースがなんらかの理由で使用できなくなった場合、データベース スナップショットもすべて使用できなくなります。

スナップショットはレポート生成に使用できます。また、ソース データベースでユーザー エラーが発生したときは、スナップショット作成時の状態にソース データベースを戻すことができます。この場合、そのスナップショットの作成後に更新したデータベース データのみが失われることになります。また、スキーマやテーブルの構造を変更する場合など、データベースを大幅に変更する直前にデータベース スナップショットを作成すると便利です。スナップショットの使用方法の詳細については、「データベース スナップショットの一般的な使用方法」を参照してください。

スナップショットのしくみは、スナップショットを使用するうえで必須の知識ではありませんが、理解しておくと便利です。データベース スナップショットは、データページ レベルで動作します。ソース データベースのページをユーザーが初めて変更する前に、元のページがソース データベースからスナップショットにコピーされます。このプロセスを、書き込み時コピー処理といいます。スナップショットには元のページが格納され、スナップショットの作成時点におけるデータ レコードの状態が保持されます。それ以降、ページが変更され、レコードが更新されても、スナップショットの内容には影響しません。初めて変更する各ページについて、同様の処理が繰り返されます。このようにして、変更するすべてのデータ レコードについて元のページのスナップショットが作成され、変更前の状態が保持されます。

コピーされた元のページを格納するために、スナップショットではスパース ファイルが使用されます。スパース ファイルの最初の状態は、ユーザー データを一切含まず、ユーザー データ用のディスク領域も割り当てられていない空のファイルです。スパース ファイルのサイズは、ソース データベースで更新されるページ数が増えるにつれて大きくなります。スナップショットが作成されても、スパース ファイルはディスク領域をほとんど消費しません。ただし、スパース ファイルは、データベースの更新に伴って非常に大きなファイルになる可能性があります。スパース ファイルの詳細については、「データベース スナップショットのスパース ファイルのサイズについて」を参照してください。

次の図は、書き込み時コピー処理を示しています。スナップショット ダイアグラムの薄い灰色の長方形は、スパース ファイル内の未割り当て領域を表しています。ソース データベースのページに対する最初の更新を受け取った時点で、データベース エンジンはスパース ファイルに書き込みを行います。同時にオペレーティング システムは、スナップショットのスパース ファイルに領域を割り当て、元のページをその領域にコピーします。次に、データベース エンジンは、ソース データベースのページを更新します。次の図は、このような書き込み時コピー処理を示しています。

ページが更新された後のスナップショットの読み取り操作

重要な注意事項重要

データベース スナップショットは冗長ストレージではないため、ディスク エラーやその他の種類の破損から保護されません。データベースの保護には、定期的なバックアップと復元プランのテストが欠かせません。データベース スナップショットを作成した時点の状態にソース データベースを復元する必要がある場合は、そのためのバックアップ ポリシーを実装してください。

データベース スナップショットに対する読み取り操作

データベース スナップショットに対する読み取り操作では、その格納場所にかかわらず、常に元のデータ ページにアクセスすることになります。したがって、データベース スナップショットはユーザーには不変なものとして映ります。

ページがソース データベースでまだ更新されていない場合、スナップショットに対する読み取り操作では、元のページがソース データベースから読み取られます。次の図は、新しく作成されたスナップショットに対する読み取り操作を示しています。当然、このスナップショットのスパース ファイルにはページが一切含まれていません。この読み取り操作では、ソース データベースからのみ読み取りが行われます。

最初のページがスナップショットにコピーされる前の読み取り操作

ページが更新された後も、スナップショットに対する読み取り操作ではやはり元のページにアクセスします。ただし、この時点では、元のページがスパース ファイルに格納されています。次の図は、ソース データベースで更新された後のページにアクセスする読み取り操作を示しています。この読み取り操作では、スナップショットのスパース ファイルから元のページが読み取られます。

書き込み時コピー (Copy On Write) 操作

更新パターンがデータベース スナップショットの拡大に与える影響

ソース データベースのサイズがかなり大きくなっており、ディスク領域の使用状況が気にかかる場合は、ある時点で古いスナップショットを新しいスナップショットで置き換える必要があります。スナップショットの理想的な有効期間は、スナップショットの拡大速度とスパース ファイルの空きディスク領域のサイズによって異なります。一方、スナップショットに必要なディスク領域のサイズは、スナップショットの有効期間中にソース データベースで更新されるページの数によって決まります。したがって、繰り返し更新される一部のページだけに更新が集中している場合、スナップショットの拡大速度は徐々に下がり、スナップショットに必要なディスク領域のサイズは比較的小さいままとなります。それとは対照的に、すべての元のページが少なくとも一度は更新される場合、スナップショットはソース データベースのサイズまで大きくなります。ディスクの空き領域が少なくなった場合、スナップショットがディスク領域を求めて互いに競争し合うようになります。そして、ディスク ドライブの空きがなくなると、どのスナップショットに対する書き込み操作も失敗します。

注意注意

スナップショットの実際のサイズと最大可能サイズを調べる方法については、「データベース スナップショットのスパース ファイルのサイズについて」を参照してください。

このように、スナップショットの予定有効期間にどのぐらいの領域が必要となるかを予測する場合は、データベースの典型的な更新パターンを把握しておくと効果的です。データベースの種類 (ページの大半が毎日更新される在庫データベースなど) によっては、更新頻度がかなり高くなる場合があるので、古いスナップショットを毎日または毎週置き換える必要があります。また、更新されるページ数の比率がビジネス サイクル中に変動するデータベース (主に四半期ごとに更新され、それ以外の時期は不定期に更新されるカタログ データベースなど) の場合は、四半期ごとの更新の直前と直後にスナップショットを作成すると賢明です。この場合、更新前のスナップショットは重大な更新エラーが発生した場合の復元を可能にし、更新後のスナップショットは翌四半期におけるレポート作成に役立てることができます。

次の図は、2 つの対照的な更新パターンがスナップショットのサイズにどのような影響を与えるかを示しています。更新パターン A は、スナップショットの有効期間に元のページの 30% しか更新されない環境を反映し、更新パターン B は、スナップショットの有効期間に元のページの 80% が更新される環境を反映しています。

更新の代替パターンとスナップショットのサイズ

データベース スナップショットに関するメタデータ

データベース スナップショットの場合、データベース メタデータには、sys.databases カタログ ビューの列に格納される source_database_id プロパティが含まれています。このプロパティの詳細については、「sys.databases (Transact-SQL)」を参照してください。

通常、データベース スナップショットは、それ自体のメタデータは公開しませんが、ソース データベースからのメタデータは公開します。このメタデータには、次のステートメントによって返されるデータなどが含まれています。

USE <database_snapshot> SELECT * FROM sys.database_files 

ここで、<database_snapshot>はデータベース スナップショットの名前です。

ただし、ソース データベースでフルテキスト検索またはデータベース ミラーリングが使用されるときは例外です。この場合、スナップショットに対するフルテキスト検索またはデータベース ミラーリングは、スナップショットのメタデータで一部の値を変更することによって無効化されます。