適用対象:Linux 上の SQL Server
この記事では、mssql-confメモリ制限、制御グループ (cgroup) 設定、Docker コンテナー メモリの例、スワップ領域に関する考慮事項など、SQL Server on Linuxのメモリ構成について説明します。
Note
ストレージ、カーネル、CPU、およびネットワークに関する推奨事項については、「パフォーマンスのベスト プラクティス: SQL Server on Linuxのストレージ、カーネル、CPU、およびネットワーク」を参照してください。
mssql-conf を使用してメモリ制限を設定する
Linux オペレーティング システムに十分な空き物理メモリがあることを確認するために、SQL Server プロセスでは既定で物理 RAM の 80% のみが使用されます。 物理 RAM の量が多いシステムによっては、20% が大きな数になる場合があります。 たとえば、RAM が 1 TB のシステムでは、既定の設定では約 200 GB の RAM が使用されません。 このような状況では、メモリの制限をより大きな値に構成することができます。
この値は、 mssql-conf ツールまたは MSSQL_MEMORY_LIMIT_MB 環境変数を使用して調整できます。 詳細については、SQL Server に表示されるメモリを制御する memory.memorylimitmb 設定 (MB 単位) を参照してください。 サイズ設定の詳細なガイダンスについては、 Linux とコンテナーでのメモリ制限の設定に関するガイドラインを参照してください。
コントロール グループ (cgroup) v2 のサポート
SQL Serverは、SQL Server 2025 (17.x) および SQL Server 2022 (16.x) 累積更新プログラム (CU) 20 以降で、制御グループ (cgroup) v2 の制約を検出して適用します。 これらの制約により、CPU リソースとメモリ リソースに対する Linux カーネルのきめ細かい制御が提供され、Docker、Kubernetes、OpenShift 環境でのリソースの分離が向上します。
以前のバージョンでは、Kubernetes クラスターでのコンテナー化されたデプロイ (たとえば、Azure Kubernetes Service v1.25 以降) でメモリ不足 (OOM) エラーが発生する可能性SQL Server、コンテナー仕様で定義されているメモリ制限が適用されていないためです。 cgroup v2 のサポートは、この問題に対処します。
cgroup のバージョンを確認する
stat -fc %T /sys/fs/cgroup
結果は次のとおりです。
| Result | Description |
|---|---|
cgroup2fs |
cgroup v2 を使用する |
cgroup |
cgroup v1 を使用する |
cgroup v2 に切り替える
最も簡単なパスは、すぐに使用できる cgroup v2 をサポートするディストリビューションを選択することです。
手動で切り替える必要がある場合は、GRUB 構成に次のパラメーターを追加します。
systemd.unified_cgroup_hierarchy=1
次に、GRUB を更新します。 たとえば、Ubuntu で次を実行します。
sudo update-grub
Red Hat Enterprise Linux (RHEL) で、次のコマンドを実行します。
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
cgroup v2 を使用した CPU 制限レポート
cgroup v2 を使用して CPU 制限を構成する場合、SQL Serverは構成済みの CPU コア数をエラー ログに表示しません。 代わりに、ホスト CPU の合計数が引き続き報告されます。
スケジューラプランとクエリ プラン (並列処理の決定など) SQL Server、cgroup v2 で定義されている目的の CPU 数に合わせて調整するには、次の構成を適用します。
プロセッサ アフィニティの構成
cgroup の実行クォータに一致するように、SQL Server のプロセッサ アフィニティを明示的に設定します。 次の例では、cgroup クォータは 8 コア ホスト上の 4 つの CPU です。
ALTER SERVER CONFIGURATION
SET PROCESS AFFINITY CPU = 0 TO 3;
この構成により、SQL Serverは、目的の数の CPU に対してのみスケジューラを作成できます。 詳細については、ALTER SERVER CONFIGURATION および ノードおよび/または CPU に PROCESS AFFINITY を使用するを参照してください。
トレース フラグ 8002 を有効にする (推奨)
SQLPAL レイヤーでソフト アフィニティを使用するには、トレース フラグ 8002 を有効にします。
sudo /opt/mssql/bin/mssql-conf traceflag 8002 on
既定では、スケジューラはアフィニティ マスクで定義されている特定の CPU にバインドされます。 トレース フラグ 8002 を使用すると、スケジューラは代わりに CPU 間を移動できます。これにより、一般に、アフィニティと cgroup の制約を考慮しながらパフォーマンスが向上します。 詳細については、「DBCC TRACEON - トレース フラグ」を参照してください。
トレース フラグを有効にした後、SQL Server再起動します。
予想される動作
再起動後:
SQL Serverは、アフィニティ設定で定義されたスケジューラの数 (たとえば、4 つのスケジューラ) のみを作成します。
Linux カーネルは引き続き cgroup v2 CPU 実行クォータを適用します。
クエリの最適化と並列処理の決定は、ホスト CPU の合計数ではなく、目的の CPU 数に基づいています。
Note
SQL Serverエラー ログには、引き続きホスト CPU の合計数が表示されることがあります。 このログ記録と表示の動作は、cgroup v2 またはプロセッサ アフィニティによる実際の CPU 使用率、スケジューラの作成、または CPU 強制には影響しません。
詳細については、次のリソースを参照してください。
- クイックスタート: Helm チャートを使用して SQL Server Linux コンテナーを Kubernetes にデプロイする
- コントロール グループ v2 (Linux カーネルのドキュメント)
Linux およびコンテナーでメモリ制限を設定するためのガイドライン
SQL Server on Linuxには、さまざまなレベルで動作する複数のメモリ コントロールがあります。 次の表と図は、各レベルで使用可能なメモリをホスト RAM からバッファー プールに縮小する方法を示しています。
| Level | 設定者 | Description |
|---|---|---|
| ホスト | ハードウェア/VM の構成 | サーバーまたは仮想マシン (VM) 上の物理 RAM。 |
cgroup の制限 (docker run --memory、 systemd、または手動) |
コンテナーランタイム、systemd スライス、または手動による cgroup 構成 |
memory.max内のすべてのプロセスに対してカーネルによって強制される上限 (cgroup)。 ベアメタル Linux では省略可能。 |
SQL Server プロセス (memorylimitmb / MSSQL_MEMORY_LIMIT_MB) |
mssql-conf または環境変数 |
すべてのSQL Server コンポーネント全体の合計メモリ。
cgroup制限 (存在する場合) またはホスト メモリを下回る必要があります。 |
バッファー プール (max_server_memory) |
sp_configure |
8 KB のデータ ページのキャッシュ。
memorylimitmbより小さくする必要があります。 |
| ヘッドルーム | 計算済み (制限間のギャップ) | OS のオーバーヘッドと補助プロセス用に予約された、 cgroup 制限 (またはホスト メモリ) と memorylimitmbの間のギャップ。 |
SQL Server on Linux のメモリ制限を設定する場合は、次のガイドラインを考慮してください。
コンテナーのデプロイでは、
cgroupを使用して、コンテナーで使用できるメモリ全体を制限します。 この設定により、コンテナー内のすべてのプロセスの上限が確立されます。メモリ制限 (
memorylimitmbまたはMSSQL_MEMORY_LIMIT_MB環境変数によって設定される) は、SQL Server on Linux がすべてのコンポーネント (バッファー プール、SQLPAL、SQL Server エージェント、LibOS、PolyBase、Full-Text Search、および Linux 上の SQL Server に読み込まれたその他のプロセスなど) に割り当てることができる合計メモリを制御します。MSSQL_MEMORY_LIMIT_MB環境変数は、memorylimitmbで定義mssql.confよりも優先されます。memorylimitmbは、ホスト システムの実際の物理メモリを超えることはできません。memorylimitmbホスト システム のメモリとcgroupの制限 (存在する場合) よりも低く設定して、Linux オペレーティング システムに十分な空き物理メモリがあることを確認します。memorylimitmbを明示的に設定しない場合、SQL Serverでは、システム メモリの合計とcgroupの制限 (存在する場合) の間の小さい値の 80% が使用されます。max_server_memory サーバー構成オプションでは、SQL Server バッファー プールのサイズのみが制限され、SQL Server on Linux の全体的なメモリ使用量は制御されません。 前の行頭文字で説明した他のコンポーネントに十分なメモリが残らないように、常にこの値を
memorylimitmbより小さく設定します。
SQL Serverとコンテナーのメモリ制限の間の余裕
メモリ制限が構成されているコンテナーでSQL Serverを実行する場合 (たとえば、cgroup設定memory.max)、memory.memorylimitmbとコンテナーのメモリ制限の間でヘッドルームを維持します。 このヘッドルームは、コンテナー内のオペレーティング システムのオーバーヘッドと補助プロセスを提供します。
ほとんどのデプロイでは、オペレーティング システムと非SQL Server プロセスのコンテナー メモリの 10 ~ 20% を予約し、残りの容量より下に
memory.memorylimitmb設定します。大きなメモリ構成の場合、パーセンテージベースのバッファーは、必要以上に多くのメモリを予約できます。 たとえば、256 GB のコンテナーの 10% は約 25 GB であり、オペレーティング システムのオーバーヘッドには妥当です。 ただし、512 GB のコンテナーの 10% は約 51 GB であり、オペレーティング システムが必要とするよりも多い可能性があります。 このような場合は、代わりに固定バッファーを使用し、ワークロードとオペレーティング システムのオーバーヘッドに適したサイズにし、残りをSQL Serverに割り当てます。
ワークロードの特性、コンテナーで実行されている他のサービス、およびホスト構成に基づいてバッファーを調整します。
Note
推奨されるヘッドルーム値は、すべての環境に適用されません。 テストを通じてメモリ設定を検証し、ピーク時の負荷下でのシステムの安定性を確保します。
使用可能なメモリよりも高いメモリ制限を構成しないようにする
ホストで使用可能な物理メモリより大きい memory.memorylimitmb 、またはコンテナーによって強制されるメモリ制限を超える値を構成しないでください。 実行すると、SQL Serverがメモリを積極的に消費し、オペレーティング システムとサポート プロセスの容量が不足する可能性があります。 この構成の結果として、次の結果が得られます。
- メモリ使用量の逼迫が高まりました。
- システムの安定性が低下し、予期しないサービスの中断が発生しました。
- メモリ不足 (OOM) 状態が原因で
sqlservrプロセスを終了するオペレーティング システム。
SQL Serverメモリ制限をホストまたはコンテナーで使用できる有効なメモリ未満に構成し、オペレーティング システムとランタイム サービスに十分なバッファー領域を残します。
Docker メモリ構成の例
docker run --memory オプションは、コンテナーのcgroupメモリ制限を設定します。 この制限は、コンテナー内のすべてのプロセスに対してカーネルによって強制されるハード上限です。
MSSQL_MEMORY_LIMIT_MB(またはmemory.memorylimitmb)は、SQL Serverが使用できるメモリの量を制御します。
前のガイドラインで説明したように、オペレーティング システムと補助プロセスのヘッドルームを残すために、常にコンテナー のメモリ制限よりMSSQL_MEMORY_LIMIT_MB低く設定してください。
次の例では、16 GB の RAM を持つホストを使用します。 環境の値を調整します。
推奨されません。コンテナーのメモリ制限なし
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" \
-e "MSSQL_MEMORY_LIMIT_MB=14336" \
-p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2022-latest
--memoryがないと、コンテナーにはcgroupの上限はありません。
MSSQL_MEMORY_LIMIT_MBはSQL Server制約を受けますが、コンテナー内の他のプロセスは引き続き無制限のホスト メモリを消費できます。
非推奨: メモリ制限を SQL Server のメモリ制限と同じにすること
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" \
-e "MSSQL_MEMORY_LIMIT_MB=12288" \
--memory 12g \
-p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2022-latest
どちらの制限も 12 GB に設定されます (--memory 12g = 12,288 MB)。 オペレーティング システムのオーバーヘッドや補助プロセスのための余裕が残っていないため、OOM キルが発生する可能性があります。
推奨されません:SQL Serverメモリ制限がコンテナーの制限を超えています
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" \
-e "MSSQL_MEMORY_LIMIT_MB=14336" \
--memory 12g \
-p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2022-latest
MSSQL_MEMORY_LIMIT_MB (14 GB) がコンテナーの制限 (12 GB) を超えています。 このシナリオでは、「 使用可能なメモリよりも高いメモリ制限の構成を避ける」で説明されている OOM 条件が発生します。
推奨: オペレーティング システム用の余裕を見込んだコンテナーの上限
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" \
-e "MSSQL_MEMORY_LIMIT_MB=10240" \
--memory 12g \
-p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2022-latest
コンテナーは 12 GB (--memory 12g) に制限されており、SQL Serverは最大 10 GB (MSSQL_MEMORY_LIMIT_MB=10240) を使用するように構成されています。 残りの 2 GB (約 17%) は、オペレーティング システムやその他のプロセスのヘッドルームを提供します。
スワップ領域に関する考慮事項
コンテナーでSQL Serverを実行する場合は、ホスト レベルでスワップ領域を有効にして、オペレーティング システムとSQL Server以外のプロセスを保護します。 ただし、構成されたメモリ制限内で動作するようにSQL Serverを構成し、通常の操作中はスワップに依存しないようにします。
メモリ制限のガイドラインに従って、SQL Serverが物理メモリ内で動作するか、該当する
cgroupメモリ制限内で動作することを確認します。スワップが有効になっている場合は、ホスト上の一時的なメモリ負荷のセーフティ ネットとして扱い、安定状態のSQL Serverワークロードの容量として扱いません。
Important
SQL Serverメモリ不足によってスワップが発生すると、パフォーマンスが大幅に低下する可能性があります。 適切なメモリサイズ設定は、メモリ関連の障害を防ぐための主要なメカニズムです。