调试高PostgreSQL内存使用率(每个连接)



是否有任何方法可以检查分配给每个连接的内存实际是如何使用的?

从PostgreSQL 9.3升级到PG 12后,每个PostgreSQL连接的内存使用量增加了一倍甚至三倍。所以我不得不从32GB的机器开始:shared_buffers=8GB用于连接的内存=8GB磁盘缓冲区内存=16GB收件人:64GB机器,具有:shared_buffers=8GB用于连接的内存=40GB磁盘缓冲区内存=16GB

但这仍然不够。单个连接达到使用170MB的专用ram(smaps中的Private,如https://www.depesz.com/2012/06/09/how-much-ram-is-postgresql-using/(,不与其他进程共享。

内存使用率如此之高的原因是什么?据我所知,它是持久的——直到连接关闭,内存才会释放。由于我使用的是由Wildfly管理的连接池,它们被重用,而且很少关闭和重新创建。

以下是我的数据源定义:

<datasource jta="true" jndi-name="java:/MainDS" pool-name="MainDCPool">
<connection-url>jdbc:postgresql://dbhost/</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<driver>postgres</driver>
<pool>
<min-pool-size>1</min-pool-size>
<max-pool-size>30</max-pool-size>
</pool>
<security>
<user-name>dbuser</user-name>
<password>password</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"/>
<validate-on-match>true</validate-on-match>
<background-validation>false</background-validation>
</validation>
<statement>
<share-prepared-statements>false</share-prepared-statements>
</statement>
<timeout>
<idle-timeout-minutes>1</idle-timeout-minutes>
</timeout>
</datasource>

到目前为止,我称之为告知设置"空闲超时分钟=1"和min-pool-size=1没有太大影响。看起来WildFly从池中选择了随机连接(当应用程序请求时(,因此它们中的任何一个都不太可能长时间处于空闲状态,并且池大小永远不会低于约20个连接

原来原因是直方图(pg_stats(。它存储在每个连接的内存中,而在具有大量分区的数据库中,它会导致显著的开销。包含大/长值的列具有显著影响。降低单个表及其分区的4列的STATISTICS属性可将内存使用量(每个连接(减少35%。升级本身并没有错,但作为升级过程的一部分,整个数据库被ANALYZEd,将新的default_statistics_target值应用于所有表。

检查直方图大小:查找给定表的直方图大小PostgreSQL

最新更新