如何调整PostgreSQL的 Out-Of-Memory Killer设置
2021-03-27 15:29 abce 阅读(1818) 评论(0) 编辑 收藏 举报
Linux操作系统的主要任务之一是在进程请求内存分配时为其分配内存。在大多数情况下,进程/应用程序将向操作系统请求内存,但它不会使用所请求的所有内存。如果操作系统将内存分配给所有请求内存但不打算使用它的进程,它将很快耗尽内存——系统将崩溃。 为了处理这种情况,操作系统有一个特性,允许操作系统将内存提交给进程,而不需要实际分配内存。只有当进程实际计划使用该内存时,才会进行分配。有时,操作系统可能没有可用的内存,但它会将这些内存提交给进程,当进程计划使用这些内存时,如果提交的内存可用,操作系统就会分配。这个特性的缺点是,操作系统有时会提交内存,在分配内存的时候没有可用的内存可以分配,系统会崩溃。OOM在这个场景中扮演着至关重要的角色,它杀死进程以避免内核恐慌。
1 | Out of Memory: Killed process 12345 (postgres). |
1 2 3 4 5 6 7 | postgres=# select pg_backend_pid(); pg_backend_pid ---------------- 4845 (1 row) postgres=# |
postgresql的进程id是4845,在另外shell中可以看到它的oom_score
1 2 | # cat /proc/4845/oom_score 0 |
如果你想你的进程不被oom killer杀掉,可以配置另外一个参数oom_score_adj。设置一个较大的负值,可以减少被kill的机会。
1 | # echo -100 > /proc/4845/oom_score_adj |
可以在启动服务中设置:
1 2 3 4 | #vi /usr/lib/systemd/system/postgresql-10.service # Disable OOM kill on the postmaster [Service] OOMScoreAdjust=-1000 |
杀死一个进程
当选择一个或多个进程时,OOM-Killer调用oom_kill_task()函数。这个函数负责向进程发送终止/kill信号。在内存不足的情况下,调用这个函数,它可以向进程发送SIGKILL信号。生成一条内核日志消息。
1 | Out of Memory: Killed process [pid] [ name ]. |
如何控制OOM-Killer
linux提供了如何启动和关闭oom-killer,但是不推荐关闭。内核参数vm.oom-kill被用来开启和关闭oom-killer。
开启
1 | sysctl -w vm.oom-kill=1 |
关闭
1 | sysctl -w vm.oom-kill=0 |
要想永久生效:
1 | echo vm.oom-kill = 1 >>/etc/sysctl.conf |
要开启或关闭的另一种方法是写变量panic_on_oom变量。
1 2 | $ cat /proc/sys/vm/panic_on_oom 0 |
设置为0表示,内核遇到内存溢出时候不会恐慌
1 2 | $ echo 0 > /proc/sys/vm/panic_on_oom $ echo 1 > /proc/sys/vm/panic_on_oom |
除了启用和禁用外,还有更多的设置。
正如我们已经提到的那样,Linux可以通过分配内存而超额分配内存给进程,这种行为可以由Linux内核设置控制。
vm.overcommit_memory是用来控制这种行为的变量。
·0:内核决定是否可以overcommit,这是默认设置
·1:内核总是使用overcommit功能。这是一个冒险的设置
·2:内核支持overcommit功能,但是不能超过overcommit_ratio(所有物理内存和交换空间总和的内存)。
1 2 3 | # vi /etc/sysctl.conf vm.overcommit_memory = 2 vm.overcommit_ratio = 90 # overcommit_memory= 2 时生效 |
影响“oom-killer”的第二个因素是交换分区。这个行为可以通过变量/proc/sys/vm/swappiness来控制。这值指定用于处理页面交换的内核设置。
这个值越大,终止进程的可能性就越小,但是由于I/O,它会影响数据库的效率。
控制swappiness的变量的值越小,意味着oom杀手出现的可能性越大,但它也会提高数据库性能。
默认值是60,但是如果整个数据库内存适合,那么建议将该值设置为1。
要想避免postgresql发生oom,建议设置vm.overcommit_memory=2。这样不能百分百避免发生,但是会减少杀死postgresql进程的机会。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)