温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

postgresql为何占用内存高

发布时间:2026-09-27 17:57:09 来源:亿速云 阅读:85 作者:小樊 栏目:数据库

PostgreSQL 占用内存“高”通常是正常现象,也可能是配置或 usage 问题。下面按原因 → 判断方法 → 解决办法来说明。


一、PostgreSQL 内存使用的组成(先搞清楚“高”在哪)

PostgreSQL 内存主要分为几部分:

  1. 共享内存(Shared Memory)

    • shared_buffers:缓存表和索引数据
    • wal_buffers:WAL 日志缓冲
  2. 每个连接私有内存

    • work_mem:排序、哈希、聚合
    • maintenance_work_mem:VACUUM、建索引
    • 每个连接都会分配
  3. 操作系统文件缓存(OS Cache)

    • PostgreSQL 读磁盘后,OS 也会缓存
    • 这部分“看起来像 PG 占的”
  4. 连接数本身

    • 连接越多,内存越高(即使空闲)

二、常见导致“内存高”的原因

1️⃣ shared_buffers 配置过大(最常见)

shared_buffers = 8GB
  • 默认通常是 128MB~25% 内存
  • 设太大不会更快,只会占内存

✅ 建议:

shared_buffers = 25% 物理内存

2️⃣ 连接数太多(非常常见)

比如:

  • 1000 个连接
  • 每个 work_mem = 64MB

理论峰值:

1000 × 64MB = 64GB

✅ 解决:

  • 使用连接池(PgBouncer)
  • 降低 work_mem
  • 控制最大连接数

3️⃣ work_mem 设置过高

work_mem = 256MB
  • 每个查询节点都会分配
  • 复杂 SQL 会倍数放大

✅ 建议:

work_mem = 4MB ~ 16MB

4️⃣ 大量排序 / 哈希 / 临时表

  • ORDER BY
  • GROUP BY
  • DISTINCT
  • 无索引的 JOIN

会大量使用 work_mem 和临时文件

✅ 优化:

  • 加索引
  • 减少一次性处理数据量

5️⃣ 长事务 / 空闲事务

SELECT * FROM pg_stat_activity
WHERE state = 'idle in transaction';
  • 长事务会阻止 VACUUM
  • 导致表膨胀 + 内存不释放

✅ 解决:

  • 杀掉 idle in transaction
  • 应用及时 commit

6️⃣ 表/索引膨胀(隐形内存杀手)

  • 删除/更新多
  • 没 VACUUM
SELECT * FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;

✅ 解决:

VACUUM ANALYZE;

7️⃣ 操作系统缓存被误认为 PG 占用

free -h
  • buff/cache 高 ≠ 内存泄漏
  • Linux 会尽量用内存做缓存

✅ 这是正常的


三、如何判断“是不是真的高”

看真实 PG 内存占用

SELECT
  pg_size_pretty(sum(backend_memory)) 
FROM pg_stat_activity;

或更实用:

ps aux --sort=-rss | head

四、推荐的安全配置(通用)

shared_buffers = 25% RAM
work_mem = 4MB
max_connections = 100
maintenance_work_mem = 512MB

连接多 → 一定上 PgBouncer


五、一句话总结

PostgreSQL 内存高,大多不是 bug,而是: shared_buffers 大 + 连接多 + work_mem 高 + 没连接池

如果你愿意,可以贴:

  • postgresql.conf 内存相关配置
  • 连接数
  • free -h 输出

我可以帮你精确算哪里吃内存。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手