「チューニングしているはずなのに、夜間バッチでレイテンシのスパイクが頻発する」
これらは、Linuxのメモリ管理機能「透過的ヒュージページ(THP: Transparent HugePages)」が原因のことがあります。カーネルが4KBの小さなページを自動で2MBの大きなページに統合しようとする処理(コンパクション)が、タイミングによってはアプリケーションの停止を引き起こします。
この記事では、RHEL 9系/Ubuntu 22.04 LTS~24.04 LTSを想定環境として、hugeページの仕組みから透過的ヒュージページの無効化、vm.nr_hugepagesによる専用ページの確保、PostgreSQLへの適用まで、設定手順を解説します。
この記事のポイント
・透過的ヒュージページ(THP)がデータベースのレイテンシ原因になる
・THPは /sys/kernel/mm/transparent_hugepage/enabled で確認・無効化する
・専用ページはvm.nr_hugepagesで確保し/proc/meminfoで残量を確認する
・PostgreSQLでhuge_pages = onを設定して専用ページを利用させる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
hugeページとは何か|4KBページとの違い
Linuxのメモリ管理は、通常4KBの「ページ」という単位で行われます。物理アドレスと仮想アドレスの変換にはTLB(Translation Lookaside Buffer)というハードウェアキャッシュが使われますが、メモリを大量に扱うアプリケーションでは4KBページ数が膨大になりTLBミスが頻発します。hugeページはデフォルト2MB(環境によっては1GB)の大きなページサイズを使い、TLBエントリを大幅に削減することでメモリアクセスを高速化します。
Linuxにはhugeページの方式が2種類あります。
・HugeTLB(静的hugeページ):管理者が事前に確保する専用ページ。アプリケーションが明示的にマップする
・透過的ヒュージページ(THP):カーネルが自動で4KBページを2MBページに統合する。設定不要で便利な反面、コンパクション処理のタイミングでアプリケーションが一時停止する可能性がある
データベース(PostgreSQL・Oracle・MySQL)はHugeTLBを使った専用ページを推奨しており、THPは無効化が基本です。
透過的ヒュージページ(THP)の現状確認
まず現在のTHP設定を確認します。# THPの有効・無効状態を確認する cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
・always:カーネルが自動でTHPを使用する(多くのディストリビューションのデフォルト)
・madvise:アプリケーションが要求した場合のみ使用する
・never:THP無効
デフラグ設定も確認しておきます。
cat /sys/kernel/mm/transparent_hugepage/defrag
THPを無効化する手順
1. 一時的に無効化する(再起動で元に戻る)
確認・検証目的であれば、次のコマンドで即座に無効化できます。echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag
2. systemdサービスで永続化する
再起動後も維持するには、起動時にコマンドを実行するsystemdサービスを作成します。# ユニットファイルを作成する cat > /etc/systemd/system/disable-thp.service << 'EOF' [Unit] Description=Disable Transparent HugePages After=network.target [Service] Type=oneshot ExecStart=/bin/sh -c "echo never > /sys/kernel/mm/transparent_hugepage/enabled" ExecStartPost=/bin/sh -c "echo never > /sys/kernel/mm/transparent_hugepage/defrag" RemainAfterExit=yes [Install] WantedBy=multi-user.target EOF
systemctl daemon-reload systemctl enable --now disable-thp.service
systemctl status disable-thp.service
* disable-thp.service - Disable Transparent HugePages Loaded: loaded (/etc/systemd/system/disable-thp.service; enabled; preset: disabled) Active: active (exited) since Mon 2026-10-26 09:00:00 JST; 1min ago
専用hugeページ(HugeTLB)を設定する
1. 現在のhugeページ情報を確認する
grep -i huge /proc/meminfo
AnonHugePages: 0 kB ShmemHugePages: 0 kB FileHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB
サーバーの物理メモリ構成を確認するには、dmidecode でハードウェア情報を取得して搭載メモリのスロット構成も把握しておくと、割り当て可能な上限を見積もりやすくなります。
2. 必要なhugeページ数を計算する
PostgreSQLの場合、主にshared_buffersの確保にhugeページを使います。計算式は次のとおりです。・必要ページ数 = ceil( shared_buffers(KB) ÷ Hugepagesize(KB) ) × 1.1(10%マージン)
例:shared_buffers = 8GB(8,388,608 KB)、Hugepagesize = 2048 KBの場合
・8,388,608 ÷ 2048 = 4096ページ → マージン込みで4506ページを確保
3. vm.nr_hugepagesで割り当てる
# 現在の設定を確認する sysctl vm.nr_hugepages # 一時的に割り当てる(再起動で0に戻る) sysctl -w vm.nr_hugepages=4506
4. /etc/sysctl.dで永続化する
# 設定ファイルを作成する echo "vm.nr_hugepages = 4506" > /etc/sysctl.d/99-hugepages.conf # 即座に適用する sysctl -p /etc/sysctl.d/99-hugepages.conf
grep -i huge /proc/meminfo
HugePages_Total: 4506 HugePages_Free: 4506 HugePages_Rsvd: 0 HugePages_Surp: 0
PostgreSQLにhugeページを適用する
postgresql.confを編集してhuge_pages設定を有効にします。# postgresql.conf の設定(デフォルトは try。on に変更する) huge_pages = on
PostgreSQLが使用する共有メモリがOS側の制限値を超えないか確認します。
# 共有メモリの上限を確認する sysctl kernel.shmmax sysctl kernel.shmall
設定が完了したらPostgreSQLを再起動します。
systemctl restart postgresql-16 # または systemctl restart postgresql
設定後の確認コマンド
1. /proc/meminfoでhugeページの使用状況を確認する
grep -i huge /proc/meminfo
2. プロセスのhugeページ使用量を確認する
# PostgreSQL メインプロセスのPIDを取得する PGPID=$(pgrep -x postgres | head -1) # そのプロセスのhugeページ使用量を確認する grep -i huge /proc/${PGPID}/status
HugetlbPages: 8388608 kB
トラブルシュート
PostgreSQLが「Cannot allocate memory」で起動しない
原因:vm.nr_hugepagesで確保したページ数が不足しています。対処:まず/proc/meminfoで HugePages_Free を確認し、0に近ければ数を増やします。
grep HugePages /proc/meminfo sysctl -w vm.nr_hugepages=5000 # ページ数を増やして再試行する
THPの設定が再起動後に元に戻る
原因:systemdサービスが起動時に実行されていません。対処:サービスが有効(enabled)かどうか確認します。
systemctl is-enabled disable-thp.service # disabled と出た場合は有効化する systemctl enable disable-thp.service
vm.nr_hugepagesで指定した数を確保できない
原因:物理メモリが断片化していて、連続した2MBの領域を確保できない状態です。対処:/etc/sysctl.d/に設定を書いてサーバー起動直後(メモリが断片化する前)に確保します。起動後にsysctl -wで後から設定しても足りない場合は、再起動が最も確実です。
本記事のまとめ
| やりたいこと | コマンド・設定ファイル |
|---|---|
| THP設定を確認する | cat /sys/kernel/mm/transparent_hugepage/enabled |
| THPを一時的に無効化する | echo never > /sys/kernel/mm/transparent_hugepage/enabled |
| THPを永続的に無効化する | /etc/systemd/system/disable-thp.service を作成してenable |
| hugeページ情報を確認する | grep -i huge /proc/meminfo |
| hugeページ数を設定する(一時) | sysctl -w vm.nr_hugepages=4506 |
| hugeページ数を永続化する | /etc/sysctl.d/99-hugepages.conf に vm.nr_hugepages = 4506 |
| PostgreSQLにhugeページを使わせる | postgresql.confの huge_pages = on |
| プロセスのhugeページ使用量を確認する | grep -i huge /proc/<PID>/status |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:LinuxのI/Oスケジューラを確認・変更する方法|mq-deadline・BFQのSSD/HDD別の推奨設定とudev永続化
- この記事の属するカテゴリ:Linuxtipsへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます