Określanie określonego pliku odpowiedzialnego za wysokie operacje we / wy

37

Jest to prosty problem, ale po raz pierwszy musiałem go naprawić: znalezienie, które konkretne pliki / i-węzły są celami największej liczby operacji we / wy. Chciałbym móc uzyskać ogólny przegląd systemu, ale jeśli muszę podać PID lub TID, nic mi nie jest.

Chciałbym przejść bez konieczności straceuruchamiania programu, który się pojawi iotop. Najlepiej, używając narzędzia w tym samym stylu, co narzędzie, iotopktóre sortuje według pliku. Mogę użyć, lsofaby zobaczyć, które pliki listonosz ma otwarty, ale nie wskazuje, który plik otrzymuje We / Wy ani ile.

Widziałem gdzie indziej, gdzie sugerowano użycie, auditdale wolałbym tego nie robić, ponieważ umieszczałoby to informacje w naszych plikach kontroli, których używamy do innych celów, i wydaje się, że to problem, który powinienem być w stanie zbadać w ten sposób.

Konkretny problem, jaki mam teraz, to zbyt szybkie zapełnianie migawek LVM. Od tego czasu rozwiązałem problem, ale chciałbym móc go rozwiązać w ten sposób, zamiast robić tylko lswszystkie otwarte deskryptory plików, /proc/<pid>/fdaby zobaczyć, który z nich rośnie najszybciej.

Bratchley
źródło
ewentualnie powiązane: unix.stackexchange.com/questions/9520/…
slm
Tak, nie widziałem tego wcześniej, ale większość odpowiedzi na to pytanie była w zasadzie taka: „Cóż, jeśli robisz rzeczy w niewiarygodnie specyficzny sposób i robisz coś dziwnego, możesz mieć szorstki pomysł” kontra coś, co bezpośrednio rozwiązuje problem bez wymagania, aby administrator był zbyt fantazyjny. Nie mam zamiaru krytykować innych i zdaję sobie sprawę, że trudność tego problemu jest prawdopodobnie sposobem oferowania takich rozwiązań, ale wydaje się, że nawet jeśli nie ma takiego narzędzia, fatraceale starsze, coś takiego jak skrypt, który napisałem, powinno zostały zaoferowane, ponieważ są bardziej użyteczne.
Bratchley,
Żeby było jasne: nie krytykuję innych, którzy oferowali pomoc. Pomoc jest zawsze lepsza niż brak pomocy. Jest to po prostu frustrujące, gdy uważasz, że problem powinien mieć bezpośrednią reakcję, a wszystko, co możesz sam zrozumieć lub zobaczyć, jak inni sugerują, to kłopotliwe obejścia lub bardzo ręczne procesy (takie jak to, co skończyłem z moim problemem z listonoszem).
Bratchley,
Tak, zawsze jestem zdumiony, gdy znajduję odpowiedzi na nowe Q zakopane tutaj, które nie pojawiają się, dopóki nie zacznę kopać przez jakiś czas. Wydaje się, że coś tam zepsuło 8-). Dlatego dobrze jest zapytać o to samo Q na wiele sposobów i połączyć je ze starszymi, gdy zostaną wyrzucone. Zgadzam się, że twój skrypt jest lepszym podejściem, nadal jestem zaskoczony, że nie ma narzędzia ogólnego przeznaczenia, które spełniałoby Twoje wymagania. Wygląda na dużą lukę w Uniksie.
slm
Większość pomocy jest po prostu bardzo ukierunkowana, co może być trochę irytujące, ponieważ odpowiadając, mówisz to samo wiele razy w różny sposób. Ale taka jest natura witryn SE. Nie wiem jak to robi Gilles. Podoba mi się to, że dłuższe pytania i odpowiedzi są lepsze.
slm

Odpowiedzi:

59

Istnieje kilka aspektów tego pytania, które zostały częściowo rozwiązane za pomocą innych narzędzi, ale wydaje się, że nie ma jednego narzędzia zapewniającego wszystkie funkcje, których szukasz.

iotop

To narzędzie pokazuje, które procesy zużywają najwięcej I / O. Brakuje jednak opcji wyświetlania określonych nazw plików.

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

Domyślnie robi to, co toprobi normalnie dla procesów rywalizujących o czas procesora, z wyjątkiem dyskowych operacji we / wy. Możesz go nakłonić, aby uzyskać widok 30 000 stóp za pomocą -aprzełącznika, tak aby z czasem pokazywał akumulację według procesu.

$ 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 * narzędzia (inotify, iwatch itp.)

Narzędzia te zapewniają dostęp do zdarzeń dostępu do plików, jednak muszą być specjalnie ukierunkowane na określone katalogi lub pliki. Nie są więc tak pomocne, gdy próbują wyśledzić nieuczciwy dostęp do pliku przez nieznany proces podczas debugowania problemów z wydajnością.

Również inotifyframework nie podaje żadnych szczegółów na temat plików, do których uzyskiwany jest dostęp. Tylko typ dostępu, więc żadne informacje o ilości danych przenoszonych tam iz powrotem nie są dostępne przy użyciu tych narzędzi.

iostat

Pokazuje ogólną wydajność (odczyt i zapis) na podstawie dostępu do danego urządzenia (dysku twardego) lub partycji. Ale nie zapewnia wglądu w to, które pliki generują te dostępy.

$ 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

Ta opcja ma zbyt niski poziom. Brakuje wglądu w to, które pliki i / lub i-węzły są dostępne, tylko surowe numery bloków.

$ 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

Jest to nowy dodatek do jądra Linuksa i mile widziany, więc jest dostępny tylko w nowszych dystrybucjach, takich jak Ubuntu 12.10. W moim systemie Fedora 14 brakowało go 8-).

