Determinando arquivo específico responsável por alta E / S

37

Esse é um problema simples, mas a primeira vez que tive que corrigi-lo: descobrir quais arquivos / inodes específicos são os alvos da maioria das E / S. Eu gostaria de obter uma visão geral do sistema, mas se eu tiver que fornecer um PID ou TID, estou bem com isso.

Eu gostaria de ir sem ter que fazer um straceprograma que aparece iotop. De preferência, usando uma ferramenta na mesma linha que iotopuma que especifica por arquivo. Posso usar lsofpara ver quais arquivos o mailman abriu, mas não indica qual arquivo está recebendo E / S ou quanto.

Já vi em outros lugares onde foi sugerido o uso, auditdmas eu preferiria não fazer isso, pois colocaria as informações em nossos arquivos de auditoria, que usamos para outros fins e isso parece um problema que eu deveria poder pesquisar nesse caminho.

O problema específico que tenho no momento é o preenchimento rápido de instantâneos do LVM. Desde então, resolvi o problema, mas gostaria de poder corrigi-lo dessa maneira, em vez de apenas fazer um lsem todos os descritores de arquivos abertos /proc/<pid>/fdpara ver qual deles estava crescendo mais rápido.

Bratchley
fonte
possivelmente relacionado: unix.stackexchange.com/questions/9520/…
slm
Sim, eu não tinha visto essa antes, mas a maioria das respostas para essa pergunta era basicamente assim: "Bem, se você faz as coisas dessa maneira incrivelmente específica e faz algo estranho, pode ter uma idéia grosseira" versus algo que resolve diretamente o problema sem exigir que o administrador fique muito chique. Não pretendo criticar os outros, e agora percebo que a dificuldade desse problema é provavelmente a maneira como essas soluções foram oferecidas, mas parece que, mesmo que não exista uma ferramenta como a fatraceanterior, algo como o script que escrevi deveria foram oferecidos, pois é mais amplamente utilizável.
Bratchley
Só para esclarecer: não estou criticando os outros que ofereceram ajuda. A ajuda é sempre melhor do que nenhuma ajuda. É frustrante quando você sente que o problema deve ter uma resposta direta e tudo o que você pode descobrir por conta própria ou ver outras pessoas sugerindo soluções alternativas complicadas ou processos muito manuais (como o que acabei fazendo com o meu problema do carteiro).
Bratchley
Sim, eu sempre fico impressionado quando encontro respostas para novos Qs aqui enterrados no site que não aparecem até que eu cavo por um tempo. Parece algo quebrado ali 8-). Por isso, é bom perguntar o mesmo Q de várias maneiras e vinculá-lo aos mais antigos à medida que eles são roteados. Como seu script é uma abordagem melhor, ainda estou surpreso por não haver uma ferramenta de uso geral que faça o que você pede. Parece uma grande lacuna no Unix.
Slm
A maior parte da ajuda é extremamente direcionada, o que pode ser um pouco irritante, pois ao responder você está dizendo a mesma coisa várias vezes, de maneiras diferentes. Mas essa é a natureza dos sites da SE. Não sei como Gilles faz isso. Eu gosto mais dessas perguntas e respostas mais longas.
Slm

Respostas:

60

Existem vários aspectos dessa questão que foram abordados parcialmente por meio de outras ferramentas, mas não parece haver uma única ferramenta que forneça todos os recursos que você procura.

iotop

Essa ferramenta mostra quais processos estão consumindo mais E / S. Mas falta opções para mostrar nomes de arquivos específicos.

$ sudo iotop
Total DISK READ:       0.00 B/s | Total DISK WRITE:       0.00 B/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                        
    1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init
    2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
    3 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
    5 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kworker/u:0]
    6 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/0]
    7 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [watchdog/0]

Por padrão, ele faz o que faz regularmente topnos processos que disputam o tempo da CPU, exceto na E / S do disco. Você pode convencê-lo a fornecer uma visão de 30.000 pés usando o -acomutador para que ele mostre um acúmulo por processo ao longo do tempo.

$ sudo iotop -a
Total DISK READ:       0.00 B/s | Total DISK WRITE:       0.00 B/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                        
  258 be/3 root          0.00 B    896.00 K  0.00 %  0.46 % [jbd2/dm-0-8]
