- 論壇徽章:
- 0
|
在文件拷貝時(shí)候,scp一個占磁盤空間300G大。╠u命令的結(jié)果)左右的目錄到另外一臺機(jī)器上,du命令發(fā)現(xiàn)該目錄占用的磁盤空間變大了,約330多G。為什么會多出來這30G呢?
分析可能原因:
一.原機(jī)器的block大小為1024k,新機(jī)器的block大小為4096k,可能是文件系統(tǒng)block大小引起的。
拷貝的數(shù)據(jù)文件大概有1000個,文件塊的影響也就是1000*4K=4M,而空間增大了約30G,所以不可能是原因一。
二.有些文件存在空洞。空洞scp到新機(jī)器后,被填充,占用磁盤空間。
實(shí)驗(yàn):在本機(jī)上cp一個有空洞的文件,發(fā)現(xiàn)cp前后占用的磁盤大小未變,而scp到另一臺機(jī)器后,空洞被填滿,占用磁盤塊變大。
背景知識:
ll和du –s讀取的文件大小和占用磁盤空間數(shù)據(jù)來源
struct stat {
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device type (if inode device) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
自己編寫一個小C程序通過fstat函數(shù),取得文件狀態(tài),st_size就是ll看到的文件大小,st_blksize是系統(tǒng)每次read,write等i/o的buff大小,通常和文件系統(tǒng)塊大小一致,st_blocks是占用的
文件系統(tǒng)的塊數(shù),這個塊區(qū)別以文件系統(tǒng)的塊,一般是512字節(jié)。Du命令讀取st_blocks(du會根據(jù)命令參數(shù)轉(zhuǎn)換)。
實(shí)驗(yàn)過程:創(chuàng)建一個空洞文件file.hole。通過lseek將文件偏移量指針超過文件末尾。
實(shí)驗(yàn)機(jī)器:block大小為4k.
ll file.hole
-rw-r--r-- 1 zhangfan zhangfan 16394 Jun 22 15:08 file.hole
du -sh file.hole
8.0K file.hole
可以看到,空洞部分沒有占用block.
cp一個空洞文件
cp file.hole file.hole.cp
ll file.hole.cp
-rw-r--r-- 1 zhangfan zhangfan 16394 Jul 10 15:51 file.hole.cp
du -sh file.hole.cp
8.0K file.hole.cp
trace一下系統(tǒng)調(diào)用的過程
read(3, "abcdefghij\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
write(4, "abcdefghij\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
lseek(4, 4096, SEEK_CUR) = 8192
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
lseek(4, 4096, SEEK_CUR) = 12288
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
lseek(4, 4096, SEEK_CUR) = 16384
read(3, "ABCDEFGHIJ", 4096) = 10
write(4, "ABCDEFGHIJ", 10) = 10
read(3, "", 4096) = 0
close(4) = 0
close(3) = 0
只write了有具體內(nèi)容的塊,空洞沒有write,但是lseek是一直在變的,所以cp不會拷貝空洞。
通過看cp的源碼,可以看到cp的具體過程:
因長度受限:http://hi.baidu.com/ops_bd/blog/item/6fc1e4f2cc08c136bd31099d.html |
評分
-
查看全部評分
|