mta*_*ott 19 memory postgresql centos centos6 postgresql-9.3
我试图找出为什么~30个空闲的postgres进程在正常使用后会占用如此多的特定于进程的内存.我正在使用Postgres 9.3.1和CentOS版本6.3(最终版).使用top,我可以看到许多postgres连接使用高达300mb(平均~200mb)的非共享(RES-SHR)内存:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3534 postgres 20 0 2330m 1.4g 1.1g S 0.0 20.4 1:06.99 postgres: deploy mtalcott 10.222.154.172(53495) idle
9143 postgres 20 0 2221m 1.1g 983m S 0.0 16.9 0:14.75 postgres: deploy mtalcott 10.222.154.167(35811) idle
6026 postgres 20 0 2341m 1.1g 864m S 0.0 16.4 0:46.56 postgres: deploy mtalcott 10.222.154.167(37110) idle
18538 postgres 20 0 2327m 1.1g 865m S 0.0 16.1 2:06.59 postgres: deploy mtalcott 10.222.154.172(47796) idle
1575 postgres 20 0 2358m 1.1g 858m S 0.0 15.9 1:41.76 postgres: deploy mtalcott 10.222.154.172(52560) idle
Run Code Online (Sandbox Code Playgroud)
总共有29个空闲连接.这些空闲连接在内存中不断增长,直到机器开始使用交换,然后性能停止.正如预期的那样,重置连接会清除特定于进程的内存.当我定期重新连接时,同一台机器上相同数量的连接仅使用20%的内存(0交换).这些流程持有什么样的信息?我希望长时间运行的闲置postgres进程具有与全新的闲置进程相似的内存使用率.
值得注意的是:我大量使用模式.在我的应用程序的每个请求,我正在设置和重置search_path.
mta*_*ott 14
这些流程持有什么样的信息?我希望长时间运行的闲置postgres进程具有与全新的闲置进程相似的内存使用率.
实际上,Postgres加载后会在本地内存中缓存一些内容:
对于大多数用例,所有这些都加起来可以忽略不计.这里的关键是模式的大量使用和对relcache的影响.该数据库包含~500个模式,每个模式具有相同的~90个表.对于Postgres,即使模式完全相同,这也可以达到45,000个表(500*90).
每个请求都在内存中缓存了一些表的关系描述符(通常在与之前的请求不同的模式中),逐渐填充relcache.不幸的是,Postgres没有提供限制这些缓存大小的方法,因为对于大多数用例来说,开销可能会适得其反.
可能的解决方案:
感谢Tom Lane和Merlin Moncure在Postgres邮件列表上的帮助.