Ubuntu 10.04でPostgreSQL 8.4.5を実行しています。 nginxで実行されているいくつかのサイトでEC2インスタンスを実行しています。これらのサイトのほとんどはDjangoで実行され、このPostgresインスタンスに接続します。
なんらかの理由で、今夜の午後8時45分に、Postgresがダウンしました。マシンにログインすると、次のエラーメッセージが表示されます。
* Starting PostgreSQL 8.4 database server
* The PostgreSQL server failed to start. Please check the log output:
2011-04-17 04:46:49 UTC FATAL: could not create shared memory segment: Cannot allocate memory
2011-04-17 04:46:49 UTC DETAIL: Failed system call was shmget(key=5432001, size=16211968, 03600).
2011-04-17 04:46:49 UTC HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory or swap space. To reduce the request size (currently 16211968 bytes), reduce PostgreSQL's shared_buffers parameter (currently 1792) and/or its max_connections parameter (currently 53).
The PostgreSQL documentation contains more information about shared memory configuration.
...fail!
私が最初にしたことは、Linuxの共有メモリ割り当てを変更することでした。
sysctl -w kernel.shmmax=367108864>
sysctl -p /etc/sysctl.conf
それはそれをしませんでした。そこで、/etc/postgresql/8.4/main/postgresql.conf
を編集し、max_connections
の値を下げました。それはうまくいきました...約10分間。
max_connections
がいくら低くても、同じエラーが発生します。少なくとも9に設定する必要があります(これは、このPostgresサーバーにアクセスする必要があるDjangoプロジェクトの数であるため)。
これを修正する方法について何か考えはありますか?
'ipcs'コマンドを使用して、すべてのSHMセグメントを一覧表示できます。プログラムが削除せずにクラッシュした場合は、メモリを消費している可能性があります。これらは、「ipcrm」コマンドを使用して手動で削除できます。
より詳細なクラスターログを表示できますか?ポストマスターが勝手にクラッシュしていますか?どのコードをOSに返しますか? PostgreSQLクラスターはいくつありますか?メインは8.4個だけですか?
Kernel.shmallおよびkernel.shmmniはどうですか? ipcs -ml、ipcs -mを使用して、メモリ(無料、トップ、システムモニター)の使用状況を確認してください。 OOMキラーを落ち着かせてみてください:
vm.overcommit_memory = 2
vm.overcommit_ratio = 50
AFAIK sysctl -w
はパラメータを永続的に変更しません(次のOSの再起動までのみ)。/etc/sysctl.confにkernel.shmmax=367108864
を追加する必要があります。
可能であれば、 バージョン管理ポリシー で提案されているようにPostgreSQLを8.4.8にアップグレードします。
使用しているメジャーバージョンに関係なく、すべてのユーザーが最新の利用可能なマイナーリリースを実行することを常にお勧めします。
これはおそらくOOMキラーの問題だと思います。SIGKILLシグナルでポストマスターを強制終了し、共有メモリを解放せずに実行するからです。 ドキュメント を見てください:
重要:SIGKILLを使用してサーバーをシャットダウンしないことをお勧めします。そうすることで、サーバーが共有メモリとセマフォを解放できなくなり、新しいサーバーを起動する前に手動で実行する必要があります。さらに、SIGKILLはpostgresプロセスを強制終了しますが、シグナルをサブプロセスに中継させないため、個々のサブプロセスも手動で強制終了する必要があります。
および ここ :
n Linux 2.4以降では、デフォルトの仮想メモリの動作はPostgreSQLには最適ではありません。カーネルがメモリオーバーコミットを実装する方法のため、別のプロセスのメモリ要求によってシステムの仮想メモリが不足すると、カーネルはPostgreSQLサーバー(マスターサーバープロセス)を終了する場合があります。
ところで、max_connectionsは「安価」です。むしろ、shared_buffersを減らします。
いくつかのグーグルは、postgres shared_buffersおよびmax_connections数を減らす必要があることを示しています。 shared_buffersで何かしましたか?
postgresql共有メモリのドキュメント を確認しましたか? Linuxマシンで共有メモリパラメータを調整する方法については、そこに多くの詳細があります。