Investigue gravações em disco para descobrir qual processo grava no meu SSD

11

Tento minimizar as gravações em disco na minha nova unidade de sistema SSD. Estou preso com a saída do iostat:

~ > iostat -d 10 /dev/sdb
Linux 2.6.32-44-generic (Pluto)     13.11.2012  _i686_  (2 CPU)

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sdb               8,60       212,67       119,45   21010156   11800488

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sdb               3,00         0,00        40,00          0        400

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sdb               1,70         0,00        18,40          0        184

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sdb               1,20         0,00        28,80          0        288

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sdb               2,20         0,00        32,80          0        328

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sdb               1,20         0,00        23,20          0        232

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sdb               3,40        19,20        42,40        192        424

Como eu vejo, há gravações em sdb. Como posso resolver qual processo é gravado?

Eu sei sobre o iotop , mas ele não mostra qual sistema de arquivos está sendo acessado.

zuba
fonte

Respostas:

7

O seguinte usa o mecanismo de despejo de bloco de memória virtual do kernel. Primeiro obtenha o script perl:

wget https://raw.githubusercontent.com/true/aspersa-mirror/master/iodump

Em seguida, ative o despejo de bloco:

echo 1 | sudo tee /proc/sys/vm/block_dump

E execute o seguinte:

while true; do sleep 1; sudo dmesg -c; done  | perl iodump

..e pressione Controlcpara concluir, você verá algo como o seguinte:

^C# Caught SIGINT.
TASK                   PID      TOTAL       READ      WRITE      DIRTY DEVICES
jbd2/sda3-8            620         40          0         40          0 sda3
jbd2/sda1-8            323         21          0         21          0 sda1
#1                    4746         11          0         11          0 sda3
flush-8:0             2759          7          0          7          0 sda1, sda3
command-not-fou       9703          4          4          0          0 sda1
mpegaudioparse8       8167          2          2          0          0 sda3
bash                  9704          1          1          0          0 sda1
bash                  9489          1          0          1          0 sda3
mount.ecryptfs_       9698          1          1          0          0 sda1

E desative o despejo de bloco quando terminar:

echo 0 | sudo tee /proc/sys/vm/block_dump

Agradecemos a http://www.xaprb.com/blog/2009/08/23/how-to-find-per-process-io-statistics-on-linux/ por essas informações úteis.

Colin Ian King
fonte
10

Você poderia pelo menos começar com o iotop. Ele não informa qual sistema de arquivos está sendo gravado, mas fornecerá alguns processos para investigar.

sudo apt-get install iotop
sudo iotop

Ele mostra leituras e gravações instantâneas de disco e o nome do comando lendo ou gravando.

Se você estiver tentando capturar um processo que grava com pouca frequência, pode usar a --accumulateopção ou registrar a saída em um arquivo:

sudo -i
iotop --batch > iotop_log_file

Obviamente, a gravação do arquivo de log será exibida nos resultados, mas você também deverá conseguir grep para outros processos de gravação em disco.

Nesse ponto, você deve ser capaz de encontrar alguns processos suspeitos candidatos. A coluna da esquerda no iotop mostra o pid. Em seguida, descubra em qual descritor de arquivo o processo está gravando:

sudo -i
strace -p <pid> 2>&1 | grep write

Você deve ver uma saída assim quando o processo escreve:

write(1, "\n", 1)                       = 1
write(4, "test\n", 5)                   = 5
write(1, ">>> ", 4)                     = 4

O primeiro argumento a escrever é o descritor de arquivo. Provavelmente, estamos procurando valores maiores que 2, porque 0, 1 e 2 são apenas stdin, stdout e stderr. O descritor de arquivo 4 parece interessante.

Agora você pode descobrir para qual arquivo o descritor de arquivos aponta:

lsof -p <pid>

O que deve produzir uma saída como:

...
python  23908  rob  mem    REG    8,1    26258 8392656 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
python  23908  rob    0u   CHR  136,5      0t0       8 /dev/pts/5
python  23908  rob    1u   CHR  136,5      0t0       8 /dev/pts/5
python  23908  rob    2u   CHR  136,5      0t0       8 /dev/pts/5
python  23908  rob    3w   REG   0,25      909 9049082 /home/rob/testfile
python  23908  rob    4w   REG   0,25       20 9049087 /home/rob/another_test_file

Veja a quarta coluna. 4wsignifica que o descritor de arquivo 4 está aberto para gravação e o arquivo é another_test_file.

É possível que um processo abra, grave e feche um arquivo, caso em que lsof não o mostraria. Você pode perceber isso acontecendo com:

strace -p <pid> 2>&1 | grep open
Rob Fisher
fonte
Eu não sabia sobre --acumule Esse é um recurso muito legal! Muito obrigado por isso!!! O redirecionamento de saída iotop --batch falha com UnicodeEncodeError: o codec 'ascii' não pode codificar caracteres na posição 92-99: ordinal fora do intervalo (128) no arquivo "/usr/lib/pymodules/python2.6/iotop/ui. py ", linha 405, em
refresh_display
Fico feliz que minha resposta tenha sido de alguma utilidade, pelo menos. O redirecionamento funciona para mim; não tenho certeza se posso explicar isso.
22812 Robbie Fisher
Ok, eu brinquei um pouco e descobri que podia usar lsof e strace para pelo menos fazer o trabalho de detetive suficiente para capturar processos gravados em um SSD. Esperemos que isso finalmente responda à pergunta conforme solicitado, embora pareça que a resposta de Colin Ian King seja mais fácil!
22612 Robbie Fisher
1
Desculpe pela resposta tardia, eu não tinha nada a dizer até brincar com strace. Obrigado por essa outra abordagem inteligente, votei. Achei bastante difícil escrever um script para implementá-lo, devido à pouca experiência em escrever scripts de shell. Por isso escolhi outra solução. Obrigado por compartilhar seu conhecimento!
Zuba
Deve ser --accumulated, mas a troca de pilhas requer 6 caracteres para aceitar a edição da postagem.
h__ 28/02/19