Zapewnia taki sam dostęp, jak można uzyskać inotifybez konieczności kierowania do określonego katalogu i / lub plików.

$ 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

Powyższe pokazuje identyfikator procesu, który uzyskuje dostęp do pliku i do którego pliku ma dostęp, ale nie zapewnia ogólnego wykorzystania przepustowości, więc każdego dostępu nie można odróżnić od żadnego innego dostępu.

Co więc zrobić?

Ta fatraceopcja pokazuje najbardziej obiecujące dla KOŃCOWO dostarczenie narzędzia, które może pokazać zagregowane użycie dysku I / O na podstawie plików, do których uzyskiwany jest dostęp, zamiast procesów uzyskujących dostęp.

Referencje

slm
źródło
6
Słodki Jezu, slm. Jeśli chodzi o mnie, jesteś jak gwiazda rocka Unix SE. Twoje odpowiedzi są zawsze niezwykle edukacyjne i pokazują wiele badań w jednym miejscu. Większość ludzi (gdyby o tym wiedziała) napisałaby ostatni kawałek fatracei nie rozwinęła go zbyt wiele. Naprawdę doceniam sposób, w jaki dokładasz wszelkich starań, aby upewnić się, że ludzie rozumieją pełny obraz i żałuję, że nie mogę zrobić więcej niż tylko głosować i dać nagrodę.
Bratchley,
@JoelDavis - dziękuję za bardzo miłe słowa. Podobał mi się twój pomysł kanonicznej odpowiedzi, więc starałem się zacząć tutaj. Wiele razy napotkałem ten problem i żałowałem, że nie mam takiego zasobu, więc pomyślałem, że stworzymy go tutaj 8-).
slm
Jedno mnie nie myli: kiedy zrobiłem instalację, yumściągnąłem biblioteki python3 z jakiegoś powodu. Zrobiłem fileto i wygląda na to, że jest to plik wykonywalny ELF. lddnie wyświetla żadnych linków pythoni nie ma strings. Wiesz, dlaczego miałeś problem z python3?
Bratchley,
1
BTW, najwyraźniej muszę trochę poczekać po zaakceptowaniu odpowiedzi na nagrodę. Nie znaczy to, że ma to znaczenie dla kogoś, kto ma mniej więcej połowę punktów reputacji w Unix SE, ale tylko dla ciebie.
Bratchley,
1
To nie jest dla mnie problem, nie. Mogę uzyskać potrzebne informacje na ten temat za pośrednictwem odpowiednich iotopi iostatpołączeń. Zrozumiałem też kwestię python, wygląda na to, że (przynajmniej na Fedorze 18) jest pythonskrypt „raport zużycia energii”, więc yumwłaśnie reagowałem na fakt, że pythonjest to zależność RPM. Aby ta szczególna tajemnica została rozwiązana.
Bratchley,
4

Nie otrzymałem jeszcze odpowiedzi, ale napisałem ten skrypt (na końcu) i wydaje się, że robi to, co chcę. Nie testowałem tego na innych systemach i jest on specyficzny dla systemu Linux.

Zasadniczo po prostu zawija się straceprzez 30 sekund, filtrując wywołania systemowe związane z plikami i stara się usunąć nazwę pliku. Liczy liczbę wystąpień tego pliku w stracei przedstawia użytkownikowi paginowane podsumowanie. Nie jest idealny, ale liczba wywołań systemowych do określonego pliku może mieć słabą korelację z wydajnością operacji we / wy.

Nie przetestowałem go w pełni, ale jeśli nie działa po wyjęciu z pudełka, powinno dać ludziom miejsce, od którego można zacząć. Jeśli zostanie już rozwinięty, może być wskazane ponowne zapisanie go w języku wyższego poziomu, takim jak python .

Jeśli nie otrzymam odpowiedzi w ciągu tygodnia od mniej domowego podejścia (nawet jeśli jest to inne narzędzie, które liczy tylko operacje wejścia / wyjścia danego procesu), zaakceptuję to jako moją odpowiedź dla potomności.

Scenariusz:

#!/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
źródło
2

Możesz użyć iwatch za pomocą iWatch

iWatch jest bardzo prosty w użyciu, załóżmy, że chcesz obejrzeć zmianę w systemie plików / etc, wystarczy uruchomić go w konsoli

$ iwatch /etc

i iwatch powie ci, jeśli coś się zmieni w tym katalogu. A jeśli chcesz otrzymywać powiadomienia pocztą e-mail:

$ iwatch -m [email protected] /etc

W takim przypadku administrator otrzyma powiadomienie e-mailem (być może możesz użyć konta bramy sms, więc natychmiast zostaniesz zaalarmowany w dowolnym miejscu i czasie). A jeśli chcesz monitorować wiele katalogów różnic, możesz użyć pliku konfiguracyjnego. Ten plik konfiguracyjny jest plikiem XML z łatwą do zrozumienia strukturą.

vfbsilva
źródło
1
Przypuszczam, że to używa. Czy inotifyto prawda? Wahałem się przed użyciem czegokolwiek opartego na tym, inotifyże musisz podać ścieżki (co jest zasadniczo tym, czego szukam) i martwiłem się, ile byłoby narzutu, gdybym tylko zrobił wszystko pod spodem /Czy można filtrować według PID? Być może będę w stanie tolerować chwilowe spowolnienie, jeśli łatwo będzie wyodrębnić, który program to robi. Witryna nie ma również żadnych przykładowych danych wyjściowych poleceń.
Bratchley,
1
@JoelDavis Im naprawdę nie jestem pewien. O ile wiem, zużywa ogromną ilość pamięci RAM, dlatego uruchomienie go pod „/” będzie niebezpieczne.
vfbsilva,