PostgreSQL在LINUX上运行的配置其实很简单,基本上不需要调整任何操作系统参数和PG参数就能够完成安装,并开始使用。这得益于PG社区的研发人员在LINUX适配与PG出厂参数上做的长期优化。和Oracle数据库不同,关于PG参数优化的资料都十分简单,实际上PG的参考手册里对这些有着十分好的建议。虽然如此,还是有几个在PG安装与使用中经常会被忽视或者误用的配置。今天老白和大家一起探讨一下,观点不一定完全准确,也不一定能够适用于所有的场景,不过在一些针对性的场景下,还是有一定的作用的。首先是OS方面的参数,实际上PG安装时不需要调整任何OS参数基本上就能顺利完成,不过在使用时还是需要关注一下IPC相关的参数,比如SHM和SEM类的参数。目前的LINUX服务器模式的缺省安装基本上都能够满足一般的PG应用的要求,不过对于max_connections十分大的系统,还是要适当的调大SEM类的参数,SEM是UNIX系统中的信号灯,PG的进程间的IPC通讯与同步协调都依赖于信号灯。除了IPC方面的OS参数,虚拟内存方面的参数也是要关注的。vm.swappiness参数是最值得关注的,和其他数据库系统(比如Oracle,Mysql)等一样,swappiness参数建议设置为小于10的(比如0或者1)。另外一个需要关注的参数是要看场景的,如果物理内存不是十分充裕的环境下,一定要设置vm.overcommit_memory参数。这个参数的含义是当进程分配内存时,内存出现不足情况下的策略。LINUX的缺省值是0,意思是当分配内存时如果当前物理内存剩余量不足则直接失败,当某些backend进程和系统进程出现内存分配不足时会报错,甚至会宕掉。在物理内存比较紧张的系统里,建议把这个参数设置为非0的值。设置为1表示允许分配所有的物理内存,不管当前内存的状态如何,设置为2的含义是允许分配超过物理内存+SWAP总和的内存,也就是允许内存超配。在这种情况下,建议将overcommit_memory设置为2。不过这种设置也还是存在风险的,在比较严重的情况下,会出现物理内存与SWAP都耗尽。因此还有一种折中的方式,就是对PG的系统进程进行保护。为什么要进行保护呢?这是和LINUX 2.6以后的内核引入了OOM KILLER有关,在物理内存不足的情况下,SWAP快要耗尽的时候,OOM KILLER就会发挥作用,OOM SCORE较高的进程杀掉,从而释放内存,保证LINUX不会因为内存资源耗尽而HANG死。如果不设置overcommit_memory参数,那么把PG系统进程的OOM SCORE调低,让OOM KILLER不会杀死PG系统进程,也就可以有效的保护PG实例了。具体方法是将PG系统进程的oom_score_adj设置为-1000,这样PG系统进程的OOM SCORE就永远为0了,也就不会被杀掉了。比如:
看到postgres的后台写进程的Pid是8792,于是我们来看看这个进程的OOM SCORE:
我们在/proc目录下找到这个进程,然后看到oom_score是83,这是比较高的分数,当物理内存不足的时候很容易被干掉。通过设置oom_score_adj为-1000后,我们发现,这个进程的OOM_SCORE变成0了。实际上我们通过D-SMART的OOM检查工具发现
排名靠前的进程基本上大多数是PG的系统进程。因此这种保护对于物理内存不是十分富裕的PG运行环境还是十分必要的(特别是一些云主机环境下)。在PG的配置参数中,也有几个容易被忽略的参数。比如log_line_prefix,这个参数大多数用户都不会去修改它,都是用缺省值。这个参数定义了PG日志的每一行的开头部分的格式。我们在很多时候做故障定位都会用到日志,当我们分析日志的时候总是希望能够看到更为丰富的信息,从而定位到底哪个会话或者哪个系统进程出了问题。通过这个参数设置,可以让日志输出一些有价值的信息。比如log_line_prefix='%t:%r:%u@%d:[%p]: '
%t: Timestamp
%u: Database username
%r: Remote host connection
%d: Database
%p: Process ID of connection
如果我们设置成这样,一旦有日志输出,我们就可以知道上面时间,在哪个数据库上,哪个远程主机通过哪个PG账号链接上来的进程ID是多少的会话输出了什么日志,是不是很有价值?最后我们谈一个更容易被忽视或者误解的参数,EFFECTIVE_CACHE_SIZE,这个参数并不能实际控制多少物理内存被用于PG的读缓冲,它是被PG CBO优化器用来评估索引扫描与顺序扫描等操作的成本的,这个参数的设置会影响到SQL执行计划。不过要注意的是,仅仅针对大型的PG数据库,这个影响才会较为显著,对于小型数据库,这个影响往往是比较小的。