web-dev-qa-db-fra.com

Détermination du fichier spécifique responsable des E / S élevées

C'est un problème simple mais la première fois que j'ai eu à le résoudre: trouver quels fichiers/inodes spécifiques sont les cibles de la plupart des E/S. J'aimerais pouvoir avoir une vue d'ensemble du système, mais si je dois donner un PID ou un TID, je suis d'accord avec ça.

J'aimerais aller sans avoir à faire un strace sur le programme qui apparaît dans iotop. De préférence, en utilisant un outil dans la même veine que iotop mais qui détaille par fichier. Je peux utiliser lsof pour voir quels fichiers mailman a ouverts mais cela n'indique pas quel fichier reçoit des E/S ou combien.

J'ai vu ailleurs où il a été suggéré d'utiliser auditd mais je préférerais ne pas le faire car cela mettrait les informations dans nos fichiers d'audit, que nous utilisons à d'autres fins et cela semble être un problème que je devrait pouvoir faire des recherches de cette manière.

Le problème spécifique que j'ai en ce moment est que les instantanés LVM se remplissent trop rapidement. J'ai depuis résolu le problème, mais j'aurais pu le résoudre de cette façon plutôt que de simplement faire un ls sur tous les descripteurs de fichiers ouverts dans /proc/<pid>/fd pour voir lequel croît le plus rapidement.

39
Bratchley

Il y a plusieurs aspects à cette question qui ont été partiellement traités par d'autres outils, mais il ne semble pas y avoir un seul outil qui offre toutes les fonctionnalités que vous recherchez.

iotop

Cet outil montre quels processus consomment le plus d'E/S. Mais il manque des options pour afficher des noms de fichiers spécifiques.

$ 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]

Par défaut, il fait ce que fait régulièrement top pour les processus rivalisant pour le temps du CPU, à l'exception des E/S disque. Vous pouvez l'amadouer pour vous donner une vue de 30 000 pieds en utilisant le -a bascule pour afficher une accumulation par processus, dans le temps.

$ 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

outils i * (inotify, iWatch, etc.)

Ces outils permettent d'accéder aux événements d'accès aux fichiers, mais ils doivent être spécifiquement ciblés sur des répertoires ou des fichiers spécifiques. Ils ne sont donc pas très utiles lors de la recherche d'un accès à un fichier non autorisé par un processus inconnu, lors du débogage de problèmes de performances.

Le cadre inotify ne fournit pas non plus de détails sur les fichiers auxquels vous accédez. Seul le type d'accès, donc aucune information sur la quantité de données déplacées d'avant en arrière n'est disponible, à l'aide de ces outils.

iostat

Affiche les performances globales (lectures et écritures) en fonction de l'accès à un périphérique donné (disque dur) ou à une partition. Mais ne donne aucune idée des fichiers qui génèrent ces accès.

$ 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

Cette option est de niveau trop bas. Il manque de visibilité sur les fichiers et/ou les inodes auxquels on accède, juste les numéros de bloc bruts.

$ 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

Il s'agit d'un nouvel ajout au noyau Linux et bienvenu, donc il n'est disponible que dans les distributions plus récentes telles que Ubuntu 12.10. Mon système Fedora 14 en manquait 8-).

Il offre le même accès que vous pouvez obtenir via inotify sans avoir à cibler un répertoire et/ou des fichiers particuliers.

$ 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

Ce qui précède vous montre l'ID de processus qui accède au fichier et à quel fichier il accède, mais il ne vous donne aucune utilisation globale de la bande passante, donc chaque accès est impossible à distinguer de tout autre accès.

Alors que faire?

L'option fatrace montre le plus de promesses pour [~ # ~] enfin [~ # ~] fournissant un outil qui peut vous montrer l'agrégat utilisation des E/S disque en fonction des fichiers auxquels on accède, plutôt que des processus effectuant l'accès.

Références

60
slm

Je n'ai pas encore obtenu de réponse mais j'ai écrit ce script (à la fin) et il semble faire ce que je veux. Je ne l'ai pas testé sur d'autres systèmes et il est spécifique à Linux.

Fondamentalement, il s'enroule autour de strace pendant 30 secondes, filtrant les appels système liés aux fichiers et s'efforce de supprimer le nom de fichier. Il compte le nombre d'occurrences de ce fichier dans le strace et présente un résumé paginé à l'utilisateur. Ce n'est pas parfait, mais le nombre d'appels système à un fichier particulier peut avoir une faible corrélation avec la quantité d'E/S qu'il effectue.

Je ne l'ai pas testé complètement, mais si cela ne fonctionne pas, il devrait donner aux gens un point de départ. S'il se développe davantage, il peut être conseillé de le réécrire dans un langage de niveau supérieur comme python .

Si je n'obtiens pas de réponse dans la semaine suivant une méthode moins homogène de le faire (même si c'est un autre outil qui compte uniquement les E/S d'un processus particulier), j'accepterai cela comme ma réponse pour la postérité.

Scénario:

#!/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
5
Bratchley

Vous pouvez utiliser iWatch Utiliser iWatch

iWatch est très simple à utiliser, supposons que vous vouliez voir le changement dans le système de fichiers/etc, il vous suffit de l'exécuter dans la console

$ iWatch /etc

et iWatch vous dira si quelque chose change dans ce répertoire. Et si vous souhaitez être averti par e-mail:

$ iWatch -m [email protected] /etc

Dans ce cas, l'administrateur recevra une notification par e-mail (vous pouvez peut-être utiliser votre compte de passerelle sms, vous serez donc immédiatement alarmé à tout moment et n'importe où). Et si vous souhaitez surveiller de nombreux répertoires de différences, vous pouvez utiliser un fichier de configuration. Ce fichier de configuration est un fichier xml avec une structure facilement compréhensible.

2
vfbsilva