每个文件的Linux IO监控?

我对在CentOS上监控磁盘IO 每个文件的实用程序或进程感兴趣。

在Win2008上, resmon实用程序允许进行这种types的向下钻取,但是我没有发现任何Linux实用程序(iostat,iotop,dstat,nmon)。

我感兴趣的是监视数据库服务器上的IO瓶颈。 有了MSSQL,我发现它是一个信息丰富的诊断,知道哪些文件/文件空间受到最大的打击。

SystemTap可能是您最好的select。

以下是iotime.stp示例的输出结果:

825946 3364 (NetworkManager) access /sys/class/net/eth0/carrier read: 8190 write: 0 825955 3364 (NetworkManager) iotime /sys/class/net/eth0/carrier time: 9 [...] 117061 2460 (pcscd) access /dev/bus/usb/003/001 read: 43 write: 0 117065 2460 (pcscd) iotime /dev/bus/usb/003/001 time: 7 [...] 3973737 2886 (sendmail) access /proc/loadavg read: 4096 write: 0 3973744 2886 (sendmail) iotime /proc/loadavg time: 11 

缺点(除了学习曲线),您将需要安装内核debugging ,这在生产系统上可能是不可能的。 但是,您可以在开发系统上编译模块的地方使用交叉检测 ,然后在生产系统上运行.ko

或者如果您不耐烦,请参阅第4章初学者指南中有用的SystemTap脚本 。

SystemTap *脚本:

 #!/usr/bin/env stap # # Monitor the I/O of a program. # # Usage: # ./monitor-io.stp name-of-the-program global program_name = @1 probe begin { printf("%5s %1s %6s %7s %s\n", "PID", "D", "BYTES", "us", "FILE") } probe vfs.read.return, vfs.write.return { # skip other programs if (execname() != program_name) next if (devname=="N/A") next time_delta = gettimeofday_us() - @entry(gettimeofday_us()) direction = name == "vfs.read" ? "R" : "W" # If you want only the filename, use // filename = kernel_string($file->f_path->dentry->d_name->name) # If you want only the path from the mountpoint, use // filename = devname . "," . reverse_path_walk($file->f_path->dentry) # If you want the full path, use filename = task_dentry_path(task_current(), $file->f_path->dentry, $file->f_path->mnt) printf("%5d %1s %6d %7d %s\n", pid(), direction, $return, time_delta, filename) } 

输出如下所示:

 [root@sl6 ~]# ./monitor-io.stp cat PID D BYTES us FILE 3117 R 224 2 /lib/ld-2.12.so 3117 R 512 3 /lib/libc-2.12.so 3117 R 17989 700 /usr/share/doc/grub-0.97/COPYING 3117 R 0 3 /usr/share/doc/grub-0.97/COPYING 

或者,如果您select仅显示来自挂载点的path:

 [root@f19 ~]# ./monitor-io.stp cat PID D BYTES us FILE 26207 R 392 4 vda3,usr/lib64/ld-2.17.so 26207 R 832 3 vda3,usr/lib64/libc-2.17.so 26207 R 1758 4 vda3,etc/passwd 26207 R 0 1 vda3,etc/passwd 26208 R 392 3 vda3,usr/lib64/ld-2.17.so 26208 R 832 3 vda3,usr/lib64/libc-2.17.so 26208 R 35147 16 vdb7,ciupicri/doc/grub2-2.00/COPYING 26208 R 0 2 vdb7,ciupicri/doc/grub2-2.00/COPYING [root@f19 ~]# mount | grep -E '(vda3|vdb7)' /dev/vda3 on / type ext4 (rw,relatime,seclabel,data=ordered) /dev/vdb7 on /mnt/mnt1/mnt11/data type xfs (rw,relatime,seclabel,attr2,inode64,noquota) 

限制/错误:

  • 基于mmap的I / O不会显示,因为devname"N/A"
  • tmpfs上的文件不会显示,因为devname"N/A"
  • 如果读取来自caching或写入缓冲区,则无关紧要

