• systemtap安装


    一、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 ", 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 ", 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 ",
                      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!

     
      参照文章:https://www.cnblogs.com/Jeb15/p/7120568.html
     
     
     
     
  • 相关阅读:
    log4net GetLogger(source).IsInfoEnabled = false
    nginx配置
    mysql数据库备份
    按序号批量更新某个字段
    MySql 执行 DELETE/UPDATE时,报 Error Code: 1175错误
    ef学习记录
    vue-cli3实行路径联想
    GitHub分支创建及合并
    Git本地分支和远程分支关联
    uniapp(三)
  • 原文地址:https://www.cnblogs.com/Nanaya/p/8488073.html
Copyright © 2020-2023  润新知