DM 统计信息¶
设备映射器支持收集 DM 设备用户定义区域上的 I/O 统计信息。如果未定义区域,则不收集任何统计信息,因此不会有任何性能影响。目前仅支持基于 bio 的 DM 设备。
每个用户定义的区域都指定了起始扇区、长度和步长。将针对指定范围内的每个步长区域收集单独的统计信息。
区域中每个步长区域的 I/O 统计计数器格式与 /sys/block/*/stat 或 /proc/diskstats 相同 (参见:I/O 统计字段)。但提供了两个额外的计数器(12 和 13):读写总耗时。当使用 histogram 参数时,会报告代表延迟直方图的第 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 <range> <step> [<number_of_optional_arguments> <optional_arguments>...] [<program_id> [<aux_data>]]
创建一个新区域并返回 region_id。
- <range>
- “-”
整个设备
- “<start_sector>+<length>”
以 <start_sector> 开始,长度为 <length> 个 512 字节扇区的范围。
- <step>
- “<area_size>”
该范围被细分为多个区域,每个区域包含 <area_size> 个扇区。
- “/<number_of_areas>”
该范围被细分为指定数量的区域。
- <number_of_optional_arguments>
可选参数的数量
- <optional_arguments>
支持以下可选参数
- 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 毫秒的请求数量。
- <program_id>
一个可选参数。一个唯一标识该范围的用户空间所有者的名称。这会将范围进行分组,以便用户空间程序可以识别它们创建的范围,并忽略其他程序创建的范围。内核会在 @stats_list 消息的输出中返回此字符串,但不会将其用于其他任何目的。如果省略可选参数的数量,则 program id 必须不是数字,否则它将被解释为可选参数的数量。
- <aux_data>
一个可选参数。一个提供对创建该范围的客户端程序有用的辅助数据的单词。内核会在 @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 [<program_id>]
列出所有已通过 @stats_create 注册的区域。
- <program_id>
一个可选参数。如果指定此参数,则只返回匹配的区域。如果未指定,则返回所有区域。
- 输出格式
- <region_id>: <start_sector>+<length> <step> <program_id> <aux_data>
precise_timestamps histogram:n1,n2,n3,...
字符串“precise_timestamps”和“histogram”仅在创建区域时指定了它们的情况下才会打印。
- @stats_print <region_id> [<starting_line> <number_of_lines>]
打印区域中每个步长区域的计数器。
- <region_id>
从 @stats_create 返回的 region_id
- <starting_line>
输出中起始行的索引。如果省略,则返回所有行。
- <number_of_lines>
输出中包含的行数。如果省略,则返回所有行。
区域中每个步长区域的输出格式
- <start_sector>+<length>
计数器
前 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
- <starting_line>
输出中起始行的索引。如果省略,则打印并清除所有行。
- <number_of_lines>
要处理的行数。如果省略,则打印并清除所有行。
- @stats_set_aux <region_id> <aux_data>
为指定区域存储辅助数据 aux_data。
- <region_id>
从 @stats_create 返回的 region_id
- <aux_data>
此字符串标识对创建该范围的客户端程序有用的数据。内核会在 @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