确定负责高I / O的特定文件


37

这是一个简单的问题,但这是我第一次真正要修复它:查找哪些特定文件/节点是大多数I / O的目标。我希望能够获得一般的系统概述,但是如果我必须提供PID或TID,那就可以了。

我想不必strace对弹出的程序进行操作iotop。优选地,使用与iotop通过文件逐项列出的工具相同的工具。我可以lsof用来查看mailman打开了哪些文件,但没有指出哪个文件正在接收I / O或接收了多少文件。

我曾在其他地方建议使用它,auditd但我不希望这样做,因为它将信息放入我们的审核文件中,我们将其用于其他目的,这似乎是我应该能够研究的问题通过这种方式。

我现在遇到的特定问题是LVM快照填充得太快。此后,我已经解决了该问题,但希望能够以这种方式解决此问题,而不是仅对ls所有打开的文件描述符执行一次,/proc/<pid>/fd以查看哪个增长最快。



是的,我之前从未见过,但是这个问题的大多数答案基本上都是这样的:“好吧,如果您以这种难以置信的特定方式来做事情,并且做一些奇怪的事情,您可能会有一个粗略的想法”,而不是直接解决的事情不需要管理员变得太花哨的问题。我并不是要批评别人,我现在意识到这个问题的困难可能在于提供这种解决方案的方式,但是即使没有像fatrace但比以前更旧的工具,似乎我写的脚本也应该如此。已提供,因为它的使用范围更广。
布莱奇利2013年

只是要清楚一点:我并不是在批评其他提供帮助的人。帮助总比没有帮助总要好。当您觉得问题应该有一个直接的答案,并且您能弄清楚自己还是看到其他人的建议是笨拙的解决方法或非常手动的处理程序(例如我最终处理邮递员问题)时,这简直令人沮丧。
2013年

是的,当我发现埋藏在网站中的新Q的答案直到挖掘了好一会才出现时,我总是感到惊讶。好像东西坏了8-)。因此,为什么最好以多种方式询问相同的Q并将其链接到较旧的Q,因为它们会被路由出去。同意您的脚本是一种更好的方法,但令我感到惊讶的是,没有一种通用工具可以满足您的要求。似乎在Unix中有很大的差距。
slm

大多数帮助只是针对性很强,可能会有些烦人,因为在回答时,您会以不同的方式一遍又一遍地重复同一件事。但这就是SE网站的本质。我不知道吉尔斯是怎么做到的。我喜欢这些时间越长的问答形式越好。
slm

Answers:


59

这个问题有几个方面可以通过其他工具部分解决,但是似乎没有哪个工具可以提供您所需要的所有功能。

iotop

该工具显示哪些进程消耗最多的I / O。但是它缺少显示特定文件名的选项。

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

默认情况下top,除了磁盘I / O以外,它会按常规处理争夺CPU时间的进程。您可以使用-a开关哄骗它,以便为您提供30,000英尺的视线,以便随着时间的推移显示按过程的累积。

$ 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 *工具(inotify,iwatch等)

这些工具提供对文件访问事件的访问,但是需要将它们专门针对特定的目录或文件。因此,当调试性能问题时,当尝试跟踪未知进程的恶意文件访问时,它们并没有帮助。

此外,inotify框架没有提供有关正在访问的文件的任何详细信息。使用这些工具只能获得访问类型,因此没有有关来回移动的数据量的信息。

iostat

根据对给定设备(硬盘驱动器)或分区的访问来显示总体性能(读取和写入)。但没有提供有关哪些文件正在生成这些访问的任何见解。

$ 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

此选项级别太低。它缺少关于正在访问哪些文件和/或索引节点的可见性,仅缺少原始块号。

$ 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%)

宽容

这是Linux内核的新增功能,也是受人欢迎的功能,因此仅在较新的发行版中(例如Ubuntu 12.10)。我的Fedora 14系统缺少它8-)。

