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