有什么方法可以检查分配给每个连接的内存的实际使用情况吗?
从 PostgreSQL 9.3 升级到 PG 12 后,每个 PostgreSQL 连接的内存使用量增加了一倍甚至三倍。所以我必须从 32GB 机器开始: 共享缓冲区 = 8GB 用于连接的内存 = 8GB 磁盘缓冲区内存 = 16GB 到: 64GB 机器: 共享缓冲区 = 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>
据我所知,设置 'idle-timeout-months=1' 和 min-pool-size=1
没有太大影响。看起来 WildFly 从池中选择随机连接(当应用程序请求时),因此它们中的任何一个不太可能长时间保持空闲状态,并且池大小永远不会低于约 20 个连接
最佳答案
原来原因是直方图(pg_stats)。它存储在每个连接的内存中,并且在具有大量分区的数据库中会导致显着的开销。包含大/长值的列会产生重大影响。降低单个表及其分区的 4 列的 STATISTICS 属性可将内存使用量(每个连接)减少 35%。
升级本身并没有问题,但作为升级过程的一部分,整个数据库被分析,将新的 default_statistics_target
值应用于所有表。
检查直方图大小:Finding the histogram size for a given table PostgreSQL
关于postgresql - 调试高 PostgreSQL 内存使用率(每个连接),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63227902/