
PostgreSQL的最佳性能取决于正确定义的操作系统参数。 操作系统内核参数调整不当会降低数据库服务器的性能。 因此,必须根据数据库服务器及其工作负载来配置这些参数。 在本文中,我们将讨论一些重要的Linux内核参数,这些参数可能会影响数据库服务器的性能以及如何对其进行调优。
SHMMAX / SHMALL
SHMMAX是一个内核参数,用于确定Linux进程可以分配的单个共享内存段的最大大小。 在9.2版之前,PostgreSQL使用System V(SysV),它需要SHMMAX配置。 9.2之后,PostgreSQL切换到POSIX共享内存。 因此,现在需要更少的System V共享内存字节。
在9.3版之前,SHMMAX是最重要的内核参数。 SHMMAX值以字节为单位指定。
同样,
SHMALL是另一个用于确定
系统范围的共享内存页面。 使用
ipcs命令查看当前的SHMMAX,SHMALL或SHMMIN
值 。
SHM *详细信息-Linux$ ipcs -lm ------ Shared Memory Limits -------- max number of segments = 4096 max seg size (kbytes) = 1073741824 max total shared memory (kbytes) = 17179869184 min seg size (bytes) = 1
SHM *详细信息-MacOS X $ ipcs -M IPC status from as of Thu Aug 16 22:20:35 PKT 2018 shminfo: shmmax: 16777216 (max shared memory segment size) shmmin: 1 (min shared memory segment size) shmmni: 32 (max number of shared memory identifiers) shmseg: 8 (max shared memory segments per process) shmall: 1024 (max amount of shared memory in pages)
PostgreSQL使用
System V IPC分配共享内存。 此参数是最重要的内核参数之一。 每当您收到以下错误消息时,就意味着您具有较低版本的PostgreSQL,并且SHMMAX值非常低。 期望用户将根据他们将要使用的共享内存来调整和增加该值。
可能的配置错误
如果未正确配置SHMMAX,则尝试使用
initdb命令初始化PostgreSQL集群时可能会收到错误消息。
initdb失败DETAIL: Failed system call was shmget(key=1, size=2072576, 03600).
HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.
You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 2072576 bytes),
reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.
The PostgreSQL documentation contains more information about shared memory configuration. child process exited with exit code 1
同样,使用
pg_ctl命令启动PostgreSQL服务器时,您可能会收到错误消息。
pg_ctl故障DETAIL: Failed system call was shmget(key=5432001, size=14385152, 03600).
HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.
You can either reduce the request size or reconfigure the kernel with larger SHMMAX.; To reduce the request size (currently 14385152 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.
The PostgreSQL documentation contains more information about shared memory configuration.
了解定义上的差异
在Linux和MacOS X上,SHMMAX / SHMALL参数的定义略有不同:
- Linux:kernel.shmmax,kernel.shmall
- MacOS X:kern.sysv.shmmax,kern.sysv.shmall
sysctl命令可用于临时更改值。 要设置常量值,请在
/etc/sysctl.conf中添加一个条目。 细节在下面给出。
在MacOS X上更改内核设置 # Get the value of SHMMAX sudo sysctl kern.sysv.shmmax kern.sysv.shmmax: 4096 # Get the value of SHMALL sudo sysctl kern.sysv.shmall kern.sysv.shmall: 4096 # Set the value of SHMMAX sudo sysctl -w kern.sysv.shmmax=16777216 kern.sysv.shmmax: 4096 -> 16777216 # Set the value of SHMALL sudo sysctl -w kern.sysv.shmall=16777216 kern.sysv.shmall: 4096 -> 16777216
更改Linux内核参数 # Get the value of SHMMAX sudo sysctl kernel.shmmax kernel.shmmax: 4096 # Get the value of SHMALL sudo sysctl kernel.shmall kernel.shmall: 4096 # Set the value of SHMMAX sudo sysctl -w kernel.shmmax=16777216 kernel.shmmax: 4096 -> 16777216 # Set the value of SHMALL sudo sysctl -w kernel.shmall=16777216 kernel.shmall: 4096 -> 16777216
记住 :要使更改永久生效 ,请将这些值添加到/etc/sysctl.conf中大页面(大页面)
Linux默认为4K页面,BSD使用
Super Pages ,Windows使用
Large Pages 。 页面是分配给进程的一块RAM。 一个进程可以有几页,具体取决于内存要求。 一个进程需要的内存越多,分配给它的页面就越多。 操作系统支持进程的页面分配表。 页面大小越小,表越大,则在此页面表中查找页面所花费的时间越长。 因此,大页面使您可以减少开销来使用大量内存。 更少的页面浏览量,更少的页面错误,通过大型缓冲区的更快的读/写操作。 结果是提高了性能。
PostgreSQL在Linux上仅支持大页面。 默认情况下,Linux使用4 KB的内存页面,因此,如果您执行了太多的内存操作,则必须安装更大的页面。 使用2 MB和最大1 GB的大页面时,性能会有所提高。 可以在启动时设置较大的页面大小。 您可以使用
cat / proc / meminfo |命令轻松检查大页面的参数及其在Linux计算机上的使用
。 grep -i巨大 。
获取有关大页面的信息(仅Linux) Note: This is only for Linux, for other OS this operation is ignored$ cat /proc/meminfo | grep -i huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
在此示例中,尽管大页面大小设置为2048(2 MB),但大页面总数为0。这意味着大页面被禁用。
确定大页数的脚本
这个简单的脚本返回所需的大页面数。 当PostgreSQL运行时,在Linux服务器上运行脚本。 验证是否为
$ PGDATA环境变量设置了PostgreSQL数据目录。
获取所需的大页面数
脚本输出如下:
脚本输出 Pid: 12737 VmPeak: 180932 kB Hugepagesize: 2048 kB Set Huge Pages: 88
大页面的建议值为88,因此应将其设置为88。
安装大页面 sysctl -w vm.nr_hugepages=88
现在检查大页面,您会看到未使用大页面(HugePages_Free = HugePages_Total)。
再次关于大页面的信息(仅Linux) $ cat /proc/meminfo | grep -i huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 88 HugePages_Free: 88 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
现在将huge_pages设置为$ PGDATA / postgresql.conf并重新启动服务器。
同样,有关大页面的信息(仅Linux) $ cat /proc/meminfo | grep -i huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 88 HugePages_Free: 81 HugePages_Rsvd: 64 HugePages_Surp: 0 Hugepagesize: 2048 kB
现在您可以看到很少使用大页面。 现在让我们尝试向数据库中添加一些数据。
一些用于回收大页面的数据库操作 postgres=
让我们看看我们现在是否使用比以前更大的页面。
再次在大页面上显示信息(仅Linux) $ cat /proc/meminfo | grep -i huge AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 88 HugePages_Free: 18 HugePages_Rsvd: 1 HugePages_Surp: 0 Hugepagesize: 2048 kB
现在您可以看到大多数大页面都在使用中。
注意:此处使用的HugePages的近似值非常低,对于食品环境中的机器而言,这不是正常值。 请评估系统所需的页面数,然后根据负载和资源进行相应设置。vm.swappiness
vm.swappiness是另一个可以影响数据库性能的内核参数。 此参数用于控制Linux上的交换行为(在内存之间交换页面)。 取值范围是0到100。它确定要卸载或卸载多少内存。 零表示禁用交换,而100表示积极交换。
通过设置较低的值可以获得良好的性能。
在较新的内核中将该值设置为0可能会导致OOM Killer(Linux内存清除进程)终止该进程。 因此,如果要最小化交换,可以安全地将值设置为1。 Linux上的默认值为60。较高的值会使MMU(内存管理单元)使用比RAM更多的分页空间,而较低的值会将更多的数据/代码保存在内存中。
较低的值可以提高PostgreSQL的性能。
vm.overcommit_memory / vm.overcommit_ratio
应用程序接收内存并在不再需要时释放它。 但是在某些情况下,应用程序获取的内存过多,无法释放它。 这可能会导致OOM杀手。 以下是
vm.overcommit_memory参数的可能值,并提供了每个说明:
- 启发式过量使用(默认); 基于核心的启发式
- 仍然允许过量使用
- 不要过度使用,不要超过过量使用比例。
链接: https : //www.kernel.org/doc/Documentation/vm/overcommit-accountingvm.overcommit_ratio-可用于过载的RAM百分比。 在具有2 GB RAM的系统中,值为50%最多可以分配3 GB RAM。
vm.overcommit_memory的值为2可为PostgreSQL提供更好的性能。 此值可最大程度地提高服务器进程的RAM使用率,而不会有被OOM杀手进程杀死的任何重大风险。 该应用程序将能够重新启动,但只能在超支范围内重新启动,从而降低了OOM杀手杀死进程的风险。 因此,值2的性能比默认值0更好。但是,可以通过确保不会超出可接受范围的内存来提高可靠性。 这消除了该过程将被OOM杀手杀死的风险。
在非分页系统上,vm.overcommit_memory等于2可能会出现问题。
https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMITvm.dirty_background_ratio / vm.dirty_background_bytes
vm.dirty_background_ratio是需要写入磁盘的脏页所占内存的百分比。 在后台重置为磁盘。 该参数的取值范围是0到100。 但是,低于5的值可能无效,并且某些内核不支持该值。 在大多数Linux系统上,默认值为10。 您可以以较低的速度提高密集记录操作的性能,这意味着Linux将在后台转储脏页。
您需要根据磁盘速度设置
vm.dirty_background_bytes的值。
这两个参数没有“好”值,因为这两个参数均取决于硬件。 但是,在大多数情况下,将vm.dirty_background_ratio设置为5并将vm.dirty_background_bytes设置为磁盘速度的25%会将性能提高到25%。
vm.dirty_ratio /脏字节
这与
vm.dirty_background_ratio / dirty_background_bytes相同,除了在工作会话中执行重置会阻止应用程序。 因此,vm.dirty_ratio应该高于
vm.dirty_background_ratio 。 这样可以确保后台进程将尽早启动,从而避免尽可能多地阻塞应用程序。 您可以根据磁盘I / O负载来调整这两个比率之间的差异。
总结
您可以配置其他参数来提高生产率,但是这种改进将是微不足道的,并且您不会获得太多收益。 我们必须记住,并非所有参数都适用于所有类型的应用程序。 当我们配置某些设置时,某些应用程序可以更好地工作,而有些则不能。 您必须在预期工作量和应用程序类型的这些参数的配置之间找到适当的平衡,并且在配置时,必须考虑操作系统的行为。 配置内核参数并不像调整数据库参数那样容易:在此处给出建议更加困难。