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

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

Контекст по этому вопросу тривиален, поскольку системный вопрос, требующий постановки вопроса, обрабатывается другими сторонами. Тем не менее, прямо сейчас у меня проблема, когда мне часто приходится освобождать место подкачки на узле 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 
  • Зашифрованные файловые системы с разделами подкачки
  • Cleancache vs zram?
  • Есть ли способ заставить Linux отказаться от использования при низком использовании ЦП?
  • Как добавить 100 МБ пространства подкачки в качестве логического тома в CentOS?
  • Как работает mkswap? Что в заголовке свопа, который он создает?
  • Безопасно ли удалять все разделы подкачки?
  • Как заставить tmpfs использовать только физическую RAM, а не своп?
  • Как я могу открыть файл в VIM в режиме readonly, если он уже имеет swap-файл?
  • А как насчет обмена?
  • Как восстановить загрузку после удаления старого свопа?
  • Почему общие свопы и ошибки / исправления страниц пуст в ps?
  • Что задает размер tmpfs? Что происходит, когда оно полно?
  • Linux и Unix - лучшая ОС в мире.