PostgreSQLは、特に同一システム上で複数のサーバコピーを実行している場合や非常に大規模なインストレーションでは、オペレーティングシステムの様々なリソース制限を超えてしまうことがあります。 本節では、PostgreSQLで使用されるカーネルリソース、およびカーネルリソース消費に関連した問題を解消する時に取ることができる手順について説明します。
PostgreSQLはオペレーティングシステムが、プロセス間通信(IPC)特に共有メモリとセマフォ機能を提供することを要求します。 Unix(派生)システムでは、「System V」 IPCや、「POSIX」 IPC、またはその両方を提供します。 Windowsは、これらの機能を独自で実装しているため、ここでは説明しません。
これらの機能の完全な欠落は、サーバ起動時の「Illegal system call」エラーによって判明します。 その場合はカーネルを設定し直すしかありません。 PostgreSQLはこれらの機能なしでは動きません。 しかし最近のオペレーティングシステムではこうした状況はまれなものです。
デフォルトではPostgreSQLは通常、非常に少量のSystem V共有メモリと、もっと大量の無名mmap
共有メモリを持ちます。
代替方法として、単一の大きなSystem Vメモリリージョンも利用できます
(shared_memory_type参照。)
さらに、System V又はPOSIXスタイルのどちらかのセマフォがサーバの起動時に作成されます。
現在、LinuxとFreeBSDシステムではPOSIXセマフォが使用され、それ以外のプラットフォームではSystem Vセマフォが使用されます。
PostgreSQL 9.3より前では、System V共有メモリだけが使用されていたので、サーバを起動させるために必要なSystem V共有メモリの量は非常に大きなものでした。 より古いバージョンのサーバで実行しているのであれば、該当するバージョンのサーバの文書を参照してください。
System V IPC機能は、通常システム全体の割り当て制限に制約されます。 PostgreSQLがこれらの制限のいずれかを超えると、サーバは起動を拒否し、問題および何をすべきかを説明するエラーメッセージを残します。 (18.3.1 も参照してください。) 関係するカーネルパラメータは別々のシステム上でも統一して名付けられています。 表 18.1で概略がわかります。 しかしこれらを設定するための方法は異なります。 以下に、いくつかのプラットフォームへの提案を挙げます。
表18.1 System V IPCパラメータ
名前 | 説明 | 一つのPostgreSQLインスタンスに必要な値 |
---|---|---|
SHMMAX | 共有メモリセグメントの最大サイズ(バイト) | 最小でも1キロバイト(ただしデフォルトはもっと多くなっています) |
SHMMIN | 共有メモリセグメントの最小サイズ(バイト) | 1 |
SHMALL | 使用可能な共有メモリの総量(バイトまたはページ) | バイト指定の場合はSHMMAX と同じ。ページ指定の場合はceil(SHMMAX/PAGE_SIZE) 。 + 他のアプリケーション用の空間 |
SHMSEG | プロセスごとの共有メモリセグメントの最大数 | 必要なのは1セグメントのみ(ただしデフォルトはもっと多くなっています) |
SHMMNI | システム全体の共有メモリセグメントの最大数 | SHMSEG と同様 + 他のアプリケーション用の空間 |
SEMMNI | セマフォ識別子の最大数(つまりセット) | 最低ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16) + 他のアプリケーション用の空間 |
SEMMNS | システム全体のセマフォの最大数 | ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16) * 17 + 他のアプリケーション用の空間 |
SEMMSL | セットごとのセマフォの最大数 | 最低17 |
SEMMAP | セマフォマップの中の項目の数 | 本文を参照 |
SEMVMX | セマフォの最大値 | 最低1000(デフォルトはしばしば32767ですが、必要がなければ変更しないでください) |
PostgreSQLは、サーバのコピー毎にSystem V共有メモリの数バイト(64ビットプラットフォームでは通常48バイト)を必要とします。
最近のほとんどのオペレーティングシステムでは、このくらいの量は簡単に割り当てられます。
しかし複数のサーバのコピーを実行している場合やSystem V共有メモリを使用する他のアプリケーションを実行している場合は、システム全体のSystem V共有メモリであるSHMALL
を増加させる必要があるかもしれません。
多くのシステムではSHMALL
をバイト単位ではなくページ単位で測ることに注意してください。
問題が少ないのは共有メモリセグメントの最小サイズ(SHMMIN
)で、PostgreSQLでは最大でもおよそ32バイトのはずです(通常では1です)。
システム全体のセグメントの最大数(SHMMNI
)もしくはプロセスごとのセグメントの最大数(SHMSEG
)に関して、使用しているシステムで0に設定されていない限り、問題が起きることはほぼありません。
System V セマフォを使用している場合、PostgreSQLは、許可した接続(max_connections)、許可したオートバキュームワーカプロセス(autovacuum_max_workers)、許可したバックエンドプロセス(max_worker_processes)ごとに1つのセマフォを使用し、16個のセマフォをセットとして扱います。
それぞれそのようなセットは、他のアプリケーションに使われているセマフォセットとの衝突を検出するための「マジックナンバー」が含まれている17個目のセマフォを持っています。
システム内のセマフォの最大数はSEMMNS
によって設定され、その結果としてその値は少なくともmax_connections
+autovacuum_max_workers
+max_worker_processes
と同じ、ただし、許可された接続とワーカ16個ごとに余分な1個を加えた値以上はなければいけません(表 18.1の公式を参照してください)。
SEMMNI
パラメータはシステム上に同時に存在できるセマフォ集合の数の上限を決定します。
ですから、このパラメータは少なくともceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16)
以上はなくてはいけません。
一時的な失敗の回避策としては許可される接続の数を下げることができますが、「No space left on device」という紛らわしい言葉がsemget
関数から表示されます。
場合によってはSEMMAP
を少なくともSEMMNS
と同程度に増やすことが必要になる場合があるかもしれません。
システムにこのパラメータがあるなら(ないかもしれません)、このパラメータはセマフォリソースマップのサイズを定義し、その中では有効なセマフォのそれぞれの隣接したブロックの項目が必要です。
セマフォ集合が解放されると、解放されたブロックに隣接する既に存在する項目に追加されるか、もしくは新しいマップの項目の下に登録されます。
もしマップが一杯だった場合、解放されたセマフォは(再起動するまで)失われます。
セマフォ空間の断片化により時間が経つごとに、有効なセマフォがあるべき量よりも少なくなる可能性があります。
SEMMNU
とSEMUME
のような、その他の様々な「semaphore undo」に関する設定はPostgreSQLには影響を与えません。
POSIXセマフォを使用している場合、System Vと同じ数のセマフォを必要とします。 つまり、許可した接続(max_connections)、許可したオートバキュームワーカプロセス(autovacuum_max_workers)、許可したバックエンドプロセス(max_worker_processes)ごとに1つのセマフォを使用します。 このオプションが優先されるプラットフォームでは、POSIXセマフォの数に特定のカーネル制限はありません。
少なくともバージョン5.1では、すべてのメモリが共有メモリとして使用できるように設定されているようにみえますので、SHMMAX
などのパラメータに対して特別な設定は必要ありません。
これはDB/2などの他のデータベースでも使用される、一般的な設定方法です。
しかし、/etc/security/limits
内の大域的なulimit
情報は変更しなければならないかもしれません。
デフォルトのファイルサイズ(fsize
)とファイル数(nofiles
)用のハードリミットは低過ぎるかもしれないためです。
デフォルトのIPC設定はsysctl
またはloader
インタフェースを使用して変更を行うことができます。
以下ではsysctl
を使用してパラメータを変更しています。
#
sysctl kern.ipc.shmall=32768
#
sysctl kern.ipc.shmmax=134217728
これらの設定を再起動しても永続化するには、/etc/sysctl.conf
を変更します。
セマフォ関連の設定はsysctl
では読み取りのみとみなされていますが、/boot/loader.conf
内で設定することができます。
kern.ipc.semmni=256 kern.ipc.semmns=512
そのファイルを変更した後、新しい設定を有効にするためには再起動が必要です。
また、System V共有メモリをRAM上に固定して、スワップによってページアウトされるのを避けるために、カーネルを設定したいと考えるかもしれません。
これはsysctl
を使用してkern.ipc.shm_use_phys
を設定することで実現できます。
sysctlのsecurity.jail.sysvipc_allowed
を有効にしてFreeBSD jailを実行している場合、異なるjailで実行するpostmasterを別のオペレーティングシステムユーザで実行しなければなりません。
これは、非特権ユーザが別のjailの共有メモリやセマフォに干渉することを防止できるため、セキュリティが向上します。
また、これによりPostgreSQLのIPCを整理するコードを適切に動作させることができます。
(FreeBSD 6.0以降では、IPC整理コードは他のjailにおけるプロセスを適切に検出せず、異なるjailで同一ポートでpostmasterを実行させることができません。)
FreeBSDのバージョン4.0より前では、(後述の)古いOpenBSDと同様に動作します。
NetBSD 5.0以降では、以下の例のようにIPCパラメータをsysctl
を用いて調整することができます。
#
sysctl -w kern.ipc.semmni=100
この設定を再起動しても永続化させるためには/etc/sysctl.conf
を編集してください。
NetBSDのデフォルト設定は不適切に小さいため、通常kern.ipc.semmni
とkern.ipc.semmns
を増加させたいと思うでしょう。
また、System V共有メモリをRAM上に固定して、スワップによってページアウトされるのを避けるために、カーネルを設定したいと考えるかもしれません。
これはsysctl
を使用してkern.ipc.shm_use_phys
を設定することで実現できます。
5.0より前のバージョンのNetBSDでは、(後述の)OpenBSDのように動作します。
ただし、カーネルパラメータはoption
ではなくoptions
キーワードを付けて設定する必要があります。
OpenBSD 3.3以降では、IPCパラメータはsysctl
コマンドを使って調整できます。例を示します。
#
sysctl kern.seminfo.semmni=100
これらの設定を再起動しても永続化するには、/etc/sysctl.conf
を変更します。
OpenBSDのデフォルト設定は不適切に小さいため、通常kern.seminfo.semmni
とkern.seminfo.semmns
を増加させたいと思うでしょう。
古いOpenBSDシステムでは、IPCパラメータを変更するためにはカスタムカーネルを構築する必要があります。
また、SYSVSHM
とSYSVSEM
オプションが有効であることを確認してください。
(デフォルトでそれらは有効になっています。)
様々なパラメータをカーネル設定ファイルで設定する方法を以下に示します。
option SYSVSHM option SHMMAXPGS=4096 option SHMSEG=256 option SYSVSEM option SEMMNI=256 option SEMMNS=512 option SEMMNU=256
デフォルトの設定は通常のインストールではほぼ十分です。
HP-UX 10ではSEMMNS
の出荷時のデフォルトは128ですが、これは大規模なデータベースサイトには低過ぎるかもしれません。
IPCパラメータはシステム管理マネージャ(SAM)から → の下で、設定することができます。 終わったら を選択してください。
デフォルトの最大セグメントサイズは32メガバイト、デフォルトの最大総サイズは2097152ページです。
「huge pages」を持つ通常ではないカーネル設定を除き、1ページはほとんど常に4096バイトです。
(検証にはgetconf PAGE_SIZE
を使用してください。)
共有メモリサイズの設定はsysctl
インタフェースを使用して変更可能です。
例えば16ギガバイトまで許すには以下のようにします。
$
sysctl -w kernel.shmmax=17179869184
$
sysctl -w kernel.shmall=4194304
更にこれらの設定を再起動時に保持できるように/etc/sysctl.conf
に保存することができます。
こうすることを大いに勧めます。
古めのディストリビューションではsysctl
プログラムが存在しない可能性があります。
この場合、/proc
ファイルシステムに対する操作で同等の変更を行うことができます。
$
echo 17179869184 >/proc/sys/kernel/shmmax
$
echo 4194304 >/proc/sys/kernel/shmall
他のデフォルトはかなり豊富なサイズですので、通常は変更する必要はありません。
macOSにおける共有メモリの推奨設定方法は、以下のような変数代入文からなる/etc/sysctl.conf
という名称のファイルを作成することです。
kern.sysv.shmmax=4194304 kern.sysv.shmmin=1 kern.sysv.shmmni=32 kern.sysv.shmseg=8 kern.sysv.shmall=1024
一部のバージョンのmacOSでは/etc/sysctl.conf
内に共有メモリパラメータ5つすべてを設定しなければならないという点に注意してください。
さもなくば値が無視されます。
最近のリリースのmacOSは、SHMMAX
を4096の倍数以外に設定しようとすると無視しますので、注意してください。
このプラットフォームではSHMALL
は4キロバイトページ単位です。
古めのバージョンのmacOSでは、共有メモリパラメータの変更を有効にするために再起動が必要になります。
10.5からSHMMNI
以外の変更は、sysctlを用いることにより、その場で行うことができます。
しかしいずれにせよ/etc/sysctl.conf
経由で望む値に設定することが最善です。
再起動を行っても値が保持されるからです。
/etc/sysctl.conf
はmacOS 10.3.9以降でのみ使用されます。
もしこれより前の10.3.xリリースを使用しているのであれば、/etc/rc
ファイルを編集し、以下のコマンドで値を変更しなければなりません。
sysctl -w kern.sysv.shmmax sysctl -w kern.sysv.shmmin sysctl -w kern.sysv.shmmni sysctl -w kern.sysv.shmseg sysctl -w kern.sysv.shmall
通常/etc/rc
はmacOSのアップデートで上書きされることに注意してください。
ですので、アップデートの度に編集し直す必要があるものと考えなければなりません。
macOS 10.2以前では、代わりに/System/Library/StartupItems/SystemTuning/SystemTuning
ファイル内にあるこれらのコマンドを編集してください。
必要な設定は/etc/system
で変えることができ、例えば以下のようになります。
set shmsys:shminfo_shmmax=0x2000000 set shmsys:shminfo_shmmin=1 set shmsys:shminfo_shmmni=256 set shmsys:shminfo_shmseg=256 set semsys:seminfo_semmap=256 set semsys:seminfo_semmni=512 set semsys:seminfo_semmns=512 set semsys:seminfo_semmsl=32
変更を反映させるには再起動する必要があります。 古めのバージョンのSolarisにおける共有メモリの情報はhttp://sunsite.uakom.sk/sunworldonline/swol-09-1997/swol-09-insidesolaris.htmlを参照してください。
Solaris 10以降とOpenSolarisでは、デフォルトの共有メモリとセマフォ設定は大抵のPostgreSQLアプリケーションで十分あります。
SolarisのデフォルトのSHMMAX
はシステムのRAMの1/4になりました。
さらにこの設定を調整するためには、postgres
ユーザに関するプロジェクト設定を使用しなければなりません。
例えば以下をroot
権限で実行してください。
projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres
このコマンドはuser.postgres
プロジェクトを追加し、postgres
ユーザの共有メモリの最大サイズを8GBに設定します。
この影響は次にこのユーザがログインした時、またはPostgreSQLを再起動した時(再読み込み時ではありません)に有効になります。
上ではPostgreSQLはpostgres
グループに属するpostgres
ユーザにより実行されていることを前提としています。
サーバの再起動は不要です。
多くの接続を受け付けるデータベースサーバにおいて推奨するカーネル設定にはこの他に以下があります。
project.max-shm-ids=(priv,32768,deny) project.max-sem-ids=(priv,4096,deny) project.max-msg-ids=(priv,4096,deny)
さらに、ゾーン内でPostgreSQLを実行している場合、ゾーンのリソース使用上限も上げる必要があるかもしれません。
projects
とprctl
についてはSystem Administrator's Guideの第2章 プロジェクトとタスクを参照してください。
systemdが使用されている場合、(共有メモリを含む)IPCリソースがオペレーティングシステムによって時期尚早に削除されないように注意する必要があります。
これはPostgreSQLをソースからインストールした場合に特に重要です。
PostgreSQLのディストリビューションパッケージのユーザーは、通常postgres
ユーザーがシステムユーザーで作成されるため、影響を受けにくいでしょう。
logind.conf
のRemoveIPC
の設定はユーザが完全にログアウトしたときにIPCオブジェクトを削除するかどうかを制御します。
システムユーザは免除されます。
この設定のデフォルトはsystemdですが、いくつかのオペレーティングシステムではデフォルトでオフになっています。
この設定が有効になっている時の典型的な影響は、並列問い合わせの実行で使われる共有メモリオブジェクトが見かけ上ランダムな時間に削除され、共有メモリオブジェクトをオープンしようとしたり、削除しようとしたりした時に以下のようなエラーや警告が出ることです。
WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory
IPCオブジェクトの違い(共有メモリ vs. セマフォ、System V vs. POSIX)はsystemdによって若干扱いが異なるため一部のIPCは他のものと違って削除されないことがあります。 しかし、これらの微妙な違いに依存することはお勧めできません。
「ユーザーログアウト」は、メンテナンスジョブの一環として、又は手動で、管理者がpostgres
ユーザーや類似のユーザでログインする可能性があるため、一般的に防止することは困難です。
「システムユーザー」は、/etc/login.defs
のSYS_UID_MAX
の設定によりsystemdのコンパイル時に決定されます。
パッケージとデプロイスクリプトは、useradd -r
, adduser --system
又は同等のコマンドを使用してpostgres
ユーザを作成するように注意する必要があります。
また、ユーザアカウントが誤って作成されて変更出来ないような場合は、以下を設定することを推奨します。
RemoveIPC=no
/etc/systemd/logind.conf
又はその他の設定ファイルで上記を入れます。
これらの2つのうち少なくとも1つが保証されてないとなりません。そうでないとPostgreSQLサーバは非常に信頼性が低くなります。
UnixライクなオペレーティングシステムではPostgreSQLサーバの操作と関係する可能性のある様々な種類のリソース制限があります。
特に重要なのは、ユーザごとのプロセス数の制限、プロセスごとのオープンファイルの数、プロセスごとの利用可能なメモリの量です。
これらのそれぞれが「ハード」と「ソフト」の2つの制限を持っています。
ソフト制限が実際に有効な制限ですが、ユーザによってハード制限まで変えることが可能です。
ハード制限はrootユーザによってのみ変えることができます。
setrlimit
システムコールがこれらのパラメータの設定を行います。
シェルの組み込みコマンドulimit
(Bourne シェル)もしくはlimit
(csh)は、コマンドラインからリソース制限を制御するために使われます。
BSD派生システム上では/etc/login.conf
ファイルが、ログイン時に設定される様々なリソース制限を制御します。
詳細はオペレーティングシステムの文書を参照してください。
関連するパラメータはmaxproc
、openfiles
、datasize
です。
以下に例を示します。
default:\ ... :datasize-cur=256M:\ :maxproc-cur=256:\ :openfiles-cur=256:\ ...
(-cur
はソフト制限です。
ハード制限を設定するためには-max
を付けてください。)
カーネルはいくつかのリソースに対して、システム全体の制限も持つことができます。
Linuxでは、/proc/sys/fs/file-max
が、カーネルがサポートするオープンファイル数の最大を決定します。
この数を変えるためには、そのファイルに別の数を書き込むか、あるいは/etc/sysctl.conf
に代入式を追加します。
プロセスごとのファイルの最大制限はカーネルがコンパイルされた時に固定されます。
詳しい情報については/usr/src/linux/Documentation/proc.txt
を参照してください。
PostgreSQLサーバは接続ごとに1つのプロセスを使うので、少なくとも許可された接続の数だけのプロセスに残りのシステムで必要な分を追加したものが必要になります。 通常はこれは問題ではありませんが、1つのマシン上でいくつかのサーバを起動している場合は厳しい状況になるかもしれません。
オープンファイルの制限の出荷時のデフォルトは、しばしば大多数のユーザはマシン上でシステムリソースの不正使用をしないという前堤に立った「社会的に友好的な」値を設定してしまいます。 もし1つのマシン上で複数のサーバを起動する場合はそれが必要でしょうが、専用サーバではこの制限を上げたいかもしれません。
反対に、個々のプロセスが多数のファイルをオープンすることを許可するシステムもあります。 そのようなプロセスが数個以上あれば、システム全体の制限は簡単に超えてしまいます。 この発生を検知し、システム全体の制限の変更を望まない場合は、PostgreSQLのmax_files_per_process設定パラメータを設定し、オープンファイルの消費を制限することができます。
Linux 2.4以降では、デフォルトの仮想メモリの動作はPostgreSQLには最適ではありません。 カーネルがメモリオーバーコミットを実装する方法のため、カーネルは、PostgreSQLや他のプロセスのメモリ要求がシステムの仮想メモリを枯渇させた場合、PostgreSQL postmaster (マスタサーバプロセス)を終了させる可能性があります。
これが発生した場合、以下のようなカーネルメッセージが現れます (こうしたメッセージを検索する場所についてはシステム文書と設定を参照してください)。
Out of Memory: Killed process 12345 (postgres).
これは、postgres
プロセスがメモリ不足のために終了してしまったことを示します。
起動中のデータベース接続は正常に動作しますが、新しい接続は受け付けられません。
復旧するには、PostgreSQLを再起動しなければなりません。
この問題を防止する1つの方法として、PostgreSQLを他のプロセスがそのマシンのメモリを枯渇させないことが確実なマシンで起動するというものがあります。 物理メモリとスワップ領域が消費尽くされた時のみにメモリ不足(OOM)killerが発生するため、メモリが不足する場合、オペレーティングシステムのスワップ領域を増やすことが問題解決の役にたちます。
PostgreSQL自体が実行中のシステムのメモリ不足を引き起こした場合、設定を変更することで問題を防止することができます。
メモリ関連の設定パラメータ、具体的にはshared_buffers
およびwork_mem
、を低くすることで回避できる場合もあります。
個の他にもデータベースサーバ自体への接続が多く許可しすぎることで問題が引き起こされる場合もあります。
多くの場合、max_connections
を減らし、外部のコネクションプールソフトウェアを使用することで改善されます。
Linux 2.6以降では、メモリを「オーバーコミット」させないようにカーネルの動作を変更することができます。
この設定は完全にOOM killerの発生を防ぐことはできませんが、その発生頻度をかなり軽減しますので、システム動作の堅牢性をより高めます。
これは、以下のようにsysctl
を使用して厳密なオーバーコミットモードを選択すること、もしくは、/etc/sysctl.conf
に同等の項目を記述することで実施されます。
sysctl -w vm.overcommit_memory=2
また、関連するvm.overcommit_ratio
設定を変更した方が良いでしょう。
詳細はカーネル文書ファイルhttps://www.kernel.org/doc/Documentation/vm/overcommit-accountingを参照してください。
vm.overcommit_memory
の変更と関係なく使用できるその他の方法は、プロセス固有のOOMスコア調整値をpostmasterプロセス向けに-1000
に設定することです。
これによりOOM killerの対象とならないことが保証されます。
このための最も簡単な方法は以下をpostmasterの起動スクリプト内でpostmasterを実行する直前に実行することです。
echo -1000 > /proc/self/oom_score_adj
この作業をrootで実行しなければならないことに注意して下さい。 さもないと効果がありません。 このためrootが所有する起動スクリプトが、これを行うための最も簡単な場所です。 その場合には、スタートアップスクリプトのpostmasterの起動前に以下の環境変数を設定することも推奨します。
export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj export PG_OOM_ADJUST_VALUE=0
これらの設定は、いざという時にpostmasterの子プロセスをOOM killerのターゲットに出来るようにOOMスコア調整を通常のゼロで実行します。
子プロセスを他のOOMスコア調整で実行したい場合には、PG_OOM_ADJUST_VALUE
により別の値にすることが出来ます。
(PG_OOM_ADJUST_VALUE
は省略することが出来て、その場合はデフォルトのゼロになります。)
PG_OOM_ADJUST_FILE
を設定しない場合、子プロセスはpostmasterと同じOOMスコア調整で実行されますが、postmasterが優先される設定にすることが肝心なので、それは賢明とは言えません。
古いLinuxカーネルは/proc/self/oom_score_adj
を提供していませんが、同様の機能を持つ/proc/self/oom_adj
があるでしょう。
これは、無効にするための設定値が-1000
ではなく-17
であるという点を除いては同じように動作します。
Linux 2.4カーネルのベンダの中には、2.6のオーバーコミットsysctl
版を持つものがあることが報告されています。
しかし、関係するコードを持たない2.4カーネルでvm.overcommit_memory
を2に設定することはより状況を悪化させます。
2.4のインストレーションではこれを試す前に、実際のカーネルソースコードを調査し、その中でサポートしているかどうかを検証することをお勧めします(mm/mmap.c
ファイル内のvm_enough_memory
関数を参照してください)。
overcommit-accounting
文書ファイルの存在は、この機能が存在するかどうかを証明するものではありません。
疑わしい場合は、使用中のカーネルベンダのカーネル専門家に相談してください。
PostgreSQLのように、メモリの大きな連続チャンクを使用するとき、特にshared_buffersの値が大きい場合に、huge pagesを使用するとオーバーヘッドが減少します。
PostgreSQLでこの機能を有効にするには、CONFIG_HUGETLBFS=y
およびCONFIG_HUGETLB_PAGE=y
としたカーネルが必要です。
またカーネル設定vm.nr_hugepages
を調整する必要もあるでしょう。
必要なhuge pages数を見積もるには、huge pagesを有効にせずにPostgreSQLを起動し、procファイルシステムを使用してpostmasterの無名共有セグメントサイズとシステムのhuge pageサイズの値をチェックします。
これは以下のような感じになるでしょう。
$head -1 $PGDATA/postmaster.pid
4170 $pmap 4170 | awk '/rw-s/ && /zero/ {print $2}'
6490428K $grep ^Hugepagesize /proc/meminfo
Hugepagesize: 2048 kB
6490428
/ 2048
はおよそ3169.154
ですので、この例では少なくとも3170
のhuge pagesが必要で、それは以下のようにして設定できます。
$ sysctl -w vm.nr_hugepages=3170
同じマシン上で他にもhuge pagesが必要なプログラムがあるなら、もっと大きな設定が適切でしょう。
再起動のときにこの設定が適用されるように、これを/etc/sysctl.conf
に追加するのを忘れないで下さい。
時には、カーネルは求められた数のhuge pagesを割り当てることができないことがあるので、そのコマンドを繰り返すか、再起動する必要があるかもしれません。 (再起動の直後は、マシンのメモリの大部分はhuge pagesへの変更が可能なはずです。) huge pagesの割り当ての状況を確認するには、次のようにします。
$ grep Huge /proc/meminfo
sysctlを使ってvm.hugetlb_shm_group
を設定する、あるいはulimit -l
でメモリをロックする権限を与えることで、データベースサーバのOSユーザにhuge pagesを使用する権限を与える必要もあるかもしれません。
PostgreSQLのhuge pagesのデフォルトの動作は、可能な場合はhuge pagesを使用し、失敗した場合は通常のページを使用します。
postgresql.conf
でhuge_pages
をon
に設定することで、huge pagesの使用を強制することができます。
この設定の場合、十分なhuge pagesが確保できなければ、PostgreSQLの起動に失敗することに注意してください。
Linuxのhuge pages機能の詳細はhttps://www.kernel.org/doc/Documentation/vm/hugetlbpage.txtを参照してください。