次の方法で共有


メモリ最適化テーブルの持続性

適用対象:SQL Server

インメモリ OLTP により、メモリ最適化テーブルには完全な持続性が提供されます。 メモリ最適化テーブルを変更したトランザクションがコミットされると、SQL Server (ディスク ベース のテーブルの場合と同様) は、基になるストレージが使用可能な場合に限り、変更が永続的 (データベースの再起動後も存続する) ことを保証します。 持続性には、トランザクション ログとディスク上ストレージでのデータ変更の保持という、2 つの主なコンポーネントがあります。

永続テーブルのサイズ制限の詳細については、「 Memory-Optimized テーブルのメモリ要件の見積もり」を参照してください。

トランザクション ログ

ディスク ベース テーブルまたは持続性のあるメモリ最適化テーブルに対するすべての変更は、1 つ以上のトランザクション ログ レコードにキャプチャされます。 トランザクションのコミット時に、SQL Server は、トランザクションに関連付けられているログ レコードをディスクに書き込んだ後、トランザクションによってコミットされたアプリケーションまたはユーザー セッションと通信します。 これにより、トランザクションによる変更が持続可能であることが保証されます。 メモリ最適化テーブルのトランザクション ログは、ディスク ベース テーブルで使用されている同じログ ストリームと完全に統合されています。 この統合により、既存のトランザクション ログのバックアップ、回復、復元の操作は、追加の手順を必要とせずに引き続き機能します。 ただし、In-Memory OLTP はワークロードのトランザクション スループットを大幅に向上させる可能性があるため、ログ IO がパフォーマンスのボトルネックになる可能性があります。 このスループットの向上を維持するには、ログ IO サブシステムが負荷の増大に対応できることをご確認ください。

データ ファイルとデルタ ファイル

メモリ最適化テーブルのデータは、自由形式のデータ行としてインメモリ ヒープ データ構造で格納され、メモリ内の 1 つ以上のインデックスでリンクされます。 ディスク ベース テーブルで使用されるような、データ行のページ構造はありません。 長期間にわたって永続化するため、およびトランザクション ログを切り捨てることができるようにするため、メモリ最適化テーブルに対する操作は、一連のデータ ファイルとデルタ ファイルに保存されます。 これらのファイルは、非同期のバック グラウンド プロセスを使用して、トランザクション ログに基づいて生成されます。 データ ファイルとデルタ ファイルは 1 つ以上のコンテナーにあります (FILESTREAM データで使用される同様のメカニズムを使用しています)。 これらのコンテナーは、メモリ最適化ファイル グループの一部になります。

データはこれらのファイルに厳密な順次形式で書き込まれるため、スピン メディアの場合のディスク待機時間が最小限に抑えられます。 異なるディスクにある複数のコンテナーを使用して、I/O 動作を分散することもできます。 異なるディスク上の複数のコンテナー内のデータ ファイルとデルタ ファイルは、ディスク上のデータ ファイルと差分ファイルからメモリにデータを読み取るときに、データベースの復元/回復のパフォーマンスを向上させます。

ユーザー トランザクションは、データ ファイルとデルタ ファイルに直接アクセスしません。 すべてのデータ読み取りと書き込みには、インメモリ データ構造が使用されます。

データ ファイル

データ ファイルには、1 つ以上のメモリ最適化テーブルからの行が格納されます。これらの行は、INSERT 操作や UPDATE 操作の一部である複数のトランザクションによって挿入されたものです。 たとえば、ある行はメモリ最適化テーブル T1 から挿入され、次の行はメモリ最適化テーブル T2 から挿入されることがあります。 これらの行は、データ アクセスが順次的になるように、トランザクション ログ内のトランザクションの順序でデータ ファイルに追加されます。 これにより、ランダム I/O と比較した場合、I/O スループットが大幅に向上します。

データ ファイルがいっぱいになると、新しいトランザクションによって挿入される行は別のデータ ファイルに格納されます。 時間の経過と同時に、持続性のあるメモリ最適化テーブルの行は、さらに 1 つのデータ ファイルに格納され、行を含む各データ ファイルは、分離された連続したトランザクション範囲を形成します。 たとえば、トランザクションのコミット タイムスタンプの範囲が (100, 200) であるデータ ファイルには、コミット タイムスタンプが 100 より大きく 200 以下のトランザクションによって挿入されたすべての行が含まれています。 コミット タイムスタンプは、コミットの準備ができたときにトランザクションに割り当てられる単調に増加する数です。 各トランザクションには、一意のコミット タイムスタンプが設定されます。