Matthew Ife的节目结果:

  • 为mmaptest私人:

      PID D BYTES us FILE 3140 R 392 5 vda3,usr/lib64/ld-2.17.so 3140 R 832 5 vda3,usr/lib64/libc-2.17.so 3140 W 23 9 N/A,3 3140 W 23 4 N/A,3 3140 W 17 3 N/A,3 3140 W 17 118 N/A,3 3140 W 17 125 N/A,3 
  • 对于mmaptest共享:

      PID D BYTES us FILE 3168 R 392 3 vda3,usr/lib64/ld-2.17.so 3168 R 832 3 vda3,usr/lib64/libc-2.17.so 3168 W 23 7 N/A,3 3168 W 23 2 N/A,3 3168 W 17 2 N/A,3 3168 W 17 98 N/A,3 
  • 对于diotest (直接I / O):

      PID D BYTES us FILE 3178 R 392 2 vda3,usr/lib64/ld-2.17.so 3178 R 832 3 vda3,usr/lib64/libc-2.17.so 3178 W 16 6 N/A,3 3178 W 1048576 509 vda3,var/tmp/test_dio.dat 3178 R 1048576 244 vda3,var/tmp/test_dio.dat 3178 W 16 25 N/A,3 

* RHEL 6或同等版本的快速安装说明: yum install systemtapdebuginfo-install kernel

你实际上想要使用blktrace 。 请参阅使用Seekwatcher和blktrace可视化Linux IO 。

我会看看我能不能很快发布我的一个例子。


编辑:

你没有提到Linux的发行版,但是如果你使用的是一个类似RHEL的系统,那么在Linux或Linux 系统上的dtrace脚本也许是一个很好的例子。

我知道的唯一的工具可以通过文件监视I / O活动inotifywatch 。 它是inotify-tools软件包的一部分。 不幸的是,它只给你操作的次数。

使用iotop获取贡献较高IO的进程的PID

针对您生成的PID运行strace,您将看到哪些文件正在被特定进程访问

 strace -f -p $PID -e trace=open,read,write 

你的意思是像iotop

我认为你可能会问错误的问题。 如果您正在寻找I / O瓶颈,那么查看磁盘上发生的事情可能同样重要。 数据库是臭名昭着的随机I / O可以显着降低吞吐量,尤其是如果你只有几个主轴。

更有意思的是看看你自己是否在磁盘上等待很长时间。 你可以用collectl通过命令“collectl -sD”来做到这一点,它会显示单独的磁盘性能统计信息。 是 – 把它变成顶级的工具。 如果涉及大量磁盘,请通过colmux:colmux -command“-sD”运行它,它可以让您按照您select的列进行sorting,即使在多个系统中也是如此。

你可以监视每个块设备的I / O(通过/ proc / diskstats)和每个进程(通过/proc/$PID/io或taskstats进行 /proc/$PID/io 记账 ),但是我不知道每个文件执行的方式。

我最终为此使用了Sysdig

虽然在这里的答案有很多很好的信息,我想知道它是否适用?

如果你正在谈论的是十几GB的文件,不断被写入,那么除非它们是不断附加到日志文件或类似的文件(在这种情况下只是监视文件大小),这很可能是文件mmap'd 。 如果是这样,那么最好的答案可能是你应该停止查看大多数解决scheme。 首先,你应该问的任何其他build议的解决scheme是“是否与mmap一起工作”,因为他们大多数都不会。但是,您可能能够将问题转变为监视块设备,而不是监视文件。

当一个程序从mmap'd文件中寻找一个页面时,它只是在虚拟内存中引用一个位置。 该页面可能已经或可能不在内存中。 如果不是,则会生成页面错误,这会触发从磁盘加载的页面,但是这发生在虚拟内存系统中,而不容易与特定的应用程序或特定的文件绑定。 同样,当你的应用程序更新一个mmap'd页面,根据标志,可能不会立即写入磁盘,并在某些情况下可能根本不会去磁盘(尽pipe大概最后这不是你有兴趣的情况下在)。

对于mmap文件来说,我能想到的最好的方法就是将每个感兴趣的文件放到一个单独的设备上,然后使用设备统计信息来收集您的使用信息。 你可以使用lvm分区。 绑定安装将无法正常工作,因为它不会创build新的块设备。

一旦你在独立的块设备上的文件,你可以从/ sys / block / *,或/ proc / diskstats

将其引入生产服务器可能太具有破坏性,但也许可以使用它。

如果文件没有被映射,那么是的,你可以在这里select其他解决scheme之一。

最近我正在用collectl修补,它看起来是一个很好的工具,而且很安装。 最有趣的是,你可以找出哪个是负责IO瓶颈的过程。 我会build议你阅读使用Collectl ,这可能是有用的。

我会build议你检查http://dag.wieers.com/home-made/dstat/ 。 这个伟大的工具可以检查很多的统计数据。

可能会解决这个问题。

inotify API提供了监视文件系统事件的机制.otify可用于监视单个文件或监视目录。 当监视目录时,inotify将返回目录本身的事件以及目录中的文件。

使用inotify监视文件系统活动

inotify引用

我认为iotop是Linux上识别IO瓶颈的最佳工具之一。