Transparent HugePage が DB レイテンシに与える影響と作業の前提
Transparent HugePage(THP)は、カーネルがユーザー空間のメモリを 2MB の巨大ページに自動集約することで TLB ミスを減らし、スループットを高める機能です。ところが、DB サーバの運用現場では長年にわたり「THP が原因とみられるレイテンシスパイク」が報告されています。MySQL・PostgreSQL・MongoDB・Redis いずれのコミュニティも公式ドキュメントで無効化を推奨しており、その理由は主に二点です。
一つ目は khugepaged による非同期なページ折りたたみ です。DB プロセスがページを確保するタイミングで khugepaged が割り込み、通常ページを 2MB ページに統合しようとすると、数ミリ秒単位のストールが不規則に発生します。二つ目は メモリ断片化 です。DB は比較的小さな固定サイズのバッファを大量に扱うため、2MB ページへの集約が空振りに終わり、断片化がかえって進むケースがあります。カーネル 5.x 以降は defrag のデフォルトが madvise に変わり挙動が改善していますが、本番環境では依然として無効化が標準的な選択肢となっています。
なお、本稿の手順は RHEL 9 系(Rocky Linux 9・AlmaLinux 9)および Ubuntu 24.04 LTS を想定しています。カーネルは 6.x 系、systemd 252 以降が前提です。
変更前のレイテンシ基準値を計測する
THP 無効化の効果を客観的に評価するには、変更前の基準値(ベースライン)が不可欠です。「体感で速くなった」では根拠に欠け、後続のロールバック判断もできません。以下の三層で計測します。
- OS 層:
perf stat -e TLB-load-misses,page-faultsで TLB ミス率と page fault 回数を 30〜60 秒採取します。 - DB 層:MySQL なら
SHOW STATUS LIKE 'Handler%'とスロークエリログを組み合わせ、P95/P99 レイテンシを記録します。PostgreSQL はpg_stat_statementsのmean_exec_time・stddev_exec_timeを確認します。 - アプリ層:可能であれば Prometheus + node_exporter のヒストグラムメトリクスをダッシュボードに固定し、変更前後のグラフを並べて比較できるようにします。
計測は「本番相当の負荷がかかっている状態」で実施します。夜間の閑散時刻だと THP の影響が出にくいため、日中のピーク帯に合わせるか、負荷テストツール(sysbench・pgbench など)で同等の IOPS を再現してください。計測結果はタイムスタンプ付きでファイルに保存しておきます。
systemd によるホスト全体の THP 無効化(恒久設定)
古くは /etc/rc.local や tuned プロファイルで対処する手法が使われていましたが、2026 年現在の標準的な方法は systemd の一時起動サービスとして設定を組み込む 形です。これにより、起動順序の依存関係が明確になり、状態管理が容易になります。
# /etc/systemd/system/disable-thp.service
[Unit]
Description=Disable Transparent Huge Pages
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=basic.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'
RemainAfterExit=yes
[Install]
WantedBy=basic.target
systemctl daemon-reload
systemctl enable --now disable-thp.service
設定後は cat /sys/kernel/mm/transparent_hugepage/enabled の出力が always madvise [never] のように never がブラケットで囲まれていることを確認します。再起動後も同じ出力になることを必ず検証してください。
RHEL 9 系では tuned プロファイルが /sys/kernel/mm/transparent_hugepage/enabled を上書きする場合があります。現在アクティブなプロファイルを tuned-adm active で確認し、throughput-performance や latency-performance が有効なら、それらのプロファイルの transparent_hugepages=never 設定との整合性を取ります。tuned が先に madvise に戻してしまうケースがあるため、systemd サービスの After= に tuned.service を追記しておくと安全です。
cgroup v2 による DB プロセス単位の分離(混在環境向け)
Web サーバや分析バッチなど、THP が有益な別プロセスが同居するサーバでホスト全体を never にすることに抵抗がある場合は、cgroup v2 の memory.hugepages 制御 で DB プロセスだけに限定適用できます。ただし、この方法はカーネル 6.1 以降かつ cgroup v2 フルモードが前提です。
systemd 管理下のサービスであれば、ユニットファイルに以下を追記するだけで cgroup スコープが自動的に作られます。
# /etc/systemd/system/mysql.service.d/thp.conf
[Service]
MemoryZSwapWriteback=no
# THPを無効化するために hugepage の自動昇格を抑制
Environment="THP_DISABLE=1"
ExecStartPre=/bin/sh -c 'echo never > /sys/fs/cgroup/system.slice/mysql.service/memory.hugepages'
より確実な方法は、DB サービスの cgroup スコープに対して memory.hugepages_limit_in_bytes を 0 に設定することですが、カーネルバージョンによってインターフェースが異なります。本番適用前に検証環境で動作を確認し、systemd-cgls と cat /proc/<pid>/smaps_rollup | grep -i huge で AnonHugePages が 0 になっていることを確認してください。
現場では、ホスト全体の無効化のほうが設定が単純でトラブルシュートしやすいという理由から、混在環境でも THP 無効化を選ぶ運用チームが多数派です。cgroup 分離はオプションとして頭に入れておく程度でよいでしょう。
変更後の効果検証と判断基準
THP 無効化後、同じ計測手順でレイテンシを再取得します。効果が現れやすい指標は以下の順です。
- P99 レイテンシの改善: スパイクの頻度と振れ幅が減少します。平均値よりも P95/P99 に変化が出やすいです。
- TLB ミス率の変化: 逆に増加することがあります。これは 2MB ページが使われなくなった直接的な結果であり、スループット重視の処理では悪化として現れる場合があります。
- page fault 回数: khugepaged による統合が止まるため、マイナーフォルトの分布が変わります。
OLTP ワークロードでは多くの場合 P99 が 10〜30% 改善しますが、大量の順次スキャンが主体の分析系クエリではスループットが微減するケースもあります。変更後 24〜48 時間は本番モニタリングを強化し、QPS・エラーレート・スロークエリの増減を継続観察します。
再有効化ロールバックの手順と注意点
THP 無効化が逆効果だったと判断した場合、または別の要因でロールバックが必要になった場合の手順です。
# 即時ロールバック(再起動不要)
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
echo madvise > /sys/kernel/mm/transparent_hugepage/defrag
# systemd サービスを無効化(次回起動から適用)
systemctl disable disable-thp.service
systemctl stop disable-thp.service
madvise を選ぶ理由は、always に戻すと再び khugepaged が全プロセスに積極的に介入するためです。madvise であれば、アプリケーション側が明示的に madvise(MADV_HUGEPAGE) を呼び出した場合のみ THP が有効になります。カーネル 6.x のデフォルト値も madvise であり、切り戻し後もしばらくはこの値で運用するほうが安全です。
ロールバック後、既存の DB プロセスに対して THP が即座に適用されるわけではありません。khugepaged が新規確保ページを対象に動き出すまで数分かかります。grep AnonHugePages /proc/<db_pid>/smaps_rollup で値が増加し始めることを確認できます。
最後に、2026 年時点での補足として、Red Hat は RHEL 9.4 以降のリリースノートで madvise をデフォルト値として改めて明記しており、新規構築サーバでは always で稼働している環境はほぼなくなっています。一方、数年前に構築した VM や物理サーバを使い続けている環境では今でも always が残っているケースがあるため、棚卸しの際は cat /sys/kernel/mm/transparent_hugepage/enabled を全ホストで確認することをお勧めします。Ansible の fact 収集やカスタムモジュールでの一括確認が現場では定番の運用になっています。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
PR・広告
コマンド操作から基本運用までを手を動かして学べる定番書。記事で触れた技術の土台固めに。
※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。