22698 be/4 emma          0.00 B     72.00 K  0.00 %  0.00 % chrome
22712 be/4 emma          0.00 B    172.00 K  0.00 %  0.00 % chrome
 1177 be/4 root          0.00 B     36.00 K  0.00 %  0.00 % cupsd -F
22711 be/4 emma          0.00 B    120.00 K  0.00 %  0.00 % chrome
22703 be/4 emma          0.00 B     32.00 K  0.00 %  0.00 % chrome
22722 be/4 emma          0.00 B     12.00 K  0.00 %  0.00 % chrome

Ferramentas i * (inotify, iwatch, etc.)

Essas ferramentas fornecem acesso aos eventos de acesso a arquivos, mas precisam ser direcionadas especificamente para diretórios ou arquivos específicos. Portanto, eles não são tão úteis ao tentar rastrear um acesso não autorizado a arquivos por um processo desconhecido, ao depurar problemas de desempenho.

Além disso, a inotifyestrutura não fornece detalhes sobre os arquivos que estão sendo acessados. Somente o tipo de acesso, portanto, nenhuma informação sobre a quantidade de dados sendo movida para frente e para trás está disponível, usando essas ferramentas.

iostat

Mostra o desempenho geral (leituras e gravações) com base no acesso a um determinado dispositivo (disco rígido) ou partição. Mas não fornece nenhum insight sobre quais arquivos estão gerando esses acessos.

$ iostat -htx 1 1
Linux 3.5.0-19-generic (manny)  08/18/2013  _x86_64_    (3 CPU)

08/18/2013 10:15:38 PM
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          18.41    0.00    1.98    0.11    0.00   79.49

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda
                  0.01     0.67    0.09    0.87     1.45    16.27    37.06     0.01   10.92   11.86   10.82   5.02   0.48
dm-0
                  0.00     0.00    0.09    1.42     1.42    16.21    23.41     0.01    9.95   12.22    9.81   3.19   0.48
dm-1
                  0.00     0.00    0.00    0.02     0.01     0.06     8.00     0.00  175.77   24.68  204.11   1.43   0.00

blktrace

Esta opção está com um nível muito baixo. Falta visibilidade sobre quais arquivos e / ou inodes estão sendo acessados, apenas números de blocos brutos.

$ sudo blktrace -d /dev/sda -o - | blkparse -i -
  8,5    0        1     0.000000000   258  A WBS 0 + 0 <- (252,0) 0
  8,0    0        2     0.000001644   258  Q WBS [(null)]
  8,0    0        3     0.000007636   258  G WBS [(null)]
  8,0    0        4     0.000011344   258  I WBS [(null)]
  8,5    2        1 1266874889.709032673   258  A  WS 852117920 + 8 <- (252,0) 852115872
  8,0    2        2 1266874889.709033751   258  A  WS 852619680 + 8 <- (8,5) 852117920
  8,0    2        3 1266874889.709034966   258  Q  WS 852619680 + 8 [jbd2/dm-0-8]
  8,0    2        4 1266874889.709043188   258  G  WS 852619680 + 8 [jbd2/dm-0-8]
  8,0    2        5 1266874889.709045444   258  P   N [jbd2/dm-0-8]
  8,0    2        6 1266874889.709051409   258  I  WS 852619680 + 8 [jbd2/dm-0-8]
  8,0    2        7 1266874889.709053080   258  U   N [jbd2/dm-0-8] 1
  8,0    2        8 1266874889.709056385   258  D  WS 852619680 + 8 [jbd2/dm-0-8]
  8,5    2        9 1266874889.709111456   258  A  WS 482763752 + 8 <- (252,0) 482761704
...
^C
...
Total (8,0):
 Reads Queued:           0,        0KiB  Writes Queued:           7,       24KiB
 Read Dispatches:        0,        0KiB  Write Dispatches:        3,       24KiB
 Reads Requeued:         0       Writes Requeued:         0
 Reads Completed:        0,        0KiB  Writes Completed:        5,       24KiB
 Read Merges:            0,        0KiB  Write Merges:            3,       12KiB
 IO unplugs:             2           Timer unplugs:           0

Throughput (R/W): 0KiB/s / 510KiB/s
Events (8,0): 43 entries
Skips: 0 forward (0 -   0.0%)

