共计 1241 个字符,预计需要花费 4 分钟才能阅读完成。
今天在调整内核中的内存策略,有台机器是 16G 内存 32 位系统,将 vm.min_free_kbytes 值设定为物理内存的 5%,也就是内存低于 5% 自动释放,跟其他机器一样,编辑好 sysctl.conf 后执行 sysctl -p,结果悲剧的事发生了,服务器马上就宕机了,通知机房重启无果,单用户也无法进入,报 Kernel panic – not syncing: Out of memory and no killable processes… , 只能赶到机房,用光盘启动救援模式,将刚才添加策略注销掉系统可以起来了。
不甘心再次尝试设定 vm.min_free_kbytes 值,sysctl -p 结果一样,最后将值设定为 2%,没有问题,那问题肯定出在这个值上,查看 messages,其中有记录 kernel: 896MB LOWMEM available 这么一句,貌似在其他系统中没看到过,就从他下手查找原因。
宕机原因:
vm.min_free_kbytes 设定值高于 LowTotal 值,系统认为没有足够的 lowmem,而触发 OOM Killer,将进程强行杀掉。
具体分析:
系统中内存分为 lowmem 和 highmem,其中 lowmem 为寻址内存,当 lowmem 耗尽时,系统会触动 OOM Killer 将多余进程杀掉来释放内存(2.6 内核为杀掉占用内存最高的进程)
其中 64 位系统会将所有内存大小都划分到 lowmem 中,防止 lowmem 不够用,而 32 为系统是分开的,上限为 896M 左右,具体可通过 egrep ‘High|Low’ /proc/meminfo 命令查看
如果将 vm.min_free_kbytes 的值设定大于 LowTotal 的值,则系统会认为当前没有足够的内存而触发 OOM Killer,直至将所有进程杀掉,重启无法启动也是因为当启动时刚启动一个进程,系统就认为内存不足而将其杀掉,导致无法启动
(已做实验,将 vm.min_free_kbytes 的值设定的比 lowmem 值大 1 都会触发 OOM Killer)
简单的说也就是像大家用 32 位的 XP,如果你是 4G 内存,系统也就只能认到 3.5G,在 32 位的 linux 里,系统认为 lowmem 就是当前内存的大小,只要 lowmem 不够用就认为内存不够用了,就开始杀进程来释放,设定 vm.min_free_kbytes 也就让系统空闲出多少 lowmem,所以设定值超出 lowmem 会出现异常。
所以,32 位系统设定前要查看实际 lowmem 的大小,虽说上限是 896M,但我这台 16G 的机器才 700M 多,具体什么原因那就是内核机制的事了,有空再做研究,现在知道是怎么死的就行了。
血的教训呀,像大内存的机器,以后还是用 64 位系统吧,32 位真是会在你不知情的情况下出问题呀。
备注:网上资料说在一个 32 位系统中,物理内存越高,所消耗的 lowmem 越高,16G 的服务器所消耗的将近是 4G 内存的 4 倍左右
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2015-08/121566.htm