找回密码
 注册
广告投放 虚位以待【阿里云】2核2G云新老同享 99元/年,续费同价做网站就用糖果主机-sugarhosts.comJtti.com-新加坡服务器,美国服务器,香港服务器
查看: 691|回复: 0

监测 Linux 进程的实时 IO 情况

[复制链接]
发表于 2010 年 10 月 2 日 15:20:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×

作为系统管理员和 VPS 服务商,经常会碰到服务器或者 VPS 磁盘 IO 繁忙的时候,VPSee 通常都会用一些工具来检测,其中一个常用的工具就是自己写的 iotop 脚本,可以很方便看到哪个进程在频繁 IO. 上周五收到一位网友的邮件和留言,问到这篇文章:如何查看进程 IO 读写情况?里的 WRITE 为什么会出现是 0 的情况,这是个好问题,VPSee 在这里好好解释一下。首先看看我们怎么样才能实时监测不同进程的 IO 活动状况。


block_dump

Linux 内核里提供了一个 block_dump 参数用来把 block 读写(WRITE/READ)状况 dump 到日志里,这样可以通过 dmesg 命令来查看,具体操作步骤是:

  1. sysctl vm.block_dump=1
复制代码
or
  1. echo 1 > /proc/sys/vm/block_dump
复制代码

然后就可以通过 dmesg 就可以观察到各个进程 IO 活动的状况了:

  1. dmesg -c
复制代码
kjournald(542): WRITE block 222528 on dm-0
kjournald(542): WRITE block 222552 on dm-0
bash(18498): dirtied inode 5892488 (ld-linux-x86-64.so.2) on dm-0
bash(18498): dirtied inode 5892482 (ld-2.5.so) on dm-0
dmesg(18498): dirtied inode 11262038 (ld.so.cache) on dm-0
dmesg(18498): dirtied inode 5892496 (libc.so.6) on dm-0
dmesg(18498): dirtied inode 5892489 (libc-2.5.so) on dm-0
问题

一位细心的网友提到这样一个问题:为什么会有 WRITE block 0 的情况出现呢?VPSee 跟踪了一段时间,发现确实有 WRITE 0 的情况出现,例如:

  1. dmesg -c
复制代码
.
...
pdflush(23123): WRITE block 0 on sdb1
pdflush(23123): WRITE block 16 on sdb1
pdflush(23123): WRITE block 104 on sdb1
pdflush(23123): WRITE block 40884480 on sdb1
...
答案

原来我们把 WRITE block 0,WRITE block 16, WRITE block 104 这里面包含的数字理解错了,这些数字不是代表写了多少 blocks,是代表写到哪个 block,为了寻找真相,VPSee 追到 Linux 2.6.18 内核代码里,在 ll_rw_blk.c 里找到了答案:

  1. $ vi linux-2.6.18/block/ll_rw_blk.c
    void submit_bio(int rw, struct bio *bio)
    {
    int count = bio_sectors(bio);
    BIO_BUG_ON(!bio->bi_size);
    BIO_BUG_ON(!bio->bi_io_vec);
    bio->bi_rw |= rw;
    if (rw & WRITE)
    count_vm_events(PGPGOUT, count);
    else
    count_vm_events(PGPGIN, count);
    if (unlikely(block_dump)) {
    char b[BDEVNAME_SIZE];
    printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
    current->comm, current->pid,
    (rw & WRITE) ? "WRITE" : "READ",
    (unsigned long long)bio->bi_sector,
    bdevname(bio->bi_bdev,b));
    }
    generic_make_request(bio);
    }
复制代码

很明显从上面代码可以看出 WRITE block 0 on sdb1,这里的 0 是 bio->bi_sector,是写到哪个 sector,不是 WRITE 了多少 blocks 的意思。还有,假设 block 设备被分成多个区的话,这个 bi_sector(sector number)是从这个分区开始计数,例如 block 0 on sdb1 就是 sdb1 分区上的第0个 sector 开始。



Jgwy.Com - Free Web Hosting Guide & Directory In China since 2001! Jgwy.Net-Jglt.Net
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|金光论坛

GMT+8, 2025 年 2 月 3 日 15:53 , Processed in 0.027295 second(s), 24 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表