它提供了inotify无需指定特定目录和/或文件即可获得的相同访问权限。

$ 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

上面显示了正在执行文件访问的进程ID和正在访问的文件,但是它并没有提供任何整体带宽使用率,因此每次访问都与其他访问没有区别。

那么该怎么办?

fatrace选项显示最有希望的FINALLY提供了一个工具,它可以告诉你磁盘的使用情况汇总I / O基于正在访问的文件,而不是做访问的过程。

参考文献


6
甜宝贝耶稣,slm。就我而言,您就像Unix SE的摇滚明星。您的答案始终具有令人难以置信的教育意义,并且一站式显示大量研究成果。大多数人(如果他们知道的话)只会发布最后一点,fatrace而没有发展到最后。我真的很感激您能付出更多努力,以确保人们了解完整的图片,并希望我能做的不仅仅是投票和给予赏金。
布莱奇利2013年

@JoelDavis-感谢您的客气话。我喜欢您提出规范答案的想法,因此我尝试从这里开始。我也多次遇到这个问题,希望我有这样的资源,所以我想我们会在这里创建它8-)。
slm

我很困惑的一件事:当我进行安装yum时,出于某种原因将其拉入了python3的库中。我file在上面做了一个,它看起来像是ELF可执行文件。ldd没有显示任何链接python,也没有显示strings。知道为什么它会困扰python3吗?
布莱奇利2013年

1
顺便说一句,显然我在接受奖励赏金的答案后不得不等待一段时间。这对拥有大约Unix SE总信誉点一半但仅供参考的人来说并不重要。
布莱奇利2013年

1
对我而言,这不是真正的问题,不。我可以通过适当的iotopiostat呼叫获得所需的信息。另外,我发现了python的东西,看起来(至少在Fedora 18上)有一个“ power-usage-report” python脚本,因此yum只是响应python了RPM依赖项中的事实。这样就解决了这个特殊的谜团。
布莱奇利2013年

4

我还没有得到答案,但是我确实写了这个脚本(最后),它似乎可以满足我的要求。我还没有在其他系统上测试过它,它是Linux特定的。

基本上,它只会绕strace30秒钟,过滤与文件相关的系统调用,并努力去除文件名。它会计算中该文件的出现次数,strace并向用户显示一个分页的摘要。这并不完美,但是对特定文件的系统调用次数与其执行的I / O量之间可能存在弱关联。

我还没有对它进行全面的测试,但是如果它不能立即使用,它应该为人们提供一个起点。如果将其充实,建议将其重新编写为更高级的语言(例如python)

如果我在一个不太习惯的方式后一周内没有得到答案(即使这是另一个只计算特定进程的I / O的工具),我将接受此作为我后代的答案。

脚本:

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

2

您可以使用iwatch 使用iWatch

iWatch的使用非常简单,假设您想观看/ etc文件系统中的更改,只需在控制台中运行它即可

$ iwatch /etc

iwatch会告诉您此目录中是否有更改。如果您希望通过电子邮件收到通知:

$ iwatch -m admin@smsgw.local /etc

在这种情况下,管理员将收到电子邮件通知(也许您可以使用您的短信网关帐户,因此您随时随地都会收到警报)。如果要监视许多不同的目录,则可以使用配置文件。此配置文件是一个具有易于理解的结构的xml文件。


1
我想这是inotify正确的吗?我很犹豫是否使用任何基于的东西,inotify因为您必须给它提供路径(这实际上是我要寻找的东西),并且我担心如果我只执行下面的所有操作,那么会产生多少开销/吗?如果可以很容易地提取出哪个程序正在执行,我也许可以容忍暂时的缓慢。该网站也没有任何示例命令输出。
布莱奇利2013年

1
@JoelDavis林真的不确定。据我所知,它消耗了大量的RAM,因此在“ /”下运行它会很危险。
vfbsilva 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.