小编Bra*_*n D的帖子

将进程的所有交换内存从交换中拉出

如何在不写入磁盘的情况下快速将进程的所有交换内存从交换中拉出?

这个问题的背景是微不足道的,因为需要这个问题的系统性问题正在由其他各方处理。但是,现在,我遇到了一个问题,我经常不得不在负载和 IO 等待非常高的情况下释放 OpenVZ 节点上的交换空间。

交换通常主要由运行在单个容器上的少数 MySQL 和 clamd 进程消耗。重新启动这些服务可以释放交换并解决节点上的问题,但由于显而易见的原因,这是不可取的。

我正在寻找一种方法,当节点过载并且需要比我当前的方法更快的东西时,可以快速从这些进程中释放交换:

unswap(){ [[ $1 && $(ls /proc/$1/maps) ]]  && ((gcore -o /tmp/deleteme $1 &>/dev/null; rm -fv /tmp/deleteme.$1)&) 2>/dev/null  || echo "must provide valid pid";};unswap
Run Code Online (Sandbox Code Playgroud)

此核心转储强制访问所有 ram,从而完成将其从交换区中拉出的工作,但我尚未找到避免将其写入文件的方法。此外,如果我可以隔离当前交换的地址范围并将该部分转储到 /dev/null,该过程似乎会更快,但我还没有找到一种方法来做到这一点。

这是一个巨大的节点,所以通常的 swapoff/swapon 方法非常耗时,而且节点的配置不在我的控制之下,所以修复根本原因不是这个问题的一部分。但是,任何有关如何在不杀死/重新启动任何东西的情况下快速释放大部分交换的见解将不胜感激。

环境:CentOS 6.7/OpenVZ

稍后可能会偶然发现此问题的任何人的更新:

使用 Jlong 的输入,我创建了以下函数:

unswap(){ (awk -F'[ \t-]+' '/^[a-f0-9]*-[a-f0-9]* /{recent="0x"$1" 0x"$2}/Swap:/&&$2>0{print recent}' /proc/$1/smaps | while read astart aend; do gdb --batch --pid $1 -ex "dump memory /dev/null $astart $aend" &>/dev/null; done&)2>/dev/null;};
Run Code Online (Sandbox Code Playgroud)

它有点慢,但完全按照这里的要求执行。可能可以通过仅查找交换中的最大地址范围并省略微不足道的小区域的迭代来提高速度,但前提是合理的。

工作示例:

#Find the process with …
Run Code Online (Sandbox Code Playgroud)

process centos swap openvz

10
推荐指数
1
解决办法
1389
查看次数

标签 统计

centos ×1

openvz ×1

process ×1

swap ×1