fatrace

Esta é uma nova adição ao Kernel Linux e uma bem-vinda, portanto, é apenas em distros mais recentes, como o Ubuntu 12.10. Meu sistema Fedora 14 estava faltando 8-).

Ele fornece o mesmo acesso que você pode obter inotifysem precisar direcionar um diretório e / ou arquivos específicos.

$ sudo fatrace
pickup(4910): O /var/spool/postfix/maildrop
pickup(4910): C /var/spool/postfix/maildrop
sshd(4927): CO /etc/group
sshd(4927): CO /etc/passwd
sshd(4927): RCO /var/log/lastlog
sshd(4927): CWO /var/log/wtmp
sshd(4927): CWO /var/log/lastlog
sshd(6808): RO /bin/dash
sshd(6808): RO /lib/x86_64-linux-gnu/ld-2.15.so
sh(6808): R /lib/x86_64-linux-gnu/ld-2.15.so
sh(6808): O /etc/ld.so.cache
sh(6808): O /lib/x86_64-linux-gnu/libc-2.15.so

A descrição acima mostra o ID do processo que está acessando o arquivo e qual arquivo está acessando, mas não fornece nenhum uso geral da largura de banda; portanto, cada acesso é indistinguível de qualquer outro acesso.

Então o que fazer?

A fatraceopção mostra a maior promessa para FINALMENTE fornecer uma ferramenta que pode mostrar o uso agregado de E / S de disco com base nos arquivos que estão sendo acessados, em vez dos processos que estão acessando.

Referências

slm
fonte
6
Doce bebê Jesus, slm. Você é como a estrela do rock do Unix SE, no que me diz respeito. Suas respostas são sempre incrivelmente educativas e mostram muita pesquisa em um só lugar. A maioria das pessoas (se soubessem) acabaria de publicar o último trecho fatracee não o desenvolveria muito. Realmente aprecio como você se esforça para garantir que as pessoas entendam o cenário completo e desejem poder fazer mais do que apenas votar e dar recompensa.
Bratchley
@ JoelDavis - obrigado por suas palavras muito gentis. Gostei da sua ideia de fazer uma resposta canônica, por isso estava tentando começar por aqui. Eu já tive esse problema muitas vezes e desejei ter um recurso como esse, então imaginei que o criaríamos aqui 8-).
slm
Uma coisa sobre a qual estou confuso: quando fiz a instalação, yumpuxei as bibliotecas do python3 por algum motivo. Eu fiz um filee parece que é um executável ELF. lddnão mostra nenhum link para pythonnem o fez strings. Alguma idéia de por que se incomodou com python3?
Bratchley
1
BTW, aparentemente eu tenho que esperar um pouco depois de aceitar a resposta para conceder recompensa. Não que isso importe para alguém com aproximadamente metade da quantidade agregada de pontos de reputação do Unix SE, mas apenas um FYI.
Bratchley
1
Não é realmente um problema para mim, não. Posso obter as informações necessárias sobre isso através do telefone apropriado iotope das iostatligações. Além disso, eu descobri a coisa do python, parece que (no Fedora 18 pelo menos) existe um pythonscript "power-use-report", então yumestava apenas respondendo ao fato de pythonestar nas dependências do RPM. Então esse mistério em particular é resolvido.
Bratchley
4

Ainda não recebi uma resposta, mas escrevi esse script (no final) e parece fazer o que quero. Não testei em outros sistemas e é específico do Linux.

Basicamente, ele permanece stracepor 30 segundos, filtrando as chamadas do sistema relacionadas a arquivos e faz um esforço para remover o nome do arquivo. Ele conta o número de ocorrências desse arquivo no stracee apresenta um resumo paginado ao usuário. Não é perfeito, mas o número de chamadas do sistema para um arquivo específico pode ter alguma correlação fraca com a quantidade de E / S que está executando.

Não testei completamente, mas se não funcionar imediatamente, deve dar às pessoas um lugar para começar. Se ficar mais detalhado, pode ser aconselhável reescrever isso em uma linguagem de nível superior, como python .

Se eu não receber uma resposta dentro de uma semana de uma maneira menos caseira de fazer isso (mesmo que seja outra ferramenta que apenas conte a E / S de um processo específico), aceitarei isso como minha resposta para a posteridade.