行が削除または更新されると、データ ファイル内の行はインプレースで削除または変更されませんが、削除された行は別の種類のファイル (デルタ ファイル) で追跡されます。 更新操作は、それぞれの行の削除操作と挿入操作の組み合わせとして処理されます。 これにより、データ ファイルでランダム IO が発生しないようになっています。

サイズ: 各データ ファイルのサイズは、16 GB を超えるメモリを搭載するコンピューターでは約 128 MB、16 GB 以下のメモリを搭載するコンピューターでは約 16 MB になります。 SQL Server 2016 (13.x) では、記憶域サブシステムが十分に高速と見なされる場合、SQL Server で大規模チェックポイント モードを使用できます。 大規模チェックポイント モードでは、データ ファイルのサイズは 1 GB になります。 この場合、高スループットのワークロードに関する記憶域サブシステムの効率を向上させることができます。

デルタ ファイル

各データ ファイルには、同じトランザクション範囲を持つデルタ ファイルが対応付けられています。デルタ ファイルは、そのトランザクション範囲のトランザクションによって挿入された削除済みの行を追跡します。 このデータとデルタ ファイルはチェックポイント ファイル ペア (CFP) と呼ばれ、割り当てと割り当て解除の単位とマージ操作の単位です。 たとえば、トランザクション範囲 (100,200) に対応するデルタ ファイルには、その範囲 (100, 200) のトランザクションによって挿入された削除された行が格納されます。 データ ファイルと同様に、デルタ ファイルは順次アクセスされます。

行が削除されると、行はデータ ファイルから削除されませんが、行への参照は、このデータ行が挿入されたトランザクション範囲に関連付けられているデルタ ファイルに追加されます。 削除対象のデータ行は既にデータ ファイルに存在するため、デルタ ファイルには参照情報 ( {inserting_tx_id, row_id, deleting_tx_id} ) が格納されるだけです。格納順序は、元の削除操作または更新操作のトランザクション ログの順序に従います。

サイズ: 各デルタ ファイルのサイズは、16 GB を超えるメモリを搭載するコンピューターでは約 16 MB、16 GB 以下のメモリを搭載するコンピューターでは約 1 MB になります。 SQL Server 2016 (13.x) 以降、記憶域サブシステムが十分に高速と見なされる場合、SQL Server で大規模チェックポイント モードを使用できます。 大規模チェックポイント モードでは、デルタ ファイルのサイズは 128 MB になります。

データ ファイルとデルタ ファイルを設定する

データ ファイルとデルタ ファイルへのデータの取り込みは、メモリ最適化テーブルに対するコミットされたトランザクションが生成したトランザクション ログ レコードに基づいて行われ、挿入された行や削除された行に関する情報が適切なデータ ファイルとデルタ ファイルに追加されます。 ディスク ベース テーブルでは、チェックポイントの完了時にデータやインデックス ページがランダム I/O でフラッシュされますが、これとは異なり、メモリ最適化テーブルの永続化は連続的なバックグラウンド操作によって行われます。 トランザクションでは、それ以前のいずれかのトランザクションによって挿入された任意の行が削除または更新されることがあるため、複数のデルタ ファイルへのアクセスが発生します。 削除情報は常にデルタ ファイルの末尾に追加されます。 たとえば、コミット タイムスタンプが 600 のトランザクションでは、次の図に示すように、1 つの新しい行が挿入され、コミット タイムスタンプが 150、250、450 のトランザクションによって挿入された行が削除されます。 4 つのファイル I/O 操作 (削除された行の場合は 3 つ、新しく挿入された行の場合は 1) はすべて、対応するデルタ ファイルとデータ ファイルへの追加専用操作です。

メモリ最適化テーブルの読み取りログ レコードのスクリーンショット。

データ ファイルとデルタ ファイルにアクセスする

