报告的文件大小差异背后的原因是什么?
[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(在未挂载的分区上),然后查看这些数字会发生什么变化。