PostgreSQL用户常常发现,服务端在连接数较大的状况下,会呈现零碎内存耗费过多的状况,严重者可能会造成OOM。然而服务端配置的共享内存(shared_buffers,wal_buffers等)是肯定的,为什么内存会继续减少呢?这就与PostgreSQL的多过程架构无关了,上面咱们来剖析下。

1. 大规格PG实例内存使用率较高剖析

为了保障物理内存能失去充沛的利用,防止内存空间节约,Linux把过程以后应用的内存局部加载到物理内存里,而不应用的局部则暂不加载。PostMaster过程注册共享内存时,零碎只是调配一个虚构的地址空间,并不间接调配物理内存。当有理论的内存拜访时,CPU才会将虚构地址映射到物理内存的一个地址上。保护这个映射关系的就是PageTable,它负责将虚拟内存地址转换成物理内存地址。

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

对于PostgreSQL这种多过程架构程序来说,当服务端应用的共享内存较大,且并发连接数较多时,因为操作系统对于每个过程都要保护独自的内存映射,PageTable中的元组数目将会变得十分多,所占用的内存大小也会特地大。

2. 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            -- 注册共享内存时不应用大页

实在利用场景:某PG用户将实例(shared_buffers = 64GB)部署在一台内存为256GB的ECS上,业务忙碌时ECS内存使用率为85%,PageTable占用内存120GB。而开启Huge Page后雷同业务场景的内存使用率升高到50%以下,PageTable大小仅300M!

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

(5)确认是否配置胜利。能够看到Huge Page总数为78643

(6)确认PG配置文件关上huge_pages

(7)启动PostgreSQL服务端,能够看到零碎中的闲暇Huge Page曾经缩小,局部大页曾经被共享内存应用。

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写抵触的产生概率。

所以强烈推荐PG实例开启Huge Page的场景:共享内存应用较大(>=8GB)且连接数较多(>= 500),并且热点数据扩散。不举荐PG实例开启Huge Page的场景:写业务密集,热点数据集中且内存应用较小。

5.PG开启Huge Page时的注意事项

(1)当配置参数huge_pages设置为on时,若PG启动时须要注册的共享内存大于操作系统提供的Huge Page大小时,数据库将无奈启动。举荐将huge_pages参数设置为try,在此种场景下,PostMaster将会改为申请一般内存。

(2)批改shared_buffers/wal_buffers等共享内存相干的GUC参数时,须要从新计算操作系统所需的Huge Page数,以防服务端无奈启动或者局部大页内存没有被应用且无奈开释而造成节约。

点击关注,第一工夫理解华为云陈腐技术~