基本上,你需要从两个方面查看系统内存,特别是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不会归还任何内存。只需提供您能够分配给它的内存即可。