行のバージョン管理用リソースの使用状況
行のバージョン管理フレームワークでは、SQL Server で使用可能な次の機能がサポートされます。
トリガ
複数のアクティブな結果セット (MARS)
オンラインのインデックス構築
また、行のバージョン管理フレームワークでは、次に示すように、行のバージョン管理に基づいたトランザクション分離レベルもサポートされます。このレベルは既定では無効になっています。
READ_COMMITTED_SNAPSHOT データベース オプションが ON になっている場合、READ_COMMITTED トランザクションで行のバージョン管理を行うことにより、ステートメント レベルでの読み取り操作を一貫性を保った状態で実行できます。
ALLOW_SNAPSHOT_ISOLATION データベース オプションが ON になっている場合、SNAPSHOT トランザクションで行のバージョン管理を行うことにより、トランザクション レベルでの読み取り操作を一貫性を保った状態で実行できます。
行のバージョン管理に基づく分離レベルを使用すると、読み取り操作での共有ロックが排除され、トランザクションから取得するロック数が減少します。その結果、ロックの管理に使用するリソースを節約できるので、システムのパフォーマンスが向上します。また、他のトランザクションから取得したロックによりトランザクションがブロックされる回数が減少することも、パフォーマンスが向上する要因です。
行のバージョン管理に基づいて分離レベルを使用すると、データの変更に必要なリソースが増加します。これらのオプションを有効にすると、データベースに対するすべてのデータ変更がバージョン管理されます。行のバージョン管理に基づく分離を使用したアクティブなトランザクションが存在しない場合でも、変更前のデータのコピーは tempdb に格納されます。変更後のデータには、tempdb に格納されたバージョン管理されるデータへのポインタが含まれます。ラージ オブジェクトの場合は、変更されたオブジェクトだけが tempdb にコピーされます。
tempdb で使用される領域
データベース エンジンの各インスタンスの tempdb には、インスタンス内の各データベースで生成される行バージョンを保持できるだけの十分な領域が必要です。データベース管理者は、バージョン ストアをサポートできるだけの十分な領域を tempdb 内に確保する必要があります。tempdb には次に示す 2 つのバージョン ストアがあります。
オンライン インデックス構築用のバージョン ストアは、すべてのデータベースのオンラインのインデックス構築操作に使用されます。
共通バージョン ストアは、すべてのデータベース内のその他すべてのデータ変更操作に使用されます。
アクティブなトランザクションで行バージョンにアクセスする必要がある限り、その行バージョンを格納しておく必要があります。1 分ごとに、バックグラウンドのスレッドによって、不要になった行バージョンが削除され、tempdb 内のバージョン領域が解放されます。次の条件のいずれかに該当する場合、実行時間の長いトランザクションにより、バージョン ストアの領域の解放が妨げられます。
トランザクションで、行のバージョン管理に基づく分離が使用されています。
トランザクションで、トリガ、MARS、またはオンラインのインデックス構築のいずれかの操作が使用されています。
トランザクションで、行バージョンが生成されます。
注意 |
---|
トランザクションの内部でトリガが呼び出されるときに、トリガによって作成される行バージョンは、トリガの完了後に不要になる行バージョンであっても、トランザクションの終了時まで保持されます。これは、行のバージョン管理を使用する READ COMMITTED トランザクションにも適用されます。この種類のトランザクションを使用すると、トランザクション内の各ステートメントに対してだけ、トランザクション全体で一貫性のあるデータベース ビューが必要です。つまり、トランザクションでステートメントに対して作成される行バージョンは、ステートメントが完了した後には不要になります。ただし、トランザクションで各ステートメントによって作成される行バージョンは、トランザクションが完了するまで保持されます。 |
tempdb の領域が不足すると、データベース エンジンによって強制的にバージョン ストアが圧縮されます。圧縮処理では、行バージョンをまだ生成していないトランザクションのうち、実行時間が最も長いトランザクションが圧縮対象になります。圧縮対象のトランザクションごとに、メッセージ 3967 がエラー ログに記録されます。あるトランザクションが圧縮の対象として設定されると、そのトランザクションではバージョン ストア内の行バージョンを読み取れなくなります。そのトランザクションから行バージョンを読み取ろうとすると、メッセージ 3966 が生成され、そのトランザクションはロールバックされます。圧縮処理が成功すると、tempdb に使用可能な領域が生成されます。失敗した場合は、tempdb の領域が不足し、次のいずれかの現象が発生します。
書き込み操作が続行および実行されますが、バージョンが生成されません。情報提供用メッセージ (3959) がエラー ログに記録されますが、データを書き込むトランザクションは影響を受けません。
tempdb 全体がロールバックされたために生成されなかった行バージョンにアクセスを試みるトランザクションが、エラー 3958 で終了します。
データ行で使用される領域
各データベース行では、行の終わりの最大 14 バイトを行のバージョン管理情報用に使用する場合があります。行のバージョン管理情報には、そのバージョンでコミットしたトランザクションのトランザクション シーケンス番号と、バージョン管理される行へのポインタが含まれています。次に示す条件のいずれかに該当する場合、行が最初に変更されたとき、または新しい行が追加されたときに、この 14 バイトが追加されます。
READ_COMMITTED_SNAPSHOT オプションまたは ALLOW_SNAPSHOT_ISOLATION オプションが ON になっています。
テーブルにトリガが含まれています。
複数のアクティブな結果セット (MARS) が使用されています。
オンラインのインデックス構築操作が、現在そのテーブルで実行されています。
次のすべての条件に該当する状況で最初に行が変更されたときに、そのデータベース行からこの 14 バイトが削除されます。
READ_COMMITTED_SNAPSHOT オプションと ALLOW_SNAPSHOT_ISOLATION オプションが OFF になっています。
テーブルに既にトリガが存在しません。
MARS が使用されていません。
オンラインのインデックス構築操作が現在実行されていません。
行のバージョン管理機能を使用する場合は、データベースに追加のディスク領域を割り当て、各データベース行で 14 バイトを使用できるようにする必要があります。行のバージョン管理用情報が追加された際に、現在のページ上に十分な空き領域がない場合、インデックス ページの分割や、新しいデータ ページの割り当てが発生します。たとえば、行の平均の長さが 100 バイトの場合は、14 バイト追加されると既存のテーブルが最大 14% 大きくなります。
FILL FACTOR を小さくすると、インデックス ページの断片化を防止または低減するのに役立ちます。テーブルまたはビューのデータとインデックスに関する断片化情報を表示するには、DBCC SHOWCONTIG を使用できます。
ラージ オブジェクトで使用される領域
SQL Server データベース エンジンでは、最大 2 GB の大きなサイズの文字列を保持できる 6 つのデータ型 (nvarchar(max)、varchar(max)、varbinary(max)、ntext、text、image) がサポートされます。これらのデータ型で格納されたサイズの大きな文字列は、データ行にリンクされている一連のデータ フラグメントに格納されます。行のバージョン管理情報は、これらの大きな文字列の格納に使用される各フラグメントに格納されます。データ フラグメントは、テーブル内のラージ オブジェクト専用のページのコレクションです。
新しい大きな値がデータベースに追加されたときに、データ フラグメントには、1 つのフラグメントにつき最大 8,040 バイトのデータが割り当てられます。以前のバージョンのデータベース エンジンでは、1 つのフラグメントにつき最大 8,080 バイトの ntext データ、text データ、または image データが格納されていました。
ntext 型、text 型、および image 型の既存のラージ オブジェクト (LOB) データは、データベースが以前のバージョンの SQL Server から SQL Server にアップグレードされても、行のバージョン管理情報用の領域を確保するために更新されることはありません。ただし、これらの LOB データが最初に変更されたときに、バージョン管理情報の領域を使用できるように動的にアップグレードされます。行のバージョンが生成されない場合でも、このアップグレードは行われます。LOB データがアップグレードされた後、1 フラグメントに格納されている最大バイト数が 8,080 バイトから 8,040 バイトに減少します。このアップグレード処理は、LOB 値を削除し、再度同じ値を挿入する処理に相当します。LOB データは、1 バイトしか変更されない場合にもアップグレードされます。このアップグレードは、ntext 型、text 型、または image 型の各列で 1 回だけ実行される操作ですが、LOB データのサイズによっては、大量のページが割り当てられたり、大量の I/O 処理が実行されたりする場合があります。また、変更が完全にログに記録される場合、ログ処理が膨大になる場合があります。WRITETEXT 操作および UPDATETEXT 操作を使用すると、データベースが完全復旧モードに設定されている場合、ログ記録を最小限に抑えることができます。
nvarchar(max)、varchar(max)、および varbinary(max) の各データ型は、以前のバージョンの SQL Server では使用できません。したがって、これらのデータ型についてはアップグレードの問題は発生しません。
この要件を満たすには、十分なディスク領域を割り当てる必要があります。
行のバージョン管理とバージョン ストアの監視
SQL Server では、パフォーマンスや問題について、行のバージョン管理、バージョン ストア、およびスナップショット分離のプロセスを監視するために、動的管理ビュー (DMV) と Windows システム モニタのパフォーマンス カウンタというツールが用意されています。
DMV
次に示す DMV からは、行のバージョン管理を使用しているトランザクションについての情報だけではなく、tempdb の現在のシステム状態とバージョン ストアについての情報が提供されます。
sys.dm_db_file_space_usage。データベース内のファイルごとに、領域の使用状況に関する情報を返します。詳細については、「sys.dm_db_file_space_usage (Transact-SQL)」を参照してください。
sys.dm_db_session_space_usage。データベースのセッション別に、ページの割り当てと割り当て解除の状態を返します。詳細については、「sys.dm_db_session_space_usage (Transact-SQL)」を参照してください。
sys.dm_db_task_space_usage。データベースのタスク別に、ページの割り当てと割り当て解除の状態を返します。詳細については、「sys.dm_db_task_space_usage (Transact-SQL)」を参照してください。
sys.dm_tran_top_version_generators。バージョン ストア内で最も高いバージョンを生成しているオブジェクトの仮想テーブルを返します。集計済みのレコード長について、長いものから順に 256 位までを database_id と rowset_id でグループ化しています。この関数を使用して、バージョン ストアを最も多く使用しているレコードを見つけます。詳細については、「sys.dm_tran_top_version_generators (Transact-SQL)」を参照してください。
sys.dm_tran_version_store。共通バージョン ストア内のすべてのバージョン レコードを表す仮想テーブルを返します。詳細については、「sys.dm_tran_version_store (Transact-SQL)」を参照してください。
注意 |
---|
sys.dm_tran_top_version_generators と sys.dm_tran_version_store では、非常に大きくなる可能性があるバージョン ストア全体に対してクエリが実行されるので、これらの関数を実行すると非常に多くのリソースが使用される可能性があります。 |
sys.dm_tran_active_snapshot_database_transactions。データベース内のすべてのアクティブなトランザクションを表す仮想テーブルを返します。行のバージョン管理を使用する SQL Server インスタンス内のすべてのデータベースが対象です。システム トランザクションは、この DMV には表示されません。詳細については、「sys.dm_tran_active_snapshot_database_transactions (Transact-SQL)」を参照してください。
sys.dm_tran_transactions_snapshot。トランザクションごとに作成されたスナップショットを表す仮想テーブルを返します。このスナップショットには、行のバージョン管理を使用するアクティブなトランザクションのシーケンス番号が含まれています。詳細については、「sys.dm_tran_transactions_snapshot (Transact-SQL)」を参照してください。
sys.dm_tran_current_transaction。現在のセッションにおけるトランザクションの行のバージョン管理に関係した状態情報を表す 1 行を返します。詳細については、「sys.dm_tran_current_transaction (Transact-SQL)」を参照してください。
sys.dm_tran_current_snapshot。現在のスナップショット分離トランザクションの開始時点でアクティブなすべてのトランザクションを表す仮想テーブルを返します。現在のトランザクションがスナップショット分離を使用している場合、この関数から行が返されません。sys.dm_tran_current_snapshot は、sys.dm_tran_transactions_snapshot と類似していますが、現在のスナップショットのアクティブなトランザクションだけを返す点が異なります。詳細については、「sys.dm_tran_current_snapshot (Transact-SQL)」を参照してください。
パフォーマンス カウンタ
SQL Server のパフォーマンス カウンタからは、SQL Server プロセスによって影響を受けるシステム パフォーマンスについての情報が提供されます。次に示すパフォーマンス カウンタでは、行のバージョン管理を使用しているトランザクションだけではなく、tempdb とそのバージョン ストアを監視します。パフォーマンス カウンタは SQLServer:Transactions パフォーマンス オブジェクトに含まれています。
Free Space in tempdb (KB)。tempdb データベース内の空き領域 (KB) を監視します。tempdb には、スナップショット分離をサポートするバージョン ストアを処理できるだけの十分な空き領域が必要です。
次の式を使用すると、バージョン ストアのサイズを概算することができます。実行時間の長いトランザクションの場合、生成率とクリーンアップ率を監視してバージョン ストアの最大サイズを推定すると有益な場合があります。
[共通バージョン ストアのサイズ] = 2 * [毎分生成されるバージョン ストア データ] * [トランザクションの最長実行時間 (分)]
実行時間が極端に長いトランザクションには、オンラインのインデックス構築操作を含めないでください。そのような場合のオンラインのインデックス構築操作は、非常に大きなテーブルでは時間がかかる場合があるので、別のバージョン ストアを使用します。オンライン インデックス構築用のバージョン ストアの大まかなサイズは、オンラインのインデックス構築がアクティブになっている間にテーブル内で変更されたデータ (すべてのインデックスを含む) の量と同じです。
Version Store Size (KB)。すべてのバージョン ストアのサイズを KB 単位で監視します。この情報は、tempdb データベースに必要なバージョン ストア用の領域のサイズを判定する際に役立ちます。このカウンタを長期間監視すると、tempdb に必要な領域を追加する際に役立つ推定値が得られます。
Version Generation rate (KB/s)。すべてのバージョン ストアについてバージョンの生成率 (KB/秒) を監視します。
Version Cleanup rate (KB/s)。すべてのバージョン ストアについてバージョンのクリーンアップ率 (KB/秒) を監視します。
注意 |
---|
Version Generation rate (KB/s) と Version Cleanup rate (KB/s) から得た情報を、tempdb に必要な領域の予測に利用できます。 |
Version Store unit count。バージョン ストア ユニットの数を監視します。
Version Store unit creation。インスタンスの開始以降に行バージョンを格納するために作成されたバージョン ストア ユニットの総数を監視します。
Version Store unit truncation。インスタンスの開始以降に切り捨てられたバージョン ストア ユニットの総数を監視します。バージョン ストア ユニットは、バージョン ストア内に格納されているバージョン行が SQL Server によりアクティブなトランザクションの実行に不要と判断された場合に切り捨てられます。
Update conflict ratio。更新スナップショット トランザクションの総数に対し、更新に関して競合が発生している更新スナップショット トランザクションの割合を監視します。
Longest Transaction Running Time。行のバージョン管理を使用しているトランザクションの最長実行時間 (秒) を監視します。このパフォーマンス カウンタを使用して、トランザクションの実行時間が不適切でないかどうかを判断できます。
Transactions。アクティブなトランザクションの総数を監視します。システム トランザクションは含まれません。
Snapshot Transactions。アクティブなスナップショット トランザクションの総数を監視します。
Update Snapshot Transactions。更新操作を実行するアクティブなスナップショット トランザクションの総数を監視します。
NonSnapshot Version Transactions。バージョン レコードを生成する、スナップショット以外のアクティブなトランザクションの総数を監視します。
注意 |
---|
Update Snapshot Transactions と NonSnapshot Version Transactions の合計は、バージョンの生成に関係するトランザクションの総数を表します。Snapshot Transactions と Update Snapshot Transactions の差分は、読み取り専用のトランザクション数を表します。 |