数据库的内存架构对数据库的性能影响十分大,PG这些年的发展十分快,其内存架构的核心部分除了共享池外,都和Oracle有一定的类似。下图是PG内存架构的一张逻辑示意图。这些结构中,shared memory对PG数据库的性能影响很大。在PG中最为重要的共享内内存缓冲包含shared buffer pool,wal buffer和commit log。
今天我们重点讨论一下shared_buffer,对应于Oracle数据库就是db cache或者buffer cache。作为一个Oracle DBA,在看待任何数据库的时候总是会和Oracle去比对。前阵子老白也写过一个关于PG的SHARED BUFFER的文章,发现SHARED BUFFER的设计思路与Oracle的DB CACHE十分类似。既然二者的作用是类似的,实现方法是类似的,那么我们按照配置Oracle DB CACHE的方式去把PG的SHARED BUFFER设置为物理内存的50%左右不就好了吗?
事实上,虽然二者的功能相同,实现方式类似,甚至PG目前的很多的SHARED BUFFER的实现算法都参考了Oracle的DB CACHE,但是二者在内部的差异还是十分巨大的。为什么呢?这和Oracle与PG的数据库的存储结构有关。Oracle数据库的数据库物理结构是基于表空间与数据文件这个基础架构的。PG也有表空间,也是和Oracle类似,表空间是一个逻辑概念。不过Oracle的数据文件结构是和PG完全不同的。Oracle的数据文件是预分配的,确定的,在操纵系统中,数据文件的每个块的地址都是已知的。因此Oracle能够更加自主的控制对物理文件上的数据的读写,利用DB CACHE和预读机制来减少IO。早期的Oracle DBA都会有这个感受,使用了裸设备之后,比使用文件系统,IO总体性能会有一定的提升,这个提升幅度在5%左右。从使用裸设备比使用文件系统总体IO性能有所提升可以看出,Oracle 的DB CACHE+预读机制基本上可以替代文件系统缓冲,因此Oracle数据库不需要使用过多的操纵系统缓冲(不是完全不使用,而是不需要过多使用,实际上文件系统缓冲对于ORACLE提升文件系统的读IO还是有帮助的,甚至对于裸设备,裸设备的块设备缓冲对IO性能也是有提升的,最为典型的就是AIX系统的PBUF)。
而PG则不同了,PG的数据物理存储结构是按文件的,每个表对应的是几个数据文件,因此所有的文件IO加速机制都是和表相关的,不像ORACLE的预读机制,是针对数据文件的。PG如果要做预读,效率会低得多。因此对于文件系统的IO优化,PG更多的是交给操纵系统来做的。因此,操纵系统的文件缓冲与虚拟内存的配置会对PG数据库的性能有着十分重要的影响。
基于这个特点,实际上PG数据库在配置SHARED BUFFER POOL的时候,就不能参考Oracle的经验了。PG的官方文档建议把SHARED BUFFER POOL设置为整个屋内内存的15-25%,对于一个32G以上的数据库服务器,建议的SHARED BUFFER POOL的大小是8GB。目前64G甚至更大内存的服务器都已经十分普及了,所以这个8GB的设置建议偏保守了一点,如果你有一台具有128G甚至更大内存的服务器,那么配置几十个G的SHARED BUFFER POOL还是没啥问题的。不过一般来说,对于大内存的服务器,配置20%的物理内存给SHARED BUFFER POOL就足够了。
刚才我们讨论过,对于PG数据库IO性能影响最大的还有另外一个因素,就是操纵系统的文件缓冲。对PG数据库来说,较优的模式是将50%的物理内存用于文件系统缓冲。对于某些小型机操纵系统,比如AIX,HP-UX,可以通过操纵系统的参数比较精准的控制文件系统缓冲的大小。而对于LINUX操纵系统,这是十分复杂的,我们需要通过一系列的VM参数来进行综合调整,大体控制文件系统缓冲的大小。不幸的是,我们目前绝大多数PG都是跑在LINUX上。对于如何通过VM参数的调整来让PG能够在最优化的文件系统缓冲上跑是个十分复杂的问题,甚至50%的比例也不一定是 较优的,我最近在REDDIT上看过一些老外的研讨,最终结论也是不确定的。不过有一点是明确的,那就是无论如何,尽可能不要产生较大的换页,产生较大的换页,可能会导致PG总体性能的不稳定。
最后我们必须来聊聊预制相关的EFFECTIVE_CACHE_SIZE参数,许多PG用户可能对这个参数比较迷惑。有些用户把这个参数看成是PG使用文件系统缓冲的大小,这其实是一个误解。在LINUX中,如何有效的控制文件系统缓冲的大小是十分困难的。实际上这个参数只是一个用于CBO优化器估算成本使用的参数,而不是实际上PG使用文件系统缓冲的大小。这个参数的默认值是OS内存的50%,从这里也可以看出,PG希望能够使用50%的物理内存作为文件系统缓冲,从而优化IO。这个参数对于索引扫描的成本估算十分关键,如果这个参数设置的较大,则在CBO优化器中,计算出来的索引扫描的成本也就越低。