SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

メモリ最適化 tempdb メタデータについて (CTP 3.0 時点の動作)

leave a comment

SQL Server 2019 CTP 3.0 から、tempdb のメタデータをメモリ最適化テーブルを使用することができるようになりました。

Hekatonized Tempdb と呼んでいる方もいるようですね。

この機能は In-Memory OLTP (Hekaton) の機能を tempdb のメタデータに適用したものとなります。
従来までの tempdb の最適化としては、次のドキュメントの情報が公開されていました。

SQL Server 2016 以降はインストール時に tempdb のデータファイルの分割が CPU コア数に応じて行われるようになり、初期状態でも最適化がされた状態で導入されるようになりました。
tempdb の分割や ?T1118 を使用することで SGAM (シェアードグローバルアロケーションマップ) や、PFS? (ページフリースペース) の競合頻度を抑えることができ、同時実行性を向上させるというような効果がありました。
これらの同時実行性向上のための最適化を実施しても tempdb の競合には課題となるものが残っていました。
その中の一つが「メタデータの競合」となります。
tempdb に一時テーブルを頻繁に作成するような処理が多い場合、システムテーブルにメタデータを書き込む際に競合が発生することがありました。
一時テーブルを作成する場合には、テーブルのオブジェクト情報をシステムテーブル内に登録する必要があります。
その際にはテーブルの情報や、一時テーブルにインデックスを設定している場合は、インデックス情報についても格納をする必要がありました。
単一のセッションで実行している場合には、問題はないのですが、複数のセッションで一時テーブルを頻繁に作成する場合などは、オブジェクト情報を登録しているテーブルのページラッチ (ページヘッダーの書き換え等による待ち)による競合が発生するケースがあります。
例として、次のようなクエリを複数セッションで実行した場合を考えてみたいと思います。


DROP TABLE IF EXISTS #T1
CREATE TABLE #T1(
	C1 int NOT NULL PRIMARY KEY CLUSTERED,
	C2 int,
	C3 uniqueidentifier ROWGUIDCOL UNIQUE NONCLUSTERED
)
INSERT INTO #T1 VALUES
(1, RAND() * 100, NEWID()),
(2, RAND() * 100, NEWID()),
(3, RAND() * 100, NEWID()),
(4, RAND() * 100, NEWID())

 
インデックスが付与されている一時テーブルを作成し、データを投入するというシンプルなものです。
これを複数セッションで実行するとどのような待ちが発生するかというと、次のようなものが発生します。
image
具体的には次の 2 種類のシステムテーブルに対してページラッチの強豪が発生します。

  • sysallocunits
  • syschobjs

テーブルの作成やデータの投入によって、システムテーブルの情報を更新する際にページ内の書き換えをシリアル化するために待ちが発生している状態ですね。
このような待ちについてはデータファイルを追加することでも緩和させることができませんでした。
これに対してのチャレンジが SQL Server 2019 で追加される「メモリ最適化 tempdb メタデータ」となります。
SQL Server の In-Memory OLTP である、メモリ最適化テーブルのメリットとして「ロックフリー / ラッチフリー」があります。
tempdb のメタデータの書き換えでページラッチが発生するのであれば、メモリ最適化テーブルのメリットを活かすことで、競合を回避できるのではないかという考え方ですね。
設定の確認や有効化 / 無効化については次のようなクエリで制御を行うことができます。
(デフォルトは無効です)

SELECT * FROM sys.configurations where name ='tempdb metadata memory-optimized'
ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON
ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = OFF

 
それでは「TEMPDB_METADATA = ON 」を実行して有効にして動作を確認してみたいと思います。
(設定の変更を適用するためには、SQL Server のサービスの再起動が必要となります)
先ほどと同じクエリを実行して情報を取得した際の結果が次の画像となります。
image
設定を変更する前は、

  • sysallocunits
  • syschobjs

の 2 種類のシステムテーブルに対してのページラッチの競合が発生していました。
設定を有効化することによって競合が発生しているテーブルが、

  • sysallocunits

のみとなり、「syschobjs」の競合が発生しなくなっていますね。
これが tempdb のメタデータにメモリ最適化テーブルにした効果です。
CTP 3.0 時点では、メタデータを取り扱う、すべてのシステムテーブルがメモリ最適化テーブルとして設定されるのではなく、次のシステムテーブルのみがメモリ最適化テーブルとして設定されているようです。
(対象となっているシステムテーブルは CTP 3.0 時点のものですので、今後の Preview / RTM した場合には対象が変わっているかもしれません)

  • sysschobjs
  • syscolpars
  • sysidxstats
  • sysiscols
  • sysobjvalues
  • syssingleobjrefs
  • sysmultiobjrefs
  • sysrscols

設定を ON にすることで、「sysschobjs」のページラッチの競合が解消されていましたが、このシステムテーブルは、メモリ最適化テーブル化された対象となっていますね。
上述のシステムテーブルの競合が発生している場合は、メモリ最適化 tempdb メタデータを利用する効果が出てきそうですね。

Share

Written by Masayuki.Ozawa

6月 19th, 2019 at 12:34 am

Posted in SQL Server

Tagged with ,

Leave a Reply