Вытащить всю измененную память процесса из-под свопа

Как можно быстро вытащить всю замененную память процесса из свопинга без записи на диск?

Контекст по этому вопросу тривиален, поскольку системный вопрос, требующий постановки вопроса, обрабатывается другими сторонами. Тем не менее, прямо сейчас у меня проблема, когда мне часто приходится освобождать место подкачки на узле 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 

Этот основной дамп заставляет всех плунгов быть доступными, и, таким образом, делает работу по вытаскиванию его из-под свопа, но мне еще предстоит найти способ избежать его записи в файл. Кроме того, похоже, что процесс будет быстрее, если я смогу выделить диапазоны адресов, которые в настоящее время заменены, и просто выгружать эту часть в / 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;}; 

Это немного медленно, но делает то, что было запрошено здесь иначе. Вероятно, это ускорит скорость, найдя только самые большие диапазоны адресов в swap и опуская итерации для тривиально небольших областей, но предпосылка звучит.

Рабочий пример:

 #Find the process with the highest swap use [~]# grep VmSwap /proc/*/status 2>/dev/null | sort -nk2 | tail -n1 | while read line; do fp=$(echo $line | cut -d: -f1); echo $line" "$(stat --format="%U" $fp)" "$(grep -oP "(?<=NameS).*" $fp); done | column -t /proc/6225/status:VmSwap: 230700 kB root mysqld #Dump the swapped address ranges and observe the swap use of the proc over time [~]# 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;}; unswap 6225; while true; do grep VmSwap /proc/6225/status; sleep 1; done VmSwap: 230700 kB VmSwap: 230700 kB VmSwap: 230676 kB VmSwap: 229824 kB VmSwap: 227564 kB ... 36 lines omitted for brevity ... VmSwap: 9564 kB VmSwap: 3212 kB VmSwap: 1876 kB VmSwap: 44 kB VmSwap: 0 kB 

Заключительное решение для массового захоронения только больших кусков смены памяти:

 unswap(){ (awk -F'[ \t-]+' '/^[a-f0-9]*-[a-f0-9]* /{recent="0x"$1" 0x"$2}/Swap:/&&$2>1000{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;}; grep VmSwap /proc/*/status 2>/dev/null | sort -nk2 | tail -n20 | cut -d/ -f3 | while read line; do unswap $line; done;echo "Dumps Free(m)"; rcount=10; while [[ $rcount -gt 0 ]]; do rcount=$(ps fauxww | grep "dump memory" | grep -v grep | wc -l); echo "$rcount $(free -m | awk '/Swap/{print $4}')"; sleep 1; done 

Мне еще предстоит определить, представляет ли этот метод какой-либо риск для здоровья процесса или системы, особенно при одновременном переходе по нескольким процессам. Если у кого-нибудь есть какие-либо потенциальные последствия для процессов или системы, пожалуйста, не стесняйтесь комментировать.

One Solution collect form web for “Вытащить всю измененную память процесса из-под свопа”

Вы можете добиться того же результата, используя команду GDB 'dump memory' и напишите в / dev / null.

Вам просто нужно найти области в / proc / $ PID / smaps, которые необходимо отключить. пример из / proc / $ PID / smaps:

 02205000-05222000 rw-p 00000000 00:00 0 Size: 49268 kB Rss: 15792 kB Pss: 9854 kB Shared_Clean: 0 kB Shared_Dirty: 11876 kB Private_Clean: 0 kB Private_Dirty: 3916 kB Referenced: 564 kB Anonymous: 15792 kB AnonHugePages: 0 kB Swap: 33276 kB KernelPageSize: 4 kB MMUPageSize: 4 kB 

а затем используйте режим -batch для выполнения команды gdb, чтобы вы могли использовать ее в своей функции:

 [root@nunya ~]# swapon -s ; gdb --batch --pid 33795 -ex "dump memory /dev/null 0x02205000 0x05222000" ;swapon -s Filename Type Size Used Priority /dev/sda2 partition 7811068 7808096 -1 [Thread debugging using libthread_db enabled] Filename Type Size Used Priority /dev/sda2 partition 7811068 7796012 -1 
  • Обмен на видеопамяти в виртуальной машине
  • Почему у меня есть только ограниченное количество файлов подкачки
  • В OpenBSD заканчивается нехватка памяти, в то время как не используется пространство подкачки
  • Фиксация fstab после переформатирования swap
  • Общий раздел подкачки FreeBSD с Linux
  • Создание разреженного (автоматически расширяющегося и сжатого) файла подкачки с поддержкой отверстий
  • Расчет требований к RAM / Swap Space
  • Изнашивание уровня SD-карты из-за файла подкачки во встроенном Linux
  • linux - OOM / swap не используется
  • Получить информацию о swap-памяти, где swapinfo недоступен
  • Разница между «none» и «swap» в качестве точки монтирования для swap в fstab?
  • Linux и Unix - лучшая ОС в мире.