强制PostgreSQL释放已分配的内存

3
我的Postgres在负载下达到了允许的最大内存(500MB),并运行了14个进程。一旦负载结束,Postgres仍然保留分配的内存并运行14个进程。由于我在同一台机器上运行Apache和Tomcat,我希望Postgresql释放已分配的内存。这可行吗?
谢谢!

你在哪个平台上运行PostgreSQL?用的是哪个版本? - Frank Bollack
4个回答

8
基本上,你需要从两个方面查看系统内存,特别是Postgres内存。
首先,是运行应用程序所需的内存。这是所有应用程序在生产环境中运行时的静态内存负载。如果您在所需负载下没有足够的内存,则没有足够的内存。现代系统可以在“危机”时利用交换空间,但仅此而已。简而言之,如果您正在使用交换空间,则表示您有内存危机,并且希望它很快消失。
一旦您拥有了应用程序所需的基本内存,所有剩余的系统内存基本上都专用于磁盘缓存。
在托管Postgres的系统中,您有两种类型的磁盘缓存。您有内核文件系统缓存,以及Postgres内部缓存。
Postgres内部缓存不会被释放。它不是这样工作的。您在配置中告诉它可以使用XXX内存量用于其目的,它将保留它。在此状态下,Postgres不关心系统上其他内容。
如果缓存是内核缓存,并且您在文件系统活动中突然出现了某些峰值,而这些峰值并非来自Postgres,则内核将缓存最近的页面并刷新较旧的页面。内核缓存将查看整个系统,而Postgres仅查看DB活动。
所以。
在Postgres的世界观中,内核缓存正在与其缓冲区缓存竞争。考虑以下情况。Postgres请求磁盘块。内核抓取该块并对其进行缓存。同时,Postgres从内核获取该块,并将其缓存。现在,该块被冗余缓存。如果内核找到了更好的用途来使用该块缓存内存,则会刷新出Postgres块,并加载新块。与此同时,Postgres将保留该块在其内部缓存中。
如果您有专用的Postgres机器,则没有太多理由拥有大量的内核缓存。由于所有的磁盘I/O都将是Postgres I/O,因此内核缓存是冗余的,并且不如Postgres缓存高效。当Postgres缓存块时,它必须将字节编组,更新其内部结构以及其他任何操作。一旦缓存,它就不再需要执行任何操作。因此,在Postgres缓存的块比由内核缓存的相同块更有效,因为移动块从内核缓存到Postgres中存在某些费用。
然而,如果您有一个混合使用的机器,那么内核和Postges缓存将不得不进行争斗。如果您的数据库足够小,可以将大部分日常操作数据放入RAM中,则应该有足够的缓冲空间在Postgres中处理大部分内存操作。这样,Postgres将一次加载其正常的“繁忙”页面并对其进行缓存,然后再也不会向内核请求它们。完成后,内核可以使用其缓冲区缓存来处理所有其他辅助系统请求。
在另一个极端,您可以给Postgres非常少的专用缓存,并让其完全依赖于内核缓存。这样,每个块每次从内核缓存中读取都会稍微更加昂贵,但远比每次从磁盘读取要便宜得多。通过这种方式,内核可以判断哪些进程更值得缓存注意。
实际上,确定Postgres的良好操作稳态并将其保持在该状态。任何活动的波动(例如报告的大型表扫描等)都将由内核缓存缓解,当该波动结束时,内核可以将该内存恢复到其他用途。
因此,底线是,Postgres不会归还任何内存。只需提供您能够分配给它的内存即可。

2
除了一些常见的进程,PostgreSQL会为每个连接运行一个进程,因此您应该检查应用程序(或连接池)的设置-如果连接在一段时间内未被使用是否会被释放。
但是我不认为这对于内存方面会有很大帮助,因为PG分配的主要内存部分是共享缓冲区,而这部分内存永远不会被释放。

0

Postgres使用大量内存通常是一件好事,因为它需要较少地访问磁盘。如果它可以将索引和最受欢迎的数据块存储在内存中,您可以实现非常高的缓存命中率,这会转化为快速的性能和在Java应用服务器中减少麻烦,因为请求在等待事务完成时被阻塞。

因此,通常情况下,您希望postgresql的缓存能够快速预热并保留在内存中。

话虽如此,您当然还需要内存来运行其他应用程序。您可以通过减少连接池上的最大连接数来减少每个请求的内存消耗。这反过来会限制postgres启动以处理请求和存储基于会话的临时数据的进程数量。

当然,您也可以调整共享缓冲区大小以获得更小的缓存。

另一种方法是减少Apache和Tomcat允许处理的并发请求数。如果您具有快速响应时间,则可以通过减少并发请求并在Apache中排队请求来获得更高的吞吐量。然后,您可以限制完整堆栈中的内存消耗,并通过限制负载来保持请求处理时间相对恒定。


0
在理想的设置中,您不会将数据库放置在Web服务器和应用程序服务器上。事实上,这些系统中的每一个都可能在自己的服务器上。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接