データとデルタ ファイルのペアは、次のイベントが発生するとアクセスされます。

オフライン チェックポイント ワーカー

このスレッドでは、メモリ最適化データ行に対する挿入と削除を、対応するデータ ファイルとデルタ ファイルのペアに追加します。 SQL Server 2014 (12.x) には、1 つのオフライン チェックポイント ワーカーがあります。 SQL Server 2016 (13.x) 以降のバージョンには、複数のチェックポイント ワーカーがあります。

マージ操作

この操作では、1 つ以上のデータ ファイルとデルタ ファイルのペアをマージして、新しいデータ ファイルとデルタ ファイルのペアを作成します。

クラッシュ後の復旧の処理中

SQL Server を再起動するか、データベースがオンラインに戻ると、データ ファイルとデルタ ファイルのペアを使用してメモリ最適化データが取り込まれます。 デルタ ファイルは、対応するデータ ファイルから行を読み取るときに、削除された行のフィルターとして機能します。 データ ファイルとデルタ ファイルのペアは独立しているため、データをメモリに取り込む時間を削減するために、これらのファイルは並列処理で読み込まれます。 データがメモリに読み込まれると、In-Memory OLTP エンジンは、メモリ最適化データが完了するように、チェックポイント ファイルではまだカバーされていないアクティブなトランザクション ログ レコードを適用します。

復元操作の処理中

インメモリ OLTP のチェックポイント ファイルはデータベースのバックアップから作成され、1 つ以上のトランザクション ログ バックアップが適用されます。 クラッシュ復旧と同様に、In-Memory OLTP エンジンは、復旧時間への影響を最小限に抑えるために、データを並列でメモリに読み込みます。

データ ファイルとデルタ ファイルをマージする

メモリ最適化テーブルのデータは、1 つ以上のデータ ファイルとデルタ ファイルのペア (チェックポイント ファイル ペアまたは CFP とも呼ばれます) に格納されます。 データ ファイルは挿入された行を格納し、デルタ ファイルは削除された行を参照します。 OLTP ワークロードの実行中、DML 操作によって行が更新、挿入、および削除されると、新しい行を保存するために新しい CFP が作成され、削除された行への参照がデルタ ファイルに追加されます。

時間の経過と共に、DML 操作では、データ ファイルとデルタ ファイルの数が増加し、ディスク領域の使用量が増加し、回復時間が長くなります。

このような非効率性を防ぐために、この記事で後述するマージ ポリシーに基づいて、古い閉じたデータファイルとデルタ ファイルがマージされるため、ストレージ アレイは同じデータ セットを表すように圧縮され、ファイルの数が少なくなります。

マージ操作は、内部定義のマージ ポリシーに基づくデータ ファイルとデルタ ファイル (マージ ソースと呼ばれる) のペアである 1 つ以上の隣接する閉じたチェックポイント ファイル ペア (CFP) を入力として受け取り、マージ ターゲットと呼ばれる 1 つの結果 CFP を生成します。 ソース CFP の各デルタ ファイル内のエントリは、対応するデータ ファイルから行をフィルター処理して、不要なデータ行を削除するために使用されます。 ソース CFP の残りの行は、1 つのターゲット CPF に統合されます。 マージが完了すると、結果のマージ ターゲット CFP によってソース CFP (マージ ソース) が置き換えられます。 マージ ソースの CFP は、ストレージから削除される前に移行フェーズを経ています。

次の例では、メモリ最適化テーブル ファイル グループのタイムスタンプ 500 に、以前のトランザクションのデータを含む 4 つのデータ とデルタ ファイルのペアがあります。 たとえば、最初のデータ ファイルの行は、100 より大きく 200 以下のタイムスタンプを持つトランザクションに対応します。この範囲は (100, 200] と表すこともできます。 2 番目と 3 番目のデータ ファイルは、削除済みとしてマークされている行を考慮すると、入力率が 50% 未満になっています。 これらの 2 つの CFP をマージ操作で結合し、タイムスタンプが 200 より大きく 400 以下 (2 つのファイルの結合範囲) のトランザクションを含む新しい CFP を作成します。 すると、範囲が (500, 600] のもう 1 つの CFP と、トランザクション範囲が (200, 400] の空でないデルタ ファイルが現れます。これは、マージ操作と同時に、ソース CFP から他の行を削除するといったトランザクション アクティビティを実行できることを示しています。

