DM 统计¶
设备映射器支持在 DM 设备的 用户定义区域上收集 I/O 统计信息。 如果没有定义区域,则不会收集任何统计信息,因此不会产生任何性能影响。 目前仅支持基于 bio 的 DM 设备。
每个用户定义的区域指定起始扇区、长度和步长。 将为指定范围内的每个步长区域收集单独的统计信息。
区域的每个步长区域的 I/O 统计计数器的格式与 /sys/block/*/stat 或 /proc/diskstats 相同(请参阅:I/O 统计字段)。 但是提供了两个额外的计数器(12 和 13):读取和写入的总时间。 当使用直方图参数时,将报告第 14 个参数,它表示延迟的直方图。 可以通过 dmsetup 向相应的 DM 设备发送 @stats_print 消息来访问所有这些计数器。
报告的时间以毫秒为单位,粒度取决于内核节拍。 当使用选项 precise_timestamps 时,报告的时间以纳秒为单位。
每个区域都有一个唯一的标识符,我们称之为 region_id,它在创建区域时分配。 在查询有关区域的统计信息、删除区域等时,必须提供 region_id。 唯一的 region_id 使多个用户空间程序可以请求和处理同一 DM 设备的统计信息,而不会相互干扰。
DM 统计的创建将通过 kmalloc 分配内存,或回退到使用 vmalloc 空间。 DM 统计最多可分配 1/4 的整体系统内存。 管理员可以通过读取查看使用了多少内存
/sys/module/dm_mod/parameters/stats_current_allocated_bytes
消息¶
- @stats_create <范围> <步长> [<可选参数数量> <可选参数>...] [<程序 ID> [<辅助数据>]]
创建一个新区域并返回 region_id。
- <范围>
- “-”
整个设备
- “<起始扇区>+<长度>”
以 <起始扇区> 开头的 <长度> 512 字节扇区的范围。
- <步长>
- “<区域大小>”
该范围细分为包含 <区域大小> 个扇区的区域。
- “/<区域数量>”
该范围细分为指定数量的区域。
- <可选参数数量>
可选参数的数量
- <可选参数>
支持以下可选参数
- precise_timestamps
使用具有纳秒分辨率的精确计时器,而不是“jiffies”变量。 当使用此参数时,结果时间以纳秒为单位,而不是毫秒。 精确时间戳的获取速度比基于 jiffies 的时间戳慢一些。
- histogram:n1,n2,n3,n4,...
收集延迟直方图。 数字 n1、n2 等是表示直方图边界的时间。 如果未使用 precise_timestamps,则时间以毫秒为单位,否则以纳秒为单位。 对于每个范围,内核将报告在此范围内完成的请求数。 例如,如果我们使用“histogram:10,20,30”,内核将报告四个数字 a:b:c:d。 a 是花费 0-10 毫秒完成的请求数,b 是花费 10-20 毫秒完成的请求数,c 是花费 20-30 毫秒完成的请求数,d 是花费超过 30 毫秒完成的请求数。
- <程序 ID>
一个可选参数。 一个唯一标识该范围的用户空间所有者的名称。 这将范围组合在一起,以便用户空间程序可以识别他们创建的范围,而忽略其他人创建的范围。 内核在 @stats_list 消息的输出中返回此字符串,但它不将其用于其他任何用途。 如果我们省略可选参数的数量,则程序 ID 不能是数字,否则它将被解释为可选参数的数量。
- <辅助数据>
一个可选参数。 一个为创建该范围的客户端程序提供有用辅助数据的词。 内核在 @stats_list 消息的输出中返回此字符串,但它不将此值用于任何用途。
- @stats_delete <region_id>
删除具有指定 ID 的区域。
- <region_id>
从 @stats_create 返回的 region_id
- @stats_clear <region_id>
清除除正在进行的 i/o 计数器之外的所有计数器。
- <region_id>
从 @stats_create 返回的 region_id
- @stats_list [<程序 ID>]
列出所有通过 @stats_create 注册的区域。
- <程序 ID>
一个可选参数。 如果指定此参数,则仅返回匹配的区域。 如果未指定,则返回所有区域。
- 输出格式
- <region_id>: <起始扇区>+<长度> <步长> <程序 ID> <辅助数据>
precise_timestamps histogram:n1,n2,n3,...
仅当在创建区域时指定了“precise_timestamps”和“histogram”字符串时才会打印它们。
- @stats_print <region_id> [<起始行> <行数>]
打印区域的每个步长区域的计数器。
- <region_id>
从 @stats_create 返回的 region_id
- <起始行>
输出中起始行的索引。 如果省略,则返回所有行。
- <行数>
要包含在输出中的行数。 如果省略,则返回所有行。
区域的每个步长区域的输出格式
- <起始扇区>+<长度>
计数器
前 11 个计数器的含义与 /sys/block/*/stat 或 /proc/diskstats 相同。
请参阅 I/O 统计字段 获取详细信息。
已完成的读取次数
合并的读取次数
读取的扇区数
读取花费的毫秒数
已完成的写入次数
合并的写入次数
写入的扇区数
写入花费的毫秒数
当前正在进行的 I/O 数
进行 I/O 花费的毫秒数
执行 I/O 操作所花费的加权毫秒数
其他计数器
读取操作总共花费的时间,单位为毫秒
写入操作总共花费的时间,单位为毫秒
- @stats_print_clear <region_id> [<starting_line> <number_of_lines>]
原子性地打印并清除所有计数器,除了正在进行中的 I/O 计数器。当使用统计信息的客户端不希望丢失任何统计信息(那些在打印和清除之间更新的统计信息)时非常有用。
- <region_id>
从 @stats_create 返回的 region_id
- <起始行>
输出中起始行的索引。如果省略,则打印并清除所有行。
- <行数>
要处理的行数。如果省略,则打印并清除所有行。
- @stats_set_aux <region_id> <aux_data>
为指定区域存储辅助数据 aux_data。
- <region_id>
从 @stats_create 返回的 region_id
- <辅助数据>
用于标识对创建范围的客户端程序有用的数据的字符串。内核在 @stats_list 消息的输出中返回此字符串,但它不会将此值用于任何目的。
示例¶
将 DM 设备 'vol' 细分为 100 个部分,并开始收集它们的统计信息
dmsetup message vol 0 @stats_create - /100
将辅助数据字符串设置为“foo bar baz”(每个空格的转义字符也必须被转义,否则 shell 将会消耗它们)
dmsetup message vol 0 @stats_set_aux 0 foo\\ bar\\ baz
列出统计信息
dmsetup message vol 0 @stats_list
打印统计信息
dmsetup message vol 0 @stats_print 0
删除统计信息
dmsetup message vol 0 @stats_delete 0