进一步调查磁盘写入,以找出哪个进程写入我的SSD


11

我尝试尽量减少对新的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,但是它没有显示正在访问哪个文件系统。

Answers:


7

以下使用内核的虚拟内存块转储机制。首先获取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/提供的有用信息。


10

您至少可以从iotop开始。它不会告诉您正在编写哪个文件系统,但是会为您提供一些调查过程。

sudo apt-get install iotop
sudo iotop

它显示瞬时磁盘读写,以及命令读写的名称。

如果尝试捕获不经常写入的进程,则可以使用该--accumulate选项或将输出记录到文件中:

sudo -i
iotop --batch > iotop_log_file

显然,日志文件的写入将显示在结果中,但是您还应该能够grep将其他进程写入磁盘。

至此,您应该能够找到一些候选可疑进程。iotop的左列显示pid。接下来,找出该进程正在写入哪个文件描述符:

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

看第四栏。4w表示文件描述符4已打开可写入,文件为another_test_file

进程可能会打开,写入然后关闭文件,在这种情况下,lsof将不会显示该文件。您可能会遇到以下情况:

strace -p <pid> 2>&1 | grep open

我不知道--accumulte这真是很酷的功能!非常感谢你!!!iotop --batch输出重定向失败,并出现UnicodeEncodeError:'ascii'编解码器无法对位置92-99中的字符进行编码:文件“ /usr/lib/pymodules/python2.6/iotop/ui”中的序号不在range(128)中。 py”,第405行,在refresh_display中
zuba 2012年

我很高兴我的回答至少有一定用处。重定向对我有用;不确定我能解释一下。
罗伯·费舍尔

好的,我玩了一下,发现我可以使用lsof和strace至少做足够的侦探工作来捕获写入SSD的进程。希望这最终能回答所问的问题,尽管看起来Colin Ian King的答案更容易!
罗伯·费舍尔

1
抱歉,您的回复很晚,直到我使用strace之前,我无话可说。我投票赞成另一种聪明的方法。我发现编写脚本来实现它非常困难,因为在编写shell脚本方面经验很少。这就是为什么我选择了另一个解决方案。感谢您分享你的知识!
zuba 2012年

应该是--accumulated,但是堆栈交换需要6个字符才能接受帖子的编辑。
h__19年
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.