如何找到 postgresql 每个连接内存泄漏的来源?

Eri*_*sen 8 postgresql memory max-connections

我在 amazon RDS 上使用 postgresql 9.5.4 和来自 rails 4.2 的约 1300 个持久连接,并带有“prepared_statements: false”。在数小时和数天的过程中,“可释放内存”RDS 统计数据继续无限期地下降,但每次我们重新连接(重新启动我们的服务器)时都会跳回到一个相对较小的工作集。如果我们让它持续太长时间,它会一直为零,并且数据库实例确实开始进入交换并最终失败。从我们重新启动时的峰值中减去几天内的可用内存,我们看到每个连接平均有 10 MB。

在此处输入图片说明

从增强监控中挖掘每个 pid RSS,我们看到示例连接 pid 的增长同样缓慢,但总 RSS 似乎只是每个连接实际内存使用量的代理(https://www.depesz.com/2012/ 06/09/how-much-ram-is-postgresql-using/)。

在此处输入图片说明

我怎样才能:

  1. 更改下面的 default.postgres9.5 参数以避免每个连接无限制的内存增长
  2. 确定哪些查询会导致这种无限增长并更改它们以防止它
  3. 确定导致这种无限增长的缓冲/缓存类型,以便我可以使用它来执行上述任一操作

在此处输入图片说明

jja*_*nes 6

如果您使用的是社区 PostgreSQL,那么确定Linux 上内存去向的最终答案是使用 gdb 连接到臃肿的后端,p MemoryContextStats(TopMemoryContext)然后检查服务器日志文件的输出。但是由于您没有使用社区 PostgreSQL,我想最终的答案是联系您的付费支持并要求他们为您解决问题。

最可能的原因是 PostgreSQL 为每个连接缓存有关它在连接生命周期中触及的所有数据库对象(表、索引等)的元数据。这个缓存的大小没有上限,也没有过期的机制。因此,如果您拥有数十万或数百万个这样的东西,并且长期连接最终会触及其中的每一个,那么它们的内存使用量将不断增长。对此的通常解决方案(假设您不能减少数据库中的对象数量)是设置您的连接池程序,以便每个连接在关闭而不是回收之前都有最长的生存时间。