我尝试尽量减少对新 SSD 系统驱动器的磁盘写入。但我还是无法看到 iostat 输出:
~ > iostat -d 10 /dev/sdb
Linux 2.6.32-44-generic (Pluto) 13.11.2012 _i686_ (2 CPU)
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sdb 8,60 212,67 119,45 21010156 11800488
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sdb 3,00 0,00 40,00 0 400
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sdb 1,70 0,00 18,40 0 184
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sdb 1,20 0,00 28,80 0 288
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sdb 2,20 0,00 32,80 0 328
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sdb 1,20 0,00 23,20 0 232
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sdb 3,40 19,20 42,40 192 424
我看见有写入 sdb 的内容。我该如何解决哪个过程写?
我知道iotop,但它没有显示正在访问哪个文件系统。
答案1
您至少可以从开始iotop
。它不会告诉您正在写入哪个文件系统,但会为您提供一些要调查的过程。
sudo apt-get install iotop
sudo iotop
它显示瞬时磁盘读写以及读取或写入的命令名称。
如果您尝试捕获不频繁写入的进程,则可以使用该--accumulated
选项或将输出记录到文件中:
sudo -i
iotop --batch > iotop_log_file
显然,日志文件的写入将显示在结果中,但您也应该能够grep
看到其他进程写入磁盘。
此时,你应该能够找到一些候选的可疑进程。左栏iotop
显示了进程号.接下来,找出进程正在写入哪个文件描述符:
sudo -i
strace -p <pid> 2>&1 | grep write
当进程写入时你应该看到如下输出:
write(1, "\n", 1) = 1
write(4, "test\n", 5) = 5
write(1, ">>> ", 4) = 4
要写入的第一个参数是文件描述符。我们可能正在寻找大于 2 的值,因为 0、1 和 2 只是 stdin、stdout 和 stderr。文件描述符 4 看起来很有趣。
现在,您可以使用以下命令找出文件描述符指向哪个文件:
lsof -p <pid>
其输出结果如下:
...
python 23908 rob mem REG 8,1 26258 8392656 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
python 23908 rob 0u CHR 136,5 0t0 8 /dev/pts/5
python 23908 rob 1u CHR 136,5 0t0 8 /dev/pts/5
python 23908 rob 2u CHR 136,5 0t0 8 /dev/pts/5
python 23908 rob 3w REG 0,25 909 9049082 /home/rob/testfile
python 23908 rob 4w REG 0,25 20 9049087 /home/rob/another_test_file
看第 4 列。4w
表示文件描述符 4 已打开并可进行写入,并且文件为another_test_file
。
进程可能会打开、写入然后关闭文件,在这种情况下lsof
不会显示它。您可能会发现这种情况发生:
strace -p <pid> 2>&1 | grep open
答案2
下面利用内核的虚拟内存块转储机制,首先获取perl脚本:
wget https://raw.githubusercontent.com/true/aspersa-mirror/master/iodump
然后打开块转储:
echo 1 | sudo tee /proc/sys/vm/block_dump
并运行以下命令:
while true; do sleep 1; sudo dmesg -c; done | perl iodump
..然后按Controlc完成,您将看到类似以下内容:
^C# Caught SIGINT.
TASK PID TOTAL READ WRITE DIRTY DEVICES
jbd2/sda3-8 620 40 0 40 0 sda3
jbd2/sda1-8 323 21 0 21 0 sda1
#1 4746 11 0 11 0 sda3
flush-8:0 2759 7 0 7 0 sda1, sda3
command-not-fou 9703 4 4 0 0 sda1
mpegaudioparse8 8167 2 2 0 0 sda3
bash 9704 1 1 0 0 sda1
bash 9489 1 0 1 0 sda3
mount.ecryptfs_ 9698 1 1 0 0 sda1
完成后关闭块转储:
echo 0 | sudo tee /proc/sys/vm/block_dump
谢谢http://www.xaprb.com/blog/2009/08/23/how-to-find-per-process-io-statistics-on-linux/以获取这些有用的信息。