図は、メモリ最適化テーブル ファイル グループを示しています。

バックグラウンド スレッドでは、閉じているすべての CFP がマージ ポリシーを使用して評価され、該当する CFP に対して 1 つ以上のマージ要求が開始されます。 これらのマージ要求は、オフライン チェックポイント スレッドによって処理されます。 マージ ポリシーの評価は定期的に実行され、チェックポイントが閉じられるときにも行われます。

SQL Server マージ ポリシー

SQL Server には、次のマージ ポリシーが実装されています。

  • 削除された行を考慮した後、2 つ以上の連続する CFP を統合できる場合は、マージがスケジュールされます。これにより、結果の行はターゲット サイズの 1 つの CFP に収まります。 前に説明したように、データ ファイルとデルタ ファイルのターゲット サイズは元のサイズに対応します。

  • データ ファイルが目標サイズの 2 倍を上回っており、半分以上の行が削除済みの場合は、単一の CFP を自己マージすることができます。 1 つのトランザクションや複数の同時実行トランザクションが大量のデータを挿入または更新する場合など、データファイルはターゲットサイズよりも大きくなる可能性があります。これは、トランザクションが複数の CFP にまたがることができないため、データファイルがターゲットサイズを超えて拡張されるのが原因です。

マージ ポリシーの下でマージする CFP を示す例を次に示します。

隣接する CFP ソース ファイル (% がいっぱい) マージの選択
CFP0 (30%)、CFP1 (50%)、CFP2 (50%)、CFP3 (90%) (CFP0、CFP1)

CFP2 は、結果のデータ ファイルが理想的なサイズの 100% を超えるので選択されません。
CFP0 (30%)、CFP1 (20%)、CFP2 (50%)、CFP3 (10%) (CFP0、CFP1、CFP2)。 ファイルは左から選択されます。

CFP3 は、結果のデータ ファイルが理想的なサイズの 100% を超えるので選択されません。
CFP0 (80%)、CFP1 (30%)、CFP2 (10%)、CFP3 (40%) (CFP1、CFP2、CFP3)。 ファイルは左から選択されます。

CFP0 はスキップされます。CFP1 と組み合わせると、結果のデータ ファイルは理想的なサイズの 100% を超えるためです。

空き領域のある CFP がすべてマージに適合するとは限りません。 たとえば、隣接する 2 つの CFP が 60% 満杯の場合、それらの CFP はマージの対象になりません。また、これらの CFP には 40 個の% ストレージが使用されていません。 最悪の場合、すべての CFP が 50% の容量で満たされており、ストレージの使用率は50%に過ぎません。 CFP がマージの対象となっていないため、削除された行がストレージに存在する可能性はありますが、削除された行はメモリ内ガベージ コレクションによって既にメモリから削除されている可能性があります。 ストレージとメモリの管理は、ガベージ コレクションから独立しています。 アクティブな CFP によって取得されたストレージ (すべての CFP が更新されるわけではありません) は、メモリ内の永続テーブルのサイズの最大 2 倍に大きくなる可能性があります。

CFP のライフ サイクル

CFP は、割り当てが解除されるまでにいくつかの状態を遷移します。 フェーズを辿ってファイルを遷移し、必要なくなったファイルを最終的にクリーンアップするには、データベースのチェックポイントとログのバックアップが必要です。 これらのフェーズの詳細については、 sys.dm_db_xtp_checkpoint_filesを参照してください。

チェックポイントとその後のログのバックアップを手動で強制的に実行し、ガベージ コレクションを早めることができます。 運用環境のシナリオでは、バックアップ戦略の一環として作成された自動チェックポイントとログ バックアップによって、手動による介入を必要とせずに、これらのフェーズを通じて CFP がシームレスに移行されます。 ガベージ コレクション プロセスの効果は、メモリ最適化テーブルを持つデータベースのストレージ サイズがメモリ内のサイズと比較して大きくなる可能性があるということです。 チェックポイントとログのバックアップが行われなければ、チェックポイント ファイルのディスク上のフットプリントは増え続けます。