某天某个测试库在重启动后,抛出了无法启动的错误.
This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 17667276800 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
出现这个问题的主要原因是什么, 这就和我们的LINUX 系统的 sysctl.conf 中的关于内存的配置有关了.
通过 ipcs -l 来对当前的系统的
ipcs -l
注:ipc命令将有关活动进程间通信设施的信息写入标准输出
SHMMAX 主要限制的是LINUX 系统上的共享内存段的尺寸,SHMALL限制的是在LINUX 系统中共享内存页面.
实际上POSTGRESQL 是有一个下面的SHELL程序来计算当前你的服务器如果是安装POSTGRESQL的服务器应该如何来分配shmmax 和 shmall 这两个值的
#!/bin/bash
# simple shmsetup script
page_size=`getconf PAGE_SIZE`
phys_pages=`getconf _PHYS_PAGES`
shmall=`expr $phys_pages / 2`
shmmax=`expr shmall * page_size`
echo kernel.shmmax = $shmmax
echo kernel.shmall = $shmall
结果得到下面的值,我们将这两个值填写到
代码语言:javascript复制/etc/sysctl.conf
kernel.shmmax = 4040679424
kernel.shmall = 986494
重新启动服务器,Postgresql ,结果启动成功
为什么刚才POSTGRESQL 会启动失败
主要的原因是,shared_buffers 分配的过大造成LINUX 系统中的 kernel.shmmax 的共享内存段无法分配,导致POSTGRESQL 无法启动
实际上根据德哥 2016年-11-21 的文档,关于OS 内核参数的设置中有说明,见下图,所以在安装POSTGRESQL 和可以遵循.
那么其他的数据库在这两个参数的设计上有什么不同
DB2 建议将所有的内存都进行相关的配置
ORACLE 建议是内存的一半
另外在一篇文档中提及
In 9.3, PostgreSQL has switched from using SysV shared memory to using Posix shared memory and mmap for memory management. This allows easier installation and configuration of PostgreSQL, and means that except in usual cases, system parameters such as SHMMAX and SHMALL no longer need to be adjusted.
在POSTGRESQL 9.3 以后,系统使用的内存管理转移到posix 和 mmap 的方式管理, 对于 shmmax shmall 的配置不在强制需求.
那么我们提出一个问题, 为什么到目前为止 DB2 ORACLE 还需要进行这样的设置, 而 MYSQL ,MONGODB , POSTGRESQL 高版本基本上可以不设置或基本设置就可以了.
其实在于在LINUX 系统中使用内存的方式
目前基于 sysV , POSIX , mmap 的方式
实际上目前POSTGRESQL 12.2 11.2 等版本(> 9.3) 的版本都不会在默认使用sysv 的方式来使用内存了, sysv 主要的问题在于他允许不相关的进程来使用共享内存
下面的文字中体现了POSTGRESQL 使用管理共享内存的方式
If you're on posix system without mmap, you'd use posix_shm. If you're on a unix without posix_shm you'd use sysv_shm. If you only need to share memory vs a parent/child you'd use mmap if available.
如果你在没有mmap的posix系统上,你可以使用posix_shm。如果你在没有posix_shm的unix上,你会使用sysv_shm。如果您只需要与父/子共享内存,则可以使用mmap(如果可用)。
postgresql 使用内存的方式是 mmap > sysv
mmap优点总结
- 对文件的读取操作跨过了页缓存,减少了数据的拷贝次数,用内存读写取代I/O读写,提高了文件读取效率。
- 实现了用户空间和内核空间的高效交互方式。两空间的各自修改操作可以直接反映在映射的区域内,从而被对方空间及时捕捉。
- 提供进程间共享内存及相互通信的方式。...
- 可用于实现高效的大规模数据传输。
具体为什么POSTGRESQL 9.3 后不再强制设置 kernel.shmmax 和
kernel.shmall ,还的找时间去查,但可以证明的是,如果shmmax shmall 动了设置,并且share buffer 设置的过大 大过了 shmmax的情况下,POSTGRESQL 是无法启动的.