PostgreSQL OUT OF MEMORY 你拎得清?

2020-11-10 13:17:45 浏览数 (1)

当看到上面的这幅图,我想你的心情一定是不怎么美好,当然如果你设置了 SWAP 倒是很难看到这幅图,但估计也不会好受多少,投诉你数据库系统缓慢的唾沫或许可以给你建一个游泳池了。

遇到这样的问题怎么解决???? 从哪几个方面入手,这就是今天要说的

在说明白这件事之前要论论 postgres processes postmaster, 这个东西负责postgres 的 启动,分配内存包括 shared buffers ,监听端口,以及管理后端和其他有关的服务线程。

其中后端指的就是用户的连接一个进程一个用户的连接

这里有一些子进程

background writer

walwriter

autoovacuum

archiver

logical replication

等等(这不是全部,根据你添加的功能而定),这些子进程都有自己要做的工作,并消耗系统的内存。

现在我们的掐指算算,怎么就OUT OF 内存了, 掐指一算都是按照默认的配置。

1 shared_buffers 用了整体的 25% (部分书籍和国外一些专家的对PG初始时的建议)

2 wal_buffers 占用了大约 1/32

3 270 * max_locks_per_transaction * (max_connections max_prepared_transactions) bytes (别问我怎么来的,我也是淘换来的)

4 Autovacuum_max_workers * maintenance_work_mem (如果你没有特殊设置可以看做64MB)

5 更改表结构,添加索引估算一个数量* maintenance_work_mem

6 MAX_connections * max_workers (这里还没有考虑并行的事情)

OK 到此为止,固定的内存需求算是有一个大致的了断。但查询需要的内存的计算还没完。

可以通过下面的语句来获得一个大概的当前已经分配的线程使用的内存数 MB

每种数据库都有自己为用户连接而分配的内存,而内存的分配的方式就决定了某些特性,postgresql 是怎么来进行用户连接内存分配的,这里面到底有什么注意的地方,那是好好的研究一下。

1 work_mem :官方给出的的定义是查询操作(例如排序或哈希表)要使用的最大内存量 ,默认4MB貌似是没有什么,但问题是,POSTGRESQL 和 MYSQL 不一样,有并发,并且可以自己调整并发数,而这4MB 针对一个查询的并发是每个并发要占用一个4MB,所以这点要明白,在配置并发数的时候,你可千万别忘记这件事,要不你的内存可就......

根据相关的内存的占用量也要和实际的连接数有关联,一个查询如果是短小,占用时间短的查询但连接数多,那就可以将work_mem 降低,如果是OLAP类型的查询,在提高work_mem的情况下就需要考虑降低连接数的上限和并发数。

2 maintenance_work_mem: 默认值64MB ,一个SESSION 只能在一个时刻存在一个VACUUM、CREATE INDEX和ALTER TABLE ,所以可以进来给的比较大,加速这些操作的运行。

大部分的消耗maintenance_work_mem 内存的情况大多是发生在vacuum 上的,所以定期的去监控一下dead tuples 和 表的膨胀率对发现vacuum 内存的消耗也是有一定帮助的。

Postgresql 的内存使用中如果出现OUT OF Memory 的可能,

1 定位错误日志,发现错误日志中的关于out of memory 的错误信息

2 根据错误信息,发现时由于 wrok_mem 有关的问题 (如查询无法分配内存) 或者是 vacuum 或者 其他消耗 maintenance_work_mem 导致内存不足产生的问题

PostgreSQL 大部分时间是很皮实的,但如果内存和所需要的系统提供的能力之间不匹配,或者由于其他问题导致内存不足,根本查找问题的方向应该是找到哪里导致内存不足或其他根本性的原因,而不是直接添加内存了事。

0 人点赞