这让我很疑惑。我认为这应该很容易,但我一定错过了一些东西,因为结果并不一致。
我使用 rsync 将一长串文件备份到多个磁盘,使用按时间顺序排序的列表,以便最早的文件位于第一个磁盘上,较晚的文件位于第二个磁盘上,依此类推。
我浏览列表,将文件大小(以 4k 块为单位)相加,并记下最后一个适合的文件的日期。然后我使用“find -not -newer 和 -newer”创建一个列表
STARTDATE="-newer /tmp/filedate.1"
ENDDATE="-not -newer /tmp/filedate.2"
find $SRC -type f ${STARTDATE} ${ENDDATE} -printf '%P\n' | sort > ${TEMPFILE}
并使用“--files-from”将其提供给 rsync 以实际进行复制。
rsync -a --progress --verbose --prune-empty-dirs --files-from=${TEMPFILE} ${SRC} ${TARGET}
我想准确地找出文件的分割位置,以便磁盘已满。
我现在拥有的:
#%T is the modification time, @ is seconds,
#%p is the path less the command line part, and %k is disk usage in 1k blocks
#MAXSIZE is number of 4k blocks available on disk
find $SRC -printf "%T@\t%p\t%k\n" | sort -n | \
awk -vMS="$MAXSIZE" '
BEGIN { FS = "\t";fnumber = 0 }
{rtot+=int(($3+3)/4); #edit; changed to ceiling on AlexP's advice
if (rtot<MS) {final=$2;filesize=rtot;}
else {
rtot=int(($3+3)/4); #edit; changed to ceiling on AlexP's advice
fnumber++;
printf "touch -r \"%s\" /tmp/filedate.%s\n", final, fnumber | "/bin/sh"
print "Found point " fnumber ". (" final ") 4096 Blocks:" filesize " Space Left:" (MS-filesize)*4
}
}
'
磁盘详细信息是:
#tune2fs -l /dev/sdzc1
tune2fs 1.41.4 (27-Jan-2009)
Filesystem volume name: <none>
Last mounted on: /share/external/sdzc1
Filesystem UUID: f3f2e855-b198-4d47-b76f-6526d16b0820
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode filetype needs_recovery extent flex_bg sparse_super large_file
huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options: (none)
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 122101760
Block count: 488378007
Reserved block count: 0
Free blocks: 89451
Free inodes: 122088914
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 907
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512
Flex block group size: 16
Filesystem created: Sun May 11 13:45:08 2014
Last mount time: Wed Dec 7 11:44:24 2016
Last write time: Wed Dec 7 11:44:24 2016
Mount count: 68
Maximum mount count: 28
Last checked: Fri Feb 20 02:06:42 2015
Check interval: 15552000 (6 months)
Next check after: Wed Aug 19 02:06:42 2015
Reserved blocks uid: 0 (user admin)
Reserved blocks gid: 0 (group administrators)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Journal inode: 8
First orphan inode: 75890825
Default directory hash: half_md4
Directory Hash Seed: 1c7f838c-8614-4af0-8506-cd3659e1e5ac
Directory Magic Number: 0x514E4150
Journal backup: inode blocks
所以,根据我的想法,有 488378007 个 4096 字节的块,以及 122101760 个 256 字节的 inode。因此,应该有 (488378007 x 4096) - (122101760 x 256) 字节可供写入。即 1,969,138,264,064,即 1,922,986,586 kB。
df 显示总共 1,922,858,380 个 1k 块(128,206 差异)= 480,714,595 4k 块。
不考虑这一点,最终结果是,当我实际复制文件时,即使使用下图作为起点,awk 输出报告的“剩余空间”也不等于实际剩余空间,通过数量不同,有时甚至完全耗尽空间。
我哪里逻辑出了问题?我知道我可以通过减少 MAXSIZE 来捏造它,但我真的很想了解我错过了什么!
附注我以 root 身份运行它,因此保留空间不相关。
只是为了澄清实际问题:我是否应该能够对文件和目录大小(整个 4k 块)进行求和以获得总磁盘使用量?
附加编辑:只是为了进一步混淆我刚刚填满了(?)一个驱动器并从 df -k 中得到了这个:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sdzb1 2927209048 2925317912 0 100% /share/external/sdzb1
2927209048-2925317912=1891136,还是我上学的时候用过的!
答案1
两个观察结果:
您需要向上舍入文件使用的块数,而不是向下舍入;如果文件的长度为 8192+1 字节,则最后一个字节将分配一个 4 KiB 块。 (因为“片段大小”是 4 KiB。)
文件所需的磁盘空间不一定等于保存文件中字节数所需的数据块数。它可以稍大一点(对于需要更多元数据来映射其分配的块的较大文件),也可以稍小一点(对于非常小的文件,可以完全存储在其 inode 中)。另外,正如用户 Stephen Kitt 提到的,整个问题是稀疏文件,其大小可能比它们在磁盘上占用的空间大得多,并且在存档或复制到不同的文件系统时可能会导致有趣的问题。
某些文件系统可能会出于自己的目的使用一些磁盘空间。此外,当使用的磁盘空间接近容量时,文件系统往往会出现故障。您确实应该计划将磁盘填充率不要超过 98% 或 99%。
答案2
我将回答我自己的问题,感谢所有贡献并指导我思想的人:
由于写入磁盘时分配空间的方式取决于文件大小和类型、稀疏文件等,因此实际上很难(如果不是不可能的话)提前准确预测将占用多少空间。
已删除文件的目录可能比首次创建时更大,并且此空间将无法恢复。 (除非该目录被删除并重新创建)空目录占用空间。
除非特别要求,否则“查找”不会报告目录。
空间以完整块写入,块大小可能因磁盘而异,并且可以从 e2fsdump 读取。
'df' 在大约 98% 后报告没有可用空间,即使它报告的已用块少于可用空间:
# df -B4k --sync
Filesystem 4K-blocks Used Available Use% Mounted on
/dev/sdzb1 731802262 731493169 0 100% /share/external/sdzb1
/dev/sdzc1 731802262 717225328 0 100% /share/external/sdzc1
'du' 报告与 'df' 不同的用法:
# du -B4k -s /share/external/sdzb1 /share/external/sdzc1
731441722 /share/external/sdzb1
717173881 /share/external/sdzc1
尽管如此,使用可用空间的初始起点是可能的:
Space = (Total blocks x blocksize) - (Total inodes x inode size)
并允许 300,000 到 500,000 块余量,以获得相当准确的结果。 (约1%以内)