文件大小不匹配

文件大小不匹配

报告的文件大小差异背后的原因是什么?

[root@localhost]# ls -lah sendlog
-rw-rw-r-- 1 mail mail 1.3T Aug 15 17:30 sendlog

[root@localhost]# du -m sendlog
24M  sendlog

当服务器的备份由于配额问题不断失败时,我们注意到了这一点,因此不仅仅是“ls”看到了这个错误的大小。

我想到的是“稀疏文件”和“块分配”等术语,但我不确定为什么会发生这种情况,也不知道背后的真正原因。显然,这两个命令检查大小的方式有所不同,我总是相信 du,对吗?

仅供参考,这应该是一个非常标准的邮件日志文件。

答案1

值之间的差异如下。

来自手册统计(2)

struct stat {
    // snip
    off_t     st_size;    /* total size, in bytes */
    // snip
    blkcnt_t  st_blocks;  /* number of blocks allocated */
    // snip
};

st_blocks 字段表示分配给文件的块数,以 512 字节为单位。(例如,当文件有空洞时,该值可能小于 st_size/512。)

ls 报告的大小为st_size,du 报告的大小为st_blocks * 512

du 报告的值是文件在文件系统/磁盘上使用的字节数,而 ls 报告的值是与文件交互时文件的实际大小/长度。(除了使用磁盘使用情况进行操作外,du 还仅对硬链接文件进行一次计数)

哪个值是“正确的值”取决于上下文。如果您想知道磁盘使用情况,du 是正确的;如果您想知道文件中有多少字节,ls/st_size是正确的。

此外,您可以使用各种选项,例如 du (--apparent-size) 来使用报告的大小,st_size或者您可以获取 ls (-s) 来报告使用的块数。

您对日志文件是稀疏文件的假设听起来似乎合理,但是我不知道原因。

答案2

正如 Kjetil 所解释的那样,您有一个稀疏文件。文件内的空白数据块不会分配给磁盘,直到您实际写入这些块为止。日志文件中如何发生这种情况是一个谜。您必须检查您的审计日志,从上次 sendlog 的大小正确到出现这个巨大漏洞的时间。也许答案就在日志文件本身中。

也许有人故意这样做,以破坏您的系统。或者是某些软件错误。

您可以使用以下方式轻松创建自己的 TB 大小的文件:

dd if=/dev/zero of='OMG_Thats_a_1_terabyte_file!!.dat' seek=1T bs=1 count=1

在任何当前 Linux 版本中,只要文件系统支持稀疏文件,该文件将仅分配几千字节的磁盘空间。

您的备份解决方案需要更换。如今,任何严肃的备份系统都能有效处理稀疏文件。即使是使用 GNU tar 的最简单的解决方案也支持它(-S 或 --sparse 选项)。

答案3

也许你的du不支持这么大的数字?

答案4

您的文件系统可能已损坏(或磁盘存在一些物理问题)。您应该尽快执行 fsck(在未挂载的分区上),然后查看这些数字会发生什么变化。

相关内容