大きなPostgresのインストールはオペレーティング システムのリソースリミットを容易に越えてしまいます。(システムに よっては出荷時のデフォルトが低すぎるため"大きな"インストール の必要さえありません。)このような問題に遭遇したことがある方は この先を読んでください。
共有メモリとセマフォはひとまとめにして"System V IPC" と呼ばれます(メッセージキューとも一緒ですが、Postgres では関係ありません。)。ほとんどすべての現代のオペレーティング システムはこれらの機能を提供しますが、特に BSD の痕跡を引きずるシステムの ように、すべてがデフォルトで有効にされたり適当なサイズになっているわけでは ありません。(QNX と BeOS ポートではPostgresは これらの機能の独自の代替実装を提供しています。)
これらの機能の完全な欠落はIllegal system call エラーで postmaster 起動時に表示されます。その場合はカーネルを 設定し直すしかありません。Postgresはこれらの 機能なしでは動きません。
Postgresが様々な IPC リソースのハードリミットを越えると postmaster は起動を拒否し、問題に関する限界条件を教え 何をすべきかを示すエラーメッセージを残します。 (Section 3.3.1も参照して下さい。) 関係するカーネルパラメータは別々のシステム上でも統一して名付けられて います。Table 3-2で概略がわかります。 しかしこれらを得るためのメソッドは異なります。下記でいくつかの プラットフォームへの提案を挙げます。これらの設定を変えるには、 しばしばマシンを再起動する ことが必要になり、カーネルをコンパイルし直す必要がある場合さえあるので 注意してください。
Table 3-2. System V IPC パラメータ
名前 | 説明 | 適当な値 |
---|---|---|
SHMMAX | 共有メモリセグメントの最大サイズ(バイト) | 512 kB + 8192 * バッファ数 + その他 ... 無限大 |
SHMMIN | 共有メモリセグメントの最小サイズ(バイト) | 1 (最大で 256 kB) |
SHMSEG | プロセスごとの共有メモリセグメントの最大数 | 必要なのは 1 セグメントだけですが、デフォルトでは もっと多くなっています |
SHMMNI | システム全体の共有メモリセグメントの最大数 | SHMSEGと同様 + 他のアプリケーション用の空間 |
SEMMNI | セマフォ識別子の最大数 (つまりセット) | >= ceil(max_connections / 16) |
SEMMNS | システム全体のセマフォの最大数 | ceil(max_connections / 16) * 17 + 他のアプリケーション用の空間 |
SEMMSL | セットごとのセマフォの最大数 | >= 17 |
SEMMAP | セマフォマップの中の項目の数 | テキスト参照 |
SEMVMX | セマフォの最大値 | >= 255 (デフォルトはしばしば 32767 ですが、そう するように言われない限り変えないでください) |
一番重要な共有メモリのパラメータは、共有メモリセグメント が持つことのできる最大サイズのバイト数SHMMAXです。 もしshmgetからInvalid argument エラーメッセージを受けた場合、このリミットを越えている 可能性があります。要求される共有メモリセグメントのサイズは 要求されるバッファの数(オプション-B)と許されている 接続の数(-N)によりますが、前者が主要です。 (したがって、一時的な策として、エラーをなくすためにこれらの設定を 低くすることもできます。)大雑把な概算としては、必要とされる セグメントサイズをバッファ数*ブロック数(デフォルトでは 8192 kB) + 十分なオーバーヘッドです。表示される全てのエラーメッセージには 失敗したメモリ表示サイズが表示されているはずです。
問題が少ないのは共有メモリセグメントの最小サイズ(SHMMIN) で、Postgresでは最大でも 256 kB のはずです(通常 では 1 です)。システム全体のセグメントの最大数(SHMMNI) もしくはプロセスごとのセグメントの最大数(SHMSEG) は使用しているシステムがゼロに設定されていない限り問題はないはず です。システムによっては共有メモリの合計値にもリミットを設定 してあります。下記のプラットフォーム固有の指示を参照して下さい。
Postgresは許可される接続ごとにひとつのセマフォを 16 のセットで使います(-N オプション)。それぞれのそのような セットは 17 個目のセマフォを持ち、そのセマフォは他のアプリケーション に使われているセマフォセットとの衝突を避けるための "マジックナンバー"を持っています。システム内のセマフォの 最多数はSEMMNS によって設定され、その結果として その数字は少なくとも接続の設定プラスそれぞれの16の接続のための余分 はなければいけません。(Table 3-2の 公式を見て下さい。)パラメータ SEMMNIはシステム上に同時に 存在できるセマフォセットの数の限度を決定します。ですからこのパラメータは 少なくともceil(max_connections / 16)以上はなくては いけません。一時的な失敗の逃げ道としては許可される接続の数を下げる ことができますが、"No space left on device"という紛らわしい言葉が関数semget() から表示されます。
場合によってはSEMMAPを少なくともSEMMNS と同じ数だけ増やすことが必要になる場合があるかもしれません。この パラメータはセマフォリソースマップのサイズを定義し、その中では 有効なセマフォのそれぞれの隣接したブロックの項目が必要です。 セマフォセットが解放されると、解放されたブロックに隣接する既に存在 する項目に追加されるか、もしくは新しいマップの項目の下に登録 されます。もしマップが一杯だった場合、解法されたセマフォは(再起動 するまで)失われます。したがってセマフォ空間の断片化により時間が経つごとに、 有効なセマフォがあるべきよりも少なくなる可能性が あります。
ひとつのセットの中にいくつのセマフォがあるかを決める SEMMSLはPostgresでは少なくとも 17 はなくてはいけません。
SEMMNU and SEMUMEのような、 その他の様々な"semaphore undo"に関する設定は Postgresでは問題にする必要がありません。
共有メモリ. デフォルトでは、4MB の共有メモリしかサポートされていません。 共有メモリはページングできないことを覚えておいて下さい。 RAM の中にロックされているのです。共有メモリのパラメータ は以下です。
#define SHMMAX /* 共有メモリの最大セグメントサイズ (バイト) */ #define SHMMIN /* 共有メモリの最小セグメントサイズ (バイト) */ #define SHMMNI /* 共有メモリ識別子の最大数 */ #define SHMSEG /* プロセスごとの共有メモリセグメントの最大数 */ #define SHMALL /* 共有メモリの最大値 (ページ) */postmaster がサポートするバッファの数を増やすためには、下記をカーネル設定 ファイルに追加して下さい。 1024のSHMALL値は共有メモリの 4MB を表します。必要に応じて 増やして下さい。
options "SHMALL=4096" options "SHMMAX=\(SHMALL*PAGE_SIZE\)"
4.1 以降のものを使っている方は、ただカーネルをコンパイルし直して 再起動して下さい。それ以前のものを使っている方は、現在の カーネルのsysptsize値を見つけるためbpatch を使って下さい。これは起動時に動的に計算されます。
$ bpatch -r sysptsize 0x9 = 9次に、SYSPTSIZEをハードコーディングされた値に 変えて下さい。bpatch 値を使い、更に希望する共有メモリの 4 MB ごとに 1 を追加して下さい。
options "SYSPTSIZE=13"sysptsizeは起動中は sysctl によって動的に変えることは できません。
セマフォ. セマフォの数を増やす必要がある場合があるかもしれません。 デフォルトではPostgresは 34 のセマフォを 割り当てていますが、これはシステム合計のデフォルトである 60 の半分以上です。
デフォルトは/sys/sys/sem.h です。
#define SEMMNI 10 /* セマフォ識別子の数 */ #define SEMMNS 60 /* システム内のセマフォの数 */ #define SEMUME 10 /* プロセスごとの取り消し項目の最高数 */ #define SEMMNU 30 /* システム内の取り消し構造体の数 */設定ファイルの中に必要な値を設定して下さい。例えば下記のようになります。
options "SEMMNI=40" options "SEMMNS=240" options "SEMUME=40" options "SEMMNU=120"
オプションSYSVSHMとSYSVSEMはカーネルの コンパイル時に動作可能にする必要があります。(デフォルトでは 動作可能になっています。)共有メモリの最大サイズはオプション SHMMAXPGSで(ページ数で)決定されます。下記は 様々なパラメータの設定方法の例です。
options SYSVSHM options SHMMAXPGS=4096 options SHMSEG=256 options SYSVSEM options SEMMNI=256 options SEMMNS=512 options SEMMNU=256 options SEMMAP=256
デフォルトの設定は通常のインストールではほぼ十分です。 HP-UX 10 ではSEMMNSの製造 デフォルトは 128 ですが、これは大きなデータベースサイト には低すぎるかもしれません。
IPC パラメータはKernel Configuration->Configurable Parameters の下で、システム管理マネージャ(SAM) の中で設定することができます。終ったら Create A New Kernelを押して下さい。
共有メモリ制限のデフォルト(SHMMAX と SHMALLの両方とも)は 2.2 カーネルで 32 MB ですが、 procファイルシステムで変えることができます (再起動なし)。例えば 128 MB を許可するためには下記のようになります。
$ echo 134217728 >/proc/sys/kernel/shmall $ echo 134217728 >/proc/sys/kernel/shmmaxこれらのコマンドは起動時に実行されるスクリプトに書いておくことが できます。
これらのパラメータをコントロールするために、もし有効であれば sysctlを代わりに使うことも できます。/etc/sysctl.confというファイル を探し、下記の2行をそれに追加して下さい。
kernel.shmall = 134217728 kernel.shmmax = 134217728このファイルは通常は起動時に処理されますが、 sysctlは後で明示的に呼び出すことも できます。
他のパラメータはどんなアプリケーションにも合うようなサイズ に設定されています。自分で確認したい方は、 /usr/src/linux/include/asm-xxx/shmparam.h と /usr/src/linux/include/linux/sem.hを見てみて下さい。
デフォルトの設定では、セグメント毎に 512 kB の共有メモリしか 許可されていませんが、これは-B 24 -N 12にはおよそ十分 です。設定を増やすためには、まずディレクトリを /etc/conf/cf.dに移動して下さい。現在の SHMMAX値をバイトで表示するためには下記を実行して 下さい。
./configure -y SHMMAXSHMMAXの新しい値を設定するためには、 valueが使おうとしている新しい値である場所で(バイトで) 下記を実行して下さい。
./configure SHMMAX=valueSHMMAXの設定が終ったら、カーネルをビルドし直して 下さい。
./link_unixそして再起動して下さい。
少なくともバージョン 2.6 では共有メモリセグメントの最大サイズは Postgresには低すぎる設定になっています。 必要な設定は/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://www.sunworld.com/swol-09-1997/swol-09-insidesolaris.html も参照して下さい。
UnixWare 7 では、共有メモリセグメントの最大サイズ はデフォルト設定で 512 kB です。これは-B 24 -N 12 にはおよそ十分です。現在のSHMMAX値を表示する ためには下記を実行して下さい。
/etc/conf/bin/idtune -g SHMMAXこれは現在の、デフォルトの、最小の、そして最大の、値をバイトで 表示します。SHMMAXの新しい値を設定するためには 下記を、valueが使おうとしている新しい値である 場所で(バイトで)実行して下さい。
/etc/conf/bin/idtune SHMMAX valueSHMMAXの設定が終ったらカーネルのビルドをし直し、
/etc/conf/bin/idbuild -B再起動して下さい。
UnixライクなオペレーティングシステムではPostgres サーバの操作と関係する可能性のある様々な種類のリソース制限が あります。重要なのは、特にユーザ毎のプロセス数の制限、 プロセス毎のオープンファイルの数、そして一つのプロセスに対して 有効なメモリの量です。これらのそれぞれが"ハード" と"ソフト"の二つの制限を持っています。ソフト制限が 実際に有効な制限ですが、ユーザによってハード制限まで変えることが 可能です。ハード制限はルートユーザによってのみ変えることができます。 システムコールsetrlimitがこれらのパラメータ の設定を行います。シェルに組み込まれたコマンドulimit (Bourne shells) もしくは limit (csh)は コマンドラインからリソース制限をコントロールするために使われます。 BSD で走るシステム上ではファイル/etc/login.conf が、様々なリソース制限がログイン時にどの値に設定されるかをコントロール します。詳細は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 を 見て下さい。
Postgresサーバはコネクション毎に一つの プロセスを使うので、少なくとも許可された接続の数だけのプロセス に残りのシステムで必要な分を追加したものが必要になります。 通常はこれは問題ではありませんが、一つのマシン上でいくつかの サーバを起動している場合は厳しい状況になるかもしれません。
オープンファイルの制限の出荷時のデフォルトは、しばしば大多数のユーザは マシン上でシステムリソースの不正使用をしないという前堤に立った "社会的に友好的な"値を設定してしまいます。 もし一つのマシン上で複数のサーバを起動する場合はそれが必要でしょうが、 専用サーバではこの制限を上げたいかもしれません。