Como encontrar o que está usando a troca linux ou o que está na troca?

12

Eu tenho um servidor linux virtual (Fedora 17) com 28 GB de RAM e 2 GB de swap. O servidor está executando um banco de dados MySQL configurado para usar a maior parte da RAM.

Depois de algum tempo em execução, o servidor começa a usar swap para trocar páginas não usadas. Isso é bom, pois meu swappiness está no padrão 60 e é o comportamento esperado.

O estranho é que o número no topo / meminfo não corresponde às informações dos processos. Ou seja, o servidor está relatando esses números:

/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

Se eu usar o script de /server//a/423603/98204, ele reportará números razoáveis ​​(poucos MBs trocados por bash'es, systemd etc.) e uma grande alocação do MySQL (omiti muitas linhas de saída ):

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

Portanto, se eu obtiver a saída do script corretamente, o uso total da troca deve ser 449264K = ca. 440MB com mysql usando ca. 90% do swap.

A questão é por que isso difere tanto dos números superiores e das meminfo? Existe alguma maneira de "despejar" as informações de troca para ver o que realmente está em vez de somar os usos de troca de todos os processos?

Ao analisar o problema, tive idéias diferentes, mas todas parecem estar erradas:

  1. A saída do script não está em KB. Mesmo se estivesse em unidades de 512 ou 4KB, não corresponderá. Na verdade, a proporção (1200: 440) é de cerca de 3: 1, que é o número "estranho".
  2. Existem algumas páginas no swap que são de alguma forma compartilhadas entre processos, conforme mencionado em /server//a/477664/98204 . Se isso for verdade, como posso encontrar o número real de memória usado assim? Quero dizer, precisaria fazer cca 800MB de diferença. E isso não parece certo neste cenário.
  3. Existem algumas páginas "antigas" em troca usadas por processos que já foram concluídos. Eu não me importaria se fosse capaz de descobrir quanto é essa troca "liberável".
  4. Existem páginas no swap que foram trocadas de volta à memória e estão no swap apenas no caso de não terem mudado na RAM e precisarem ser trocadas novamente, conforme mencionado em /server//a/100636/98204 . Mas o valor SwapCached é de apenas 24 MB.

O estranho é que o uso da troca está aumentando lentamente, enquanto a saída da soma do script é aproximadamente a mesma. Nos últimos 3 dias, a troca usada aumentou de 1100MB para 1230MB atuais, enquanto a soma aumentou de 430MB para 449MB atuais (ca.).

O servidor tem RAM livre (capaz) suficiente para que eu pudesse desligar e trocar a troca. Ou eu provavelmente poderia definir o swappiness como 0, para que o swap fosse usado apenas se não houvesse outra maneira. Gostaria de resolver o problema ou, pelo menos, descobrir qual é a causa disso.

Radek Hladík
fonte
Como você disse que deveria definir vm.swappiness = 0 (ou 1) e swapoff && swapon
HTTP500
Mas isso não resolveria o problema. Estou assumindo que a troca iria começar a aumentar novamente se eu definir swappines volta para 60 ou não seria usado em tudo, se eu mantê-lo em 0 ou 1 (a menos que o servidor sai de memória)
Radek Hladík
Se for um servidor de banco de dados, ele só deve usar swap em uma emergência, portanto, você deve sempre defini-lo como 0 (ou 1).
HTTP500 5/05
Isso é verdade e provavelmente é o que vou fazer se não encontrar a causa desse problema ... Por outro lado, existem muitos DBs pequenos no servidor que são usados ​​esporadicamente e gostei da ideia deles serem trocado pelo sistema quando eles não estão em uso ... No entanto, suponho que o MySQL seja capaz de lidar com isso por conta própria ...
Radek Hladík -
O Mysql faz um bom trabalho ao gerenciar seus próprios caches, mas isso é baseado em suposições sobre o que realmente está na memória e o que não está. Se você tentar adivinhar usando a memória swap, você estará prejudicando a capacidade do mysql de decidir o que precisa ser armazenado em cache e o que não. Desative a troca. Se você apertar swap, é uma falha de ajuste. Ajuste o tamanho do cache para que a troca nunca aconteça, mas, além disso, você deseja utilizar toda a memória física disponível.
Mc0e 6/11

Respostas:

9

O Fedora 18 e superior têm smemnos repositórios. Você pode baixar o script python e instalar a partir do código - fonte .

Aqui está uma amostra de saída (um pouco cortada e anônima) da minha máquina:

# 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 

A fonte também fornece smemcapque armazenará todos os dados relevantes para que o smem possa ser executado posteriormente.

   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.
rickhg12hs
fonte
1
O Smem do repo F17 não funcionou (mostrou uma lista vazia), mas o da fonte funcionou e está mostrando quase os mesmos números que os outros :-) mysql 358.1M de um total de 392.6M, enquanto o topo mostra 1191224k usado
Radek Hladík
4

Você deve verificar este script em outra máquina, porque meu sistema mostra o uso correto da troca:

# Your_script.sh
111280   Total Swap Used
# free
Swap:     33551716     120368   33431348

Muito próximo 111280 ~ = 120368.

Além disso, veja este script:

para proc em / proc / *; faça cat $ proc / smaps 2> / dev / null | awk '/ Swap / {swap + = $ 2} END {print swap "\ t' readlink $proc/exe'"}'; feito | classificar -n | awk '{total + = $ 1} / [0-9] /; END {print total "\ tTotal"}'

A partir deste tópico:

/unix/71714/linux-total-swap-used-swap-used-by-processes

vertente
fonte
O script mencionado está retornando os mesmos resultados ... 364920 / usr / libexec / mysqld 400372 Total
Radek Hladík
Quando eu tentei o script em outro servidor com uso de troca muito baixa (50MB) relatou 72MB cca no total :-) vou precisar para simulá-lo em algum servidor nonproduction mais tarde ...
Radek Hladík