Roteiro:

#!/bin/bash

####
# Creates files underneath /tmp
# Requires commands: timeout  strace  stty
####
#
# All commands are GNU unless otherwise stated
#
##########################################################


####
## Initialization
####

outputFile=/tmp/out.$RANDOM.$$
uniqueLinesFile=/tmp/unique.$RANDOM.$$
finalResults=/tmp/finalOutput.txt.$$

if [ $# -ne 1 ]; then
    echo "USAGE: traceIO [PID]" >&2
    exit 2
fi

if ! [[ "$1" =~ ^[0-9]+$ ]]; then
    echo "USAGE: traceIO [PID]" >&2
    echo -e "\nGiven Process ID is not a number." >&2
    exit 2
fi

if [ ! -e /proc/$1 ]; then
    echo "USAGE: traceIO [PID]" >&2
    echo -e "\nThere is no process with $1 as the PID." >&2
    exit 2
fi

if [[ "x$PAGER" == "x" ]]; then

   for currentNeedle in less more cat; do

      which $currentNeedle >/dev/null 2>&1

      if [ $? -eq 0 ]; then
         PAGER=$currentNeedle
         break;
      fi

   done

  if [[ "x$PAGER" == "x" ]]; then

     echo "Please set \$PAGER appropriately and re-run" >&2
     exit 1

  fi

fi

####
## Tracing
####

echo "Tracing command for 30 seconds..."

timeout 30 strace -e trace=file -fvv -p $1 2>&1 | egrep -v -e "detached$" -e "interrupt to quit$" | cut -f2 -d \" > $outputFile

if [ $? -ne 0 ]; then
   echo -e "\nError performing Trace. Exiting"
   rm -f $outputFile 2>/dev/null
   exit 1
fi

echo "Trace complete. Preparing Results..."

####
## Processing
####

sort $outputFile | uniq > $uniqueLinesFile

echo -e "\n--------  RESULTS --------\n\n  #\t Path " > $finalResults
echo -e " ---\t-------" >> $finalResults

while IFS= read -r currentLine; do

   echo -n $(grep -c "$currentLine" "$outputFile")
   echo -e "\t$currentLine"

done < "$uniqueLinesFile" | sort -rn >> $finalResults

####
## Presentation
####

resultSize=$(wc -l $finalResults | awk '{print $1}')
currentWindowSize=$(stty size | awk '{print $1}')

  # We put five literal lines in the file so if we don't have more than that, there were no results
if [ $resultSize -eq 5 ]; then

   echo -e "\n\n No Results found!"

elif [ $resultSize -ge $currentWindowSize ] ; then

   $PAGER $finalResults

else

   cat $finalResults

fi

  # Cleanup
rm -f $uniqueLinesFile $outputFile $finalResults
Bratchley
fonte
2

Você pode usar o iwatch Usando o iWatch

O iWatch é muito simples de usar, suponha que você queira observar a alteração no sistema de arquivos / etc, basta executá-lo no console

$ iwatch /etc

e o iwatch informará se algo mudar neste diretório. E se você deseja ser notificado por email:

$ iwatch -m [email protected] /etc

Nesse caso, o administrador receberá uma notificação por e-mail (talvez você possa usar sua conta de gateway sms, para que você se assuste imediatamente a qualquer momento e em qualquer lugar). E se você deseja monitorar muitos diretórios diferentes, pode usar um arquivo de configuração. Este arquivo de configuração é um arquivo xml com uma estrutura fácil de entender.

vfbsilva
fonte
1
Suponho que isso esteja usando, inotifyestá correto? Eu hesitava em usar qualquer coisa com base, inotifyjá que você precisa fornecer caminhos (o que é basicamente o que estou procurando) e fiquei preocupado com a quantidade de sobrecarga que haveria se eu fizesse tudo por baixo. /Pode filtrar por PID? Talvez eu consiga tolerar lentidão temporária se for fácil extrair qual programa está sendo executado. O site também não possui nenhum exemplo de saída de comando.
Bratchley
1
@JoelDavis Eu realmente não tenho certeza. Tanto quanto sei, consome uma quantidade enorme de RAM, portanto, executá-lo em "/" será perigoso.
precisa saber é o seguinte