文件空洞产生的原因分析
时间:2011-01-28
来源:互联网
在文件拷贝时候,scp一个占磁盘空间300G大小(du命令的结果)左右的目录到另外一台机器上,du命令发现该目录占用的磁盘空间变大了,约330多G。为什么会多出来这30G呢?
分析可能原因:
一.原机器的block大小为1024k,新机器的block大小为4096k,可能是文件系统block大小引起的。
拷贝的数据文件大概有1000个,文件块的影响也就是1000*4K=4M,而空间增大了约30G,所以不可能是原因一。
二.有些文件存在空洞。空洞scp到新机器后,被填充,占用磁盘空间。
实验:在本机上cp一个有空洞的文件,发现cp前后占用的磁盘大小未变,而scp到另一台机器后,空洞被填满,占用磁盘块变大。
背景知识:
ll和du –s读取的文件大小和占用磁盘空间数据来源
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函数,取得文件状态,st_size就是ll看到的文件大小,st_blksize是系统每次read,write等i/o的buff大小,通常和文件系统块大小一致,st_blocks是占用的
文件系统的块数,这个块区别以文件系统的块,一般是512字节。Du命令读取st_blocks(du会根据命令参数转换)。
实验过程:创建一个空洞文件file.hole。通过lseek将文件偏移量指针超过文件末尾。
实验机器: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一下系统调用的过程
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了有具体内容的块,空洞没有write,但是lseek是一直在变的,所以cp不会拷贝空洞。
通过看cp的源码,可以看到cp的具体过程:
因长度受限:http://hi.baidu.com/ops_bd/blog/item/6fc1e4f2cc08c136bd31099d.html
分析可能原因:
一.原机器的block大小为1024k,新机器的block大小为4096k,可能是文件系统block大小引起的。
拷贝的数据文件大概有1000个,文件块的影响也就是1000*4K=4M,而空间增大了约30G,所以不可能是原因一。
二.有些文件存在空洞。空洞scp到新机器后,被填充,占用磁盘空间。
实验:在本机上cp一个有空洞的文件,发现cp前后占用的磁盘大小未变,而scp到另一台机器后,空洞被填满,占用磁盘块变大。
背景知识:
ll和du –s读取的文件大小和占用磁盘空间数据来源
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函数,取得文件状态,st_size就是ll看到的文件大小,st_blksize是系统每次read,write等i/o的buff大小,通常和文件系统块大小一致,st_blocks是占用的
文件系统的块数,这个块区别以文件系统的块,一般是512字节。Du命令读取st_blocks(du会根据命令参数转换)。
实验过程:创建一个空洞文件file.hole。通过lseek将文件偏移量指针超过文件末尾。
实验机器: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一下系统调用的过程
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了有具体内容的块,空洞没有write,但是lseek是一直在变的,所以cp不会拷贝空洞。
通过看cp的源码,可以看到cp的具体过程:
因长度受限:http://hi.baidu.com/ops_bd/blog/item/6fc1e4f2cc08c136bd31099d.html
作者: amos613 发布时间: 2011-01-28
感谢分享
作者: Godbach: 发布时间: 2011-01-30
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28