12月06, 2020

PostgreSQL DBA 数据库优化建议

当使用PostgreSQL作为数据存储时,对于大内存服务器并且有大量写入和查询操作,有两条优化建议:

  • 刷脏页的调度可能需要优化
  • 虚拟内存与物理内存映射表相关的部分需要优化

1. 脏页调度优化

当大量更新删除操作发生时,PostgreSQL并不会马上旧的版本,而是保留以前多个版本的数据,而vaccum进程会定期清理做版本合并。因此vaccum在什么时机启动清理有一些相关的配置参数如下:

1) 调整后台进程刷脏页的阈值、唤醒间隔、以及老化阈值。(脏页大于多少时开始刷、多久探测一次有多少脏页、刷时多老的脏页刷出

vm.dirty_background_bytes = 4096000000    
vm.dirty_background_ratio = 0    
vm.dirty_expire_centisecs = 6000    
vm.dirty_writeback_centisecs = 100    

2) 用户进程刷脏页调度,当脏页大于多少时,用户如果要申请内存,需要协助刷脏页

vm.dirty_bytes = 0    
vm.dirty_ratio = 80

2. 启用huge table,内存表映射优化

1)大规格PG实例内存使用率较高分析

PostgreSQL用户经常发现,服务端在连接数较大的情况下,会出现系统内存消耗过多的情况,严重者可能会造成OOM。但是服务端配置的共享内存(shared_buffers,wal_buffers等)是一定的,为什么内存会持续增加呢?

为了保证物理内存能得到充分的利用,避免内存空间浪费,Linux把进程当前使用的内存部分加载到物理内存里,而不使用的部分则暂不加载。PostMaster进程注册共享内存时,系统只是分配一个虚拟的地址空间,并不直接分配物理内存。当有实际的内存访问时,CPU才会将虚拟地址映射到物理内存的一个地址上。维护这个映射关系的就是PageTable,它负责将虚拟内存地址转换成物理内存地址。

Linux的内存管理采取的是分页存取机制:把较大的物理内存分为了一个个固定大小(4kB)的内存页进行管理。每块内存页通过PageTable中的一个元组来维护虚拟/物理内存之间的映射。CPU为了提高虚拟/物理内存之间的转换效率,也会在TLB中缓存一定量的Page Table元组。

对于PostgreSQL这种多进程架构程序来说,当服务端使用的共享内存较大,且并发连接数较多时,由于操作系统对于每个进程都要维护单独的内存映射,PageTable中的元组数目将会变得非常多,所占用的内存大小也会特别大。

2) Huge Page改善措施

为了提升转换性能,最好这部分能够cache在cpu的cache里面。页越大,映射表就越小。使用huge page可以减少页表大小。

Linux为了应对这种场景,降低多进程下PageTable的内存消耗。自从2.6及以上内核版本提供了内存页大小为2MB的管理方式,称为Huge Page。如果使用Huge Page的话,相同物理内存使用量的情况下内存页的数目变少,减少了PageTable元组的条目个数,从而降低了系统的内存占用。

作为世界上最先进的开源数据库,PostgreSQL也适配了Linux的Huge Page特性,服务端在注册共享内存时,会通过配置参数huge_pages来决定是否申请大页内存。

postgresql.conf:
    huge_pages = on             -- 注册共享内存时必须使用大页
    huge_pages = try            -- 注册共享内存时首先考虑大页,若系统提供的大页内存不足时,则全部使用普通页
    huge_pages = off            -- 注册共享内存时不使用大页

3) PG实例开启Huge Page操作步骤

(1)查看操作系统的Huge Page大小

grep Hugepage /proc/meminfo

(2)估算PostgreSQL实例需要的Huge Page使用量:128GB/2MB * 1.2 = 78643



(3)/etc/sysctl.conf中添加:vm.nr_hugepages = 78643



(4)重新加载系统配置参数:sysctl –p /etc/sysctl.conf



(5)确认是否配置成功。可以看到Huge Page总数为78643

sysctl -a | grep huge



(6)确认PG配置文件打开huge_pages



(7)启动PostgreSQL服务端,可以看到系统中的空闲Huge Page已经减少,部分大页已经被共享内存使用。

(8)top -u postgres 检验内存占用量 同样使用share_buffer=16GB,开启huge table后减少了2GB内存的使用,但查询性能没有变化

4) Huge Page使用建议



虽然Huge Page在一定场景下可以改善服务端内存使用过高的情况,但不是鼓励所有的PG实例都使用大页,盲目的开启Huge Page可能引起服务端的性能下降。下面我们根据Huge Page的优缺点来分析下使用场景。

Huge Page优势:



(1)CPU的TLB可以缓存的物理地址空间更大,从而提升TLB的命中率,降低CPU负载;



(2)Huge Page使用的内存是不可交换(swap)的,没有内存空间换入/换出的开销;



(3)极大的减少了系统维护PageTable的内存开销。



Huge Page劣势:



(1)Huge Page使用的内存需要预先分配;



(2)Huge Page使用固定大小的内存区域,不会被释放;



(3)对于写密集型的场景,Huge Page会加大Cache写冲突的发生概率。



本文链接:http://57km.cc/post/PostgreSQL performance optimization for DBA.html

-- EOF --

Comments