У меня есть виртуальный сервер Linux (Fedora 17) с 28 ГБ ОЗУ и 2 ГБ подкачки. На сервере работает база данных MySQL, настроенная на использование большей части ОЗУ.
По прошествии некоторого времени сервер начинает использовать подкачку для замены не отправленных страниц. Это нормально, поскольку у меня значение swappiness по умолчанию 60, и это ожидаемое поведение.
Странно то, что номер в top / meminfo не соответствует информации от процессов. Т.е. сервер сообщает эти числа:
/proc/meminfo:
SwapCached: 24588 kB
SwapTotal: 2097148 kB
SwapFree: 865912 kB
top:
Mem: 28189800k total, 27583776k used, 606024k free, 163452k buffers
Swap: 2097148k total, 1231512k used, 865636k free, 6554356k cached
Если я использую скрипт из https://serverfault.com/a/423603/98204 он сообщает разумные числа (несколько мегабайт, замененных bash'ами, systemd и т.д.) и одно большое выделение из MySQL (я пропустил много строк вывода):
892 [2442] qmgr -l -t fifo -u
896 [2412] /usr/libexec/postfix/master
904 [28382] mysql -u root
976 [27559] -bash
984 [27637] -bash
992 [27931] SCREEN
1000 [27932] /bin/bash
1192 [27558] sshd: admin@pts/0
1196 [27556] sshd: admin [priv]
1244 [1] /usr/lib/systemd/systemd
9444 [26626] /usr/bin/perl /bin/innotop
413852 [31039] /usr/libexec/mysqld --basedir=/usr --datadir=/data/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/data/mysql/err --open-files-limit=8192 --pid-file=/data/mysql/pid --socket=/data/mysql/mysql.sock --port=3306
449264 Total Swap Used
Итак, если я получу вывод сценария правильно, общее использование свопа должно быть 449264K = ca. 440 МБ с mysql с использованием ca. 90% свопа.
Спрашивается, почему это так сильно отличается от номеров top и meminfo? Есть ли способ, как «выгрузить» информацию о свопе, чтобы увидеть, что на самом деле в ней, вместо того, чтобы суммировать использование свопа всеми процессами?
При анализе проблемы у меня возникли разные идеи, но все они кажутся ошибочными:
Странно то, что использование подкачки медленно увеличивается, в то время как суммарный вывод скрипта примерно такой же. За последние 3 дня используемый своп увеличился с 1100 МБ до 1230 МБ, а сумма увеличилась с 430 МБ до 449 МБ (примерно).
На сервере достаточно свободной (доступной) оперативной памяти, поэтому я мог просто отключить своп и снова включить его. Или я, вероятно, мог бы установить swappiness на 0, чтобы своп использовался только в том случае, если нет другого пути. Но хотелось бы решить вопрос или хотя бы выяснить, в чем причина этого.
Fedora 18 и выше имеют smem
в репо. Вы можете скачать скрипт python и установить его с источник.
Вот пример вывода (несколько сокращенный и анонимный) с моей машины:
# smem -s swap -t -k -n
PID User Command Swap USS PSS RSS
20917 1001 bash 0 1.1M 1.1M 1.9M
28329 0 python /bin/smem -s swap -t 0 6.3M 6.5M 7.4M
2719 1001 gnome-pty-helper 16.0K 72.0K 73.0K 516.0K
619 0 @sbin/mdadm --monitor --sca 28.0K 72.0K 73.0K 248.0K
[big snip]
32079 42 gnome-shell --mode=gdm 41.9M 1.9M 2.0M 5.0M
32403 1001 /opt/google/chrome/chrome - 43.1M 118.5M 119.4M 132.3M
4844 1002 /opt/google/chrome/chrome 48.1M 38.1M 41.9M 51.9M
5411 1002 /opt/google/chrome/chrome - 54.6M 33.4M 33.5M 36.8M
5624 1002 /opt/google/chrome/chrome - 72.4M 54.9M 55.5M 65.7M
24328 1002 /opt/Adobe/Reader9/Reader/i 77.5M 1.9M 2.0M 5.2M
4921 1002 /opt/google/chrome/chrome - 147.2M 258.4M 259.4M 272.0M
-------------------------------------------------------------------------------
214 14 1.1G 1.1G 1.2G 1.7G
Источник также предоставляет smemcap
в котором будут храниться все соответствующие данные, чтобы в дальнейшем на них можно было запускать smem.
To capture memory statistics on resource-constrained systems, the the smem source includes a utility named smemcap. smemcap captures all /proc entries required by smem and outputs them as an uncompressed .tar file to STDOUT. smem can analyze the output using the --source option. smemcap is small and does not require Python.
Вы должны проверить этот сценарий на другом компьютере, потому что моя система показывает правильное использование свопа:
# Your_script.sh
111280 Total Swap Used
# free
Swap: 33551716 120368 33431348
Очень близко 111280 ~ = 120368.
Также посмотрите на этот сценарий:
для proc в / proc / *; сделать cat $ proc / smaps 2> / dev / null | awk '/ Swap / {swap + = $ 2} END {печать swap "\ t'
readlink $proc/exe
'"}'; done | sort -n | awk '{total + = $ 1} / [0-9] /; END {print total" \ tTotal "}'
Из этой ветки:
https://unix.stackexchange.com/questions/71714/linux-total-swap-used-swap-used-by-processes