kevx's Writing

架构 / 云计算 / 技术管理 | kevx@outlook.com 未经授权请勿转载©

Contact Me

XFS底层块设备IOPath分析备注

XFS在中间件和数据库应用上广泛使用,而有的时候我们需要对XFS上的IO进行性能诊断,例如数据库IO读写过于缓慢或者发生不符合预期的写入请求。常规的诊断工具如iostat等仅能看到统计型的指标,无法精准定位具体的文件和数据。

要想得到这类信息,可借助blktrace工具,其工作在块设备层,可提供丰富的诊断信息。

一个IO请求进入块设备层后可能有多个处理流程:

  • Remap,被DM(Device Mapper)或MD(Multiple Device,如RAID)重映射到其它设备
  • Split,因IO请求与扇区边界未对齐或者太大而被分拆成为多次IO
  • Merge,因与其它I/O请求的物理位置相邻而合并成一次IO
  • 被IO调度器发送给底层驱动程序
  • 被驱动程序提交给实际设备,设备完成IO请求之后再发回结果。

一般来说通过下列命令启动分析程序,例如:

sudo blktrace -d /dev/vda -o - | blkparse -i -

该程序会将对于/dev/vda设备的所有IO请求打印在当前控制台,如下所示

253,0  0  153  22.820854964 22822  A  W  1671440 + 8 <- (253,2) 850192
253,2  0  154  22.820858837 22822  Q  W  1671440 + 8 [kworker/u4:1]
253,2  0  155  22.820862417 22822  G  W  1671440 + 8 [kworker/u4:1]
253,2  0  156  22.820869028 22822  I  W  1671440 + 8 [kworker/u4:1]
253,2  0  157  22.820885675   258  D  W  1671440 + 8 [kworker/0:1H]
253,0  0  158  22.820914903 22822  A  W  1671448 + 8 <- (253,2) 850200
253,2  0  159  22.820915456 22822  Q  W  1671448 + 8 [kworker/u4:1]
253,2  0  160  22.820915936 22822  G  W  1671448 + 8 [kworker/u4:1]
253,0  0  163  22.820936760 22822  A  W  23161992 + 8 <- (253,2) 22340744
253,2  0  168  22.828410920     0  C  W  1671440 + 8 [0]

主要关注的第4/5/6和最后一列,分别含义是时间戳(单位为秒,小数点精确到纳秒)、进程ID、IO事件类型、起始BlockID和Block数量。重点说明一下IO事件类型,目前常见的类型有下面几个:

  • A,IO请求被重映射
  • C,IO请求已经完成
  • D,IO请求已经提交到驱动
  • G,IO请求已经生成
  • I,IO请求进入调度队列
  • Q,IO请求即将生成

各事件间隔时间的意义:

  • I->D,IO请求在调度队列中消耗的时间(跟IO调度策略有关)
  • D->C,IO在硬件上消耗的时间
  • A/Q->G,生成IO请求的时间,含Remap/Split
  • G->I,IO请求进入到调度队列的时间,含Merge
  • A/Q->C,即整个IO请求时间,与iostat的await指标接近

然后看一下最后一列,例如1671440 + 8 <- (253,2) 850192,这个含义表示当前请求是从1671440(850192)起始的block,当次IO一共操作8个block,这个例子因为有RAID所以还涉及到重映射(由850192映射到1671440)。这里的block定义究竟是什么,网络上并没有明显的信息。

但其实很简单,就是块设备的扇区ID,扇区大小固定为512字节,设备第一个扇区ID为0,第二个扇区ID为1,依此类推。可直接使用dd命令从设备中dump具体的扇区数据,例如sudo dd if=/dev/vda of=/tmp/test.txt skip=850192 bs=512 count=8,将从850192号开始的8个扇区数据导出至文件中。

至此块设备层的问题基本上搞定,接下来就是另外一个难题:如何与具体文件系统如XFS上的文件本身关联起来?

仍然以上面的Block:850192为例,对所有可能的文件执行xfs_bmap命令,例如:

sudo xfs_bmap ./xxx.bin,其会输出下列结果:

./xxx.bin:
    0: [0..127]: 850160..850287
    1: [128..383]: 852264..852519
    2: [384..5079]: 824008..828703
    3: [5080..7719]: 774176..776815

很显然,Block:850192恰好位于该文件所关联的扇区段内。

返回主页