我想知道输出中的“IO Block”的含义stat
以及该数字是如何计算的。
我知道文件夹/文件的物理大小以 4096 字节块为单位。
然而在下面这个例子中,文件的大小超过了 4096 字节,“IO Block”的值并没有改变。
IO 块的含义是什么以及如何改变它?
stat yeni
File: 'yeni'
Size: 12890 Blocks: 32 IO Block: 4096 normal dosya
Device: 805h/2053d Inode: 2255976 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ ihsan) Gid: ( 1000/ ihsan)
Access: 2017-08-15 20:07:26.324017949 +0300
Modify: 2017-08-15 20:06:30.703053636 +0300
Change: 2017-08-15 20:07:26.324017949 +0300
Birth: -
答案1
简短说明
- 输出中的“IO Block”
stat
是文件系统用于读取和写入文件的首选字节数。IO Block 通常4096 字节。 - 另一方面,“块”计算的是512 字节在磁盘上为文件分配块。
更详细的解释
“IO 块”与“块”
输入输出块
“IO Block”是文件系统读写文件时首选的字节数。
在我的 ext4 分区上,这个数字固定为 4096 字节。
对于 512 MB 到 4 TB 之间的文件系统,块大小默认为 4096 字节。请参阅man mke2fs.conf
,你的,以及选项/etc/mke2fs.conf
的文档-T
man mkfs.ext4
。
区块
另一方面,“Blocks”给出了512字节为磁盘上的文件分配的块。请注意,stat
“块”的块大小与“IO 块”的块大小不同:
- “IO 块”块中的字节数:由文件系统定义。在您和我的情况下是 4096 字节。
- “块”块中的字节数:始终为 512 字节。
我们怎么知道“IO Block”和“Blocks”真正指的是什么呢?
挖掘stat
的源代码我们发现此行创建了默认输出stat
:
Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n\
拆开来看:
Size: %-10s
:“Size:”以字节为单位打印文件的大小,并使用一些填充-10
。
Blocks: %-10b
:“Blocks”打印占位符的值%b
(带有一些填充)。是什么%b
?根据man 1 stat
:
%b 分配的块数(参见 %B)
看一下%B
:
%B %b 报告的每个块的大小(以字节为单位)
“Blocks” 表示一个块中有多少个字节?
stat --format="%B" ~/small_file
这会打印“512”。好的,“Blocks”的块大小为 512 字节。
接下来是打印“IO Block”的代码:
IO Block: %-6o
:占位符是什么%o
?直接来自man 1 stat
:
%o 最佳 I/O 传输大小提示
有趣!“IO Block”是“最佳 I/O 传输大小提示”的缩写。
在 ext4 文件系统上运行此命令:
stat --format="%o" ~/small_file
我们了解到“IO 块”是 4096 字节。大小差别很大:
- “IO 块”:4096 字节
- “块”:512字节
综合起来:
stat --format="File is %s bytes but needs %B*%b bytes on disk. Optimal I/O transfer size hint (alias IO Block): %o bytes" ~/small_file
在我的例子中,它将打印以下内容:
文件为 116 字节,但需要磁盘上 512*8 字节。最佳 I/O 传输大小提示(别名 IO 块):4096 字节
很容易制作这错误认为 Blocks 值计算的是磁盘上分配的 IO Blocks 的数量。
stat
系统调用
从man 2 stat
我们可以详细了解 IO 传输大小提示,也称为“IO Block”:
st_blksize 字段提供高效文件系统 I/O 的“首选”块大小。(以较小的块写入文件可能会导致读取-修改-重写效率低下。)
还引用自man 2 stat
st_blocks
描述有助于理解stat
“块”的字段:
该字段表示分配给文件的块数,以 512 字节为单位。
更多示例stat
以下是简化的示例输出stat ~/small_file
:
File: /home/mb/small_file
Size: 116 Blocks: 8 IO Block: 4096 regular file
// Rest omitted
Size: 116
表示该文件中有 116 个字节的数据。但它并没有告诉我们在磁盘上存储该文件使用了多少个字节。这就是“块”的作用所在。Blocks: 8
意味着该文件在磁盘上占用了 8 * 512 = 4096 字节。考虑到该文件只有 116 字节的数据,这有点浪费。但是我们不能使用更少的字节,因为我的系统上的 ext4 块大小是 4096 字节。有多浪费?让我们计算一下:这116 / 4096 * 100 ≈ 2.8
意味着只有大约 2.8% 的分配字节实际上用于存储文件的数据。IO Block: 4096
表示一次从磁盘读取或写入的首选字节数。
另一个示例文件稍大一些,stat ~/larger_file
:
File: /home/mb/larger_file
Size: 91246 Blocks: 184 IO Block: 4096 regular file
// Rest omitted
Size: 91246
告诉我们该文件中的字节数,与我们的文件系统和它在磁盘上物理占用的字节数无关。Blocks: 184
让我们计算一下这个文件在磁盘上实际占用的字节数:184 * 512 = 94208 字节。这些分配的字节中有多少用于实际存储larger_file
的数据?91246 / 94208 * 100 ≈ 96.9
。大约 96.6% 是文件的数据,与我们之前的示例相比,这要高效得多~/small_file
。
改变“IO Block”的值
我怀疑你能改变“IO Block”的值现存的文件系统。以下是对此进行讨论。
如果你正在创建一个新的文件系统,有-b
选项以字节为单位指定块大小。
mkfs.ext4 -b 2048 /dev/sdb1
来自手动的:
有效的块大小值为每块 1024、2048 和 4096 字节。
答案2
Linux 文件系统分为 4 个主要部分。
- 引导块
- 超级块
- 列表
- 数据块
在超级块中,有一个参数叫做块大小,这意味着 Linux 将磁盘分成 4096 个块。您可能知道块设备中的磁盘(请ll /dev/sda
查看b在左边),您从磁盘读取块而不仅仅是字符。因此,I/O 块意味着文件系统在读取磁盘的一部分时每 4096 个块读取一次。它与文件大小无关。为了改变 BS,您应该训练文件系统读取更小或更大的块(不推荐)。