Linux systemtap定位系統IO資源使用情況


一、systemtap介紹

  SystemTap是一個強大的調試工具,是監控和跟蹤運行中的Linux 內核的操作的動態方法,確切的說應該是一門調試語言,因為它有自己的語法,也有解析、編譯、運行等過程(准確的說有五個階段),但它主要解決的問題是收集Linux內核或者用戶進程的信息,主要目的是調試。gdb、kgdb同是linux最強大的調試器,gdb和SystemTap不是競爭關系,而是互補關系,gdb能做的事情SystemTap做不到,比如斷點/watch變量等等這些SystemTap都做不到,而SystemTap能做的事情gdb做不到或者非常麻煩才做到,比如很方便查看內核調試棧/嵌入C語言等等gdb就很難。

 

二、systemtap安裝

1.安裝步驟:

  1.1 yum install systemtap

  1.2 yum install kernel-devel  kernel-headers gcc elfutils

     1.3 通過 http://debuginfo.centos.org/6/x86_64/  

        下載kernel-debuginfo 以及kernel-debuginfo-common,要下載對應內核版本的(錯誤版本會提示semantic error: no match等報錯);

         例如測試機器下載:

        

       

        

  執行rpm安裝(先安裝依賴包common):

  rpm -ivh kernel-debuginfo-common-x86_64-2.6.32-279.el6.x86_64.rpm

  rpm -ivh kernel-debuginfo-2.6.32-279.el6.x86_64.rpm

  1.4  執行 stap-prep進行stap環境檢查,如沒有報錯,表示stap可以正常使用。

  1.5 測試腳本執行查看是否成功(檢查正在添加系統中的page_cache信息):

  stap -e 'probe vfs.add_to_page_cache {printf("dev=%x, devname=%s, ino=%d, index=%d, nrpages=%d\n", dev, devname, ino, index, nrpages)}'

 

三、實戰應用及常用工具瓶頸

  1.故障處理中遇到的困境:

  1.1 iostat等命令看到的是系統級的統計,比如下例中我們看到/dev/vdb很忙,如果要追查是哪個進程導致的I/O繁忙,應該怎么辦?

              

  進程的內核數據結構中包含了I/O數量的統計:

  struct task_struct {

        struct task_io_accounting ioac;
    };
 
   可以直接在 /proc/<pid>/io 中看到:
         
  # cat /proc/3088/io
 
   rchar: 125119 //在read(),pread(),readv(),sendfile等系統調用中讀取的字節數
   wchar: 632    //在write(),pwrite(),writev(),sendfile等系統調用中寫入的字節數
   syscr: 111    //調用read(),pread(),readv(),sendfile等系統調用的次數
   syscw: 79     //調用write(),pwrite(),writev(),sendfile等系統調用的次數
   read_bytes: 425984 //進程讀取的物理I/O字節數,包括mmap pagein,在submit_bio()中統計的
   write_bytes: 0     //進程寫出的物理I/O字節數,包括mmap pageout,在submit_bio()中統計的
   cancelled_write_bytes: 0 //如果進程截短了cache中的文件,事實上就減少了原本要發生的寫I/O
 
  我們關心的是實際發生的物理I/O,從上面的注釋可知,應該關注 read_bytes 和 write_bytes。請注意這都是歷史累計值,從進程開始執行之初就一直累加。如果要 觀察動態變化情況,可以使用 pidstat 命令,它就是利用了/proc/<pid>/io 中的原始數據計算單位時間內的增量:
 
  

  另外還有一個常用的命令 iotop 也可以觀察進程的動態I/O:

         

             pidstat 和 iotop 也有不足之處,它們無法具體到某個硬盤設備,如果系統中有很多硬盤設備,都在忙,而我們只想看某一個特定的硬盤的I/O來自哪些進程,這兩個命令就幫不上忙了。怎么辦呢?

       

  2.SystemTap查找方法:

  可以用上萬能SystemTap工具。比如:我們希望找出訪問/dev/vdb的進程,可以用下列腳本,它的原理是對submit_bio下探針:

           [root@template ~]# cat io_vdb.stap
   #! /usr/bin/env stap
 
   global device_of_interest

           probe begin {
      device_of_interest = $1
      printf ("device of interest: %x\n", device_of_interest)
    }
 
   probe kernel.function("submit_bio")
   {
      dev = $bio->bi_bdev->bd_dev
      if (dev == device_of_interest)
          printf ("[%s](%d) dev:0x%x rw:%d size:%d\n",
                  execname(), pid(), dev, $rw, $bio->bi_size)
   }

  這個腳本需要在命令行參數中指定需要監控的硬盤設備號,得到這個設備號(fc,10)的方法如下:

       十六進制: (fc,10)---->(主設備號Major number(12-bit),次設備號Minor number(20-bit))  需要轉換為10進制作為io_vdb.stap的入參數($1)

       十進制:(252,10)

  

  stat /dev/vdb:

       

  cat /proc/devices:

        

 

 

  3.SystemTap 查證結果:

  3.1 查看某個分區或目錄io訪問情況:

  腳本執行命令:./io_vdb 264241171

  (264241171為 fc00013的十進制表示,因為 fc00010為/dev/vdb,我們的測試目錄為/dev/vdb3,所以對應的次設備號變為13(fc,13)

       

            執行grep命令進行驗證io實際執行情況:

         執行前:

       

 

  執行后:

  通過結果,我們看到是進程號為8446的grep命令在對/dev/vdb3進行讀操作(rw:0)。

         

               

   Enjoyjing youeself!

 

參考文章:

  http://linuxperf.com/?cat=4

  http://www.xbwolf.com/507

  http://blog.csdn.net/wangzuxi/article/details/42849053

          

 
 
 
 
 
 
 
 
 
 
          

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM