当前位置:Gxlcms > 数据库问题 > block_dump观察Linux IO写入的具体文件(mysqld)

block_dump观察Linux IO写入的具体文件(mysqld)

时间:2021-07-01 10:21:17 帮助过:9人阅读

一、使用方法:

需要先停掉syslog功能,因为具体IO数据要通过printk输出,如果syslog存在,则会往message产生大量IO,干扰正常结果

 

 
1 2 suse:~ # service syslog stop Shutting down syslog services done

 

然后启动block_dump

 

 
1 suse:~ # echo 1 > /proc/sys/vm/block_dump

 

先说效果:

 

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 suse:~ # dmesg | tail dmesg(3414): dirtied inode 9594 (LC_MONETARY) on sda1 dmesg(3414): dirtied inode 9238 (LC_COLLATE) on sda1 dmesg(3414): dirtied inode 9241 (LC_TIME) on sda1 dmesg(3414): dirtied inode 9606 (LC_NUMERIC) on sda1 dmesg(3414): dirtied inode 9350 (LC_CTYPE) on sda1 kjournald(506): WRITE block 3683672 on sda1 kjournald(506): WRITE block 3683680 on sda1 kjournald(506): WRITE block 3683688 on sda1 kjournald(506): WRITE block 3683696 on sda1 kjournald(506): WRITE block 3683704 on sda1 kjournald(506): WRITE block 3683712 on sda1 kjournald(506): WRITE block 3683720 on sda1 kjournald(506): WRITE block 3683728 on sda1 kjournald(506): WRITE block 3683736 on sda1 kjournald(506): WRITE block 3683744 on sda1

 

通过dmesg信息可以看到IO正在写那些文件,有进程号,inode号,文件名和磁盘设备名;但每个文件写了多少呢,仅仅通过dirtied inode就看不出来了,还需要分析WRITE block,后面的数字并不是真正的块号,而是内核IO层获取的扇区号,除以8即为块号,然后根据debugfs工具的icheck和ncheck选项,就可以获取该文件系统块属于哪个具体文件,具体请google之。

二、基本原理:

block_dump的原理其实很简单,内核在IO层根据标志block_dump在IO提交给磁盘的关口卡主过关的每一个BIO,将它们的数据打出来:

 

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 void submit_bio(int rw, struct bio *bio) {      int count = bio_sectors(bio);        bio->bi_rw |= rw;   /* * If it‘s a regular read/write or a barrier with data attached, * go through the normal accounting stuff before submission. */      if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {          if (rw & WRITE) {          count_vm_events(PGPGOUT, count);      } else {          task_io_account_read(bio->bi_size);          count_vm_events(PGPGIN, count);      }        if (unlikely(block_dump)) {          char b[BDEVNAME_SIZE];          printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)n",               current->comm, task_pid_nr(current),               (rw & WRITE) ? "WRITE" : "READ",               (unsigned long long)bio->bi_sector,               bdevname(bio->bi_bdev, b),               count);         }     }       generic_make_request(bio); }

 

具体WRITE block块号和文件系统块号之间的对应关系在submit_bh函数中决定

 

 
1 bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);

 

inode的block_dump实现是通过block_dump___mark_inode_dirty搞定的,这次把关口架在inode脏数据写回的路上,把每个过关的inode信息打出来:

 

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 void __mark_inode_dirty(struct inode *inode, int flags) {   if (unlikely(block_dump)) block_dump___mark_inode_dirty(inode);   }   static noinline void block_dump___mark_inode_dirty(struct inode *inode) { if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) { struct dentry *dentry; const char *name = "?";   dentry = d_find_alias(inode); if (dentry) { spin_lock(&dentry->d_lock); name = (const char *) dentry->d_name.name; } printk(KERN_DEBUG "%s(%d): dirtied inode %lu (%s) on %sn", current->comm, task_pid_nr(current), inode->i_ino, name, inode->i_sb->s_id); if (dentry) { spin_unlock(&dentry->d_lock); dput(dentry); } }

 

三、总结

1.内核由很多合适的关口来截获获取的IO信息,不改动内核,也可以用jprobe抢劫很多东西。

2.debugfs在大量的block–>file转换过程总太慢,自己用ext2fs写一个,效率应该能提高很多。

—结束—

 

block_dump观察Linux IO写入的具体文件–OenHan

http://www.oenhan.com/block-dump-linux-io

 

[root@server-mysql log]# echo 5 > /proc/sys/vm/block_dump

[root@server-mysql log]# dmesg -c |grep mysqld
mysqld(11780): dirtied inode 1069049 (ib_logfile0) on sda3
mysqld(11780): dirtied inode 1069049 (ib_logfile0) on sda3
mysqld(11780): WRITE block 8236616 on sda3
mysqld(9674): dirtied inode 1069048 (ibdata1) on sda3
mysqld(9674): dirtied inode 1069048 (ibdata1) on sda3
mysqld(9674): WRITE block 8144896 on sda3
mysqld(9674): WRITE block 8144904 on sda3
mysqld(9674): WRITE block 8144912 on sda3
mysqld(9674): WRITE block 8144920 on sda3
mysqld(9674): WRITE block 8144928 on sda3
mysqld(9674): WRITE block 8144936 on sda3
mysqld(9674): WRITE block 8144944 on sda3
mysqld(9674): WRITE block 8144952 on sda3
mysqld(9674): dirtied inode 1071023 (kk.ibd) on sda3
mysqld(9674): dirtied inode 1071023 (kk.ibd) on sda3
mysqld(9663): WRITE block 32762104 on sda3
mysqld(9663): WRITE block 32762112 on sda3
mysqld(9663): WRITE block 32762120 on sda3
mysqld(9663): WRITE block 32762128 on sda3
mysqld(9663): WRITE block 16177376 on sda3
mysqld(9663): WRITE block 16177384 on sda3
mysqld(9663): WRITE block 16177392 on sda3
mysqld(9663): WRITE block 16177400 on sda3
mysqld(9658): WRITE block 8175616 on sda3



block_dump观察Linux IO写入的具体文件(mysqld)

标签:

人气教程排行