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

33

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

Eu gostaria de ir sem ter que fazer um strace no programa que aparece em iotop . De preferência, usando uma ferramenta na mesma veia como iotop , mas uma que relacione por arquivo. Posso usar lsof para ver quais arquivos o mailman abriu, mas não indica qual arquivo está recebendo E / S ou quanto.

Eu já vi em outro lugar onde foi sugerido usar auditd , mas eu preferiria não fazer isso, pois colocaria as informações em nossos arquivos de auditoria, que usamos para outros propósitos e isso parece ser um problema que eu deveria ser capaz de pesquisar desta forma.

O problema específico que tenho agora é o preenchimento instantâneo de instantâneos do LVM. Desde então, resolvi o problema, mas gostaria de ter conseguido corrigi-lo desta maneira, em vez de apenas fazer um ls em todos os descritores de arquivos abertos em /proc/<pid>/fd para ver qual deles estava crescendo mais rapidamente.

    
por Bratchley 15.08.2013 / 16:19

3 respostas

52

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

iotop

Essas ferramentas mostram 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 o% normaltop faz para processos disputando o tempo da CPU, exceto para E / S de disco. Você pode persuadi-lo para obter uma visualização de 30.000 pés usando a opção -a para mostrar uma acumulação 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

i * ferramentas (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. Então, eles não são úteis quando tentam rastrear um acesso de arquivo invasor por um processo desconhecido, ao depurar problemas de desempenho.

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

iostat

Mostra o desempenho geral (lê & escreve) com base no acesso a um determinado dispositivo (disco rígido) ou partição. Mas não fornece informações 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 é de 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 bem-vinda, por isso é apenas em novas distribuições como o Ubuntu 12.10. Meu sistema Fedora 14 estava faltando 8-).

Ele fornece o mesmo acesso que você pode obter através de inotify sem ter que segmentar 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

O texto acima mostra a ID do processo que está acessando o arquivo e o arquivo que 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 opção fatrace mostra a mais promissora 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 fazem o acesso. / p>

Referências

por 19.08.2013 / 04:38
3

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

Basicamente, ele apenas envolve strace por 30 segundos, filtrando chamadas de sistema relacionadas a arquivos e se esforçando para remover o nome do arquivo. Ele conta o número de ocorrências desse arquivo no strace e 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 o desempenho de E / S.

Eu não testei totalmente, mas se não funcionar imediatamente, isso deve dar às pessoas um lugar para começar. Se ela for mais desenvolvida, talvez seja recomendável reescrever isso em uma linguagem de nível superior como python .

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

Script:

#!/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
    
por 16.08.2013 / 15:17
1

Você pode usar iwatch Usando o iWatch

O iWatch é muito simples de usar, suponha que você queira assistir a mudança no sistema de arquivos / etc, você só precisa executá-lo no console

$ iwatch /etc

e o iwatch lhe dirá se algo mudar neste diretório. E se você quiser ser notificado por e-mail:

$ 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ê quiser monitorar muitos diretórios de diferenças, você pode usar um arquivo de configuração. Este arquivo de configuração é um arquivo xml com uma estrutura fácil de entender.

    
por 15.08.2013 / 16:32