PostgreSQL不会启动,因为它“无法分配内存”

我在Ubuntu 10.04上运行PostgreSQL 8.4.5。 我运行一个ECN实例,在nginx上运行几个站点。 大多数这些网站在Django上运行并连接到这个Postgres实例。

出于某种原因,今天晚上8:45,Postgres倒下了。 我login到机器,我看到这个错误消息:

* 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分钟。

现在我得到了同样的错误,不pipemax_connections多低。 我需要将它设置为至less9(因为这是需要访问此Postgres服务器的Django项目的数量)。

任何想法如何我可以去解决这个问题?

您可以使用'ipcs'命令列出所有的SHM段。 如果一个程序崩溃而不删除它们,它们可能正在消耗内存; 您可以使用“ipcrm”命令手动删除这些文件。

一些谷歌search表明,你应该减lesspostgres shared_buffers max_connections数字。 你有没有做任何与shared_buffers呢?

您是否查看过postgresql共享内存文档 ? 在那里有很多关于如何调整Linux机器上的共享内存参数的细节。

你能显示更详细的集群日志吗? 是邮政大臣任意崩溃? 哪个代码返回到操作系统? 你有多less个PostgreSQL集群,只有8.4 / main?

那你的kernel.shmall和kernel.shmmni呢? 尝试使用ipcs -ml,ipcs -m并检查你的内存(free,top,System Monitor)的使用情况。 尝试冷静OOM杀手:

 vm.overcommit_memory = 2 vm.overcommit_ratio = 50 

AFAIK sysctl -w不会永久更改参数(仅在下一次操作系统重新引导之前),并且需要将kernel.shmmax=367108864添加到/etc/sysctl.conf。

如果可能,请按照版本控制策略中的build议将PostgreSQL升级到8.4.8:

我们总是build议所有用户运行最新版本的次要版本,以便使用任何主要版本。

我认为这可能是OOM杀手问题,因为它用SIGKILL信号杀死postmaster 而不释放共享内存。 看文档 :

重要提示:最好不要使用SIGKILL来closures服务器。 这样做会阻止服务器释放共享内存和信号量,这可能必须在新服务器启动之前手动完成。 此外,SIGKILL杀死postgres进程而不让信号传递给subprocess,所以有必要手工杀死各个subprocess。

这里 :

在Linux 2.4和更高版本中,默认的虚拟内存行为对于PostgreSQL来说并不是最优的。 由于内核实现内存过量使用的方式,如果另一个进程的内存需求导致系统耗尽虚拟内存,内核可能会终止PostgreSQL服务器(主服务器进程)。

顺便说一句,max_connections是“便宜”。 而是减lessshared_buffers。