为什么ls看到的文件大小和du看到的文件大小不同

记一次数据迁移排错记录

因公司NAS空间不足的原因,需要将LINUX服务器上的数据,从A盘迁移到B盘。因为一些历史遗留问题,主要是安全问题,想要将原本的CIFS协议挂载,变更成更安全的NFS协议。

具体步骤以及遇到问题如下:

0、mount: 文件系统类型错误、选项错误、nas-server:/sharepath 上有坏超级块、
       缺少代码页或助手程序,或其他错误

操作系统:cat /etc/redhat-release

CentOS Linux release 7.9.2009 (Core)

挂载参数:#cat /etc/fstab
//nas-server:/sharepath /data/nas cifs  domain=companyname,username=user,
password=password,uid=1809,gid=1809,vers=2.1 0 0

nas-server:/sharepath /data/nas2 nfs defaults,rw,vers=4.0,async,bg,soft,intr,
_netdev,retrans=5,timeo=300,nosharecache 0 0

配置好nfs挂载参数后,执行挂载命令#mount -a,返回报错如下

root@pts/1 # mount -a
mount: 文件系统类型错误、选项错误、nas-server:/sharepath 上有坏超级块、
       缺少代码页或助手程序,或其他错误

       (对某些文件系统(如 nfs、cifs) 您可能需要
       一款 /sbin/mount.<类型> 助手程序)

       有些情况下在 syslog 中可以找到一些有用信息- 请尝试
       dmesg | tail  这样的命令看看。

仔细查看原因,因nfs客户端包未安装导致。

安装客户端:yum install -y nfs-utils
配置nfs自启动:service rpcbind start; chkconfig rpcbind on

df -h 检查挂载情况

1、ls下看文件大小相同,但是du下文件夹大小不一致

NFS挂在/data/nas2

CIFS挂在/data/nas

#df -h
//nas-server:/sharepath 1014G  301G  713G  /data/nas      -->cifs
nas-server:/sharepath   1.0T   0G    0G    /data/nas2     -->nfs

从nas1拷贝文件到nas2,经检查拷贝完成后,每个文件大小相同,但文件夹总大小不一致。如下图du -sh 9 所示,大小分别为2.5M 和 772K

因为为刚刚拷贝过来的文件,检查无隐藏文件影响文件夹大小

 经检查 losf | grep deleted ,没有待删除的文件。待删除的文件会占用磁盘空间,未能及时释放空间。

 使用stat -f查看两目录下文件,发现可以清楚的看到两个文件系统存储块大小是不一样的。

nas1块大小为4096

nas2块大小为1048576

因为块大小不同,总使用空间也不一样。

du查看的是总占用的磁盘空间,ls显示文件的大小size

 

 ------------------------------

相关资料:linux du与ls查看文件大小时的区别 - 绿色star - 博客园du和ls查看文件大小的区别 du和ls查看文件大小的区别 du == disk usage (磁盘使用量,占用的磁盘空间)du 的基本使用du -s #s参数是可以统计占硬盘空间大小的如 du -shttps://www.cnblogs.com/newjiang/p/7860718.html

du和ls查看文件大小的区别

du == disk usage (磁盘使用量,占用的磁盘空间)
du 的基本使用
du -s     #s参数是可以统计占硬盘空间大小的
如 du -skh web
-k或--kilobytes 以1024 bytes为单位。
-h或--human-readable 以K,M,G为单位,提高信息的可读性
-s或--summarize 统计目录或文件

一个文件占用的磁盘空间和一个文件的大小是两码事情。占用空间取决于文件系统的块(block)的大小,linux一般默认是4k(4096) ,因此,一个大小为1个字节的文件,最小也要占用4k,如果你创建文件系统的时候制定块大小是16K,那么即便一个文件只有1个字节,占用空间也是16K。

如果一个分区上主要放大文件,那么block可以大一些,有利于减少磁盘碎片,如果主要放小文件,那么block设置小一下,否则太浪费磁盘空间。

通常情况下,ls 显示的文件大小比du显示的磁盘占用空间小
原因:
    比如文件系统的block是4K,一个13K的文件占用的空间是 13k/4k = 3.25 个block,一个block只能被一个文件占用,因此实际占用空间就是4个block,就是16K。

如果一个文件有比较大的黑洞,那么会出现文件大小比磁盘空间占用大的情况
原因:
    首先要理解什么是黑洞,怎么才能产生黑洞?(以下来自《UNIX 环境高级编程》)
    在向一个文件中写数据的时候,文件偏移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将加长该文件,并在文件中构成一个空洞,这一定是允许的。位于文件中但没有写过的字节都被读为0.
    文件中的空洞并不要求在磁盘上占用存储区。具体处理方式与文件系统的实现有关,当定位超出文件尾端之后写时,对于新写的数据需要分配磁盘块,但是对于原文件尾端和新开始写位置之间的部分则不需要分配磁盘块

  例如:用dd if=/dev/zero of=a.out seek=1023 bs=1M count=1创建a.out文件后,用ls查看a.out的文件大小为1G,用du查看a.out文件大小为1M。


生成黑洞文件的示例代码temp.c:
#include
#include
#include
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";

void err_sys(char *msg){
    printf("%s", msg);
    exit(0);
}

int main(void){
    int fd;
    if((fd = creat("file.hole", FILE_MODE)) < 0)
        err_sys("creat error");
    if(write(fd, buf1, 10) != 10)      
        err_sys("buf1 write error");
    if(lseek(fd, 16384, SEEK_SET) == -1)   
        err_sys("lseek error");
    if(write(fd, buf2, 10) != 10)  
        err_sys("buf2 write error");
    exit(0);
}

$gcc temp.c
$./a.out
$od -c file.hole
0000000   a   b   c   d   e   f   g   h   i   j  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0040000   A   B   C   D   E   F   G   H   I   J
0040012
$du -sh file.hole
8.0K    file.hole
$ls -al
drwxr-xr-x 2 root root  4096 Apr 15 20:20 .
drwxr-xr-x 8 root root  4096 Mar 20 13:22 ..
-rwxr-xr-x 1 root root  5598 Apr 15 20:20 a.out
-rw-r--r-- 1 root root 16394 Apr 15 20:20 file.hole
-rw-r--r-- 1 root root   718 Apr 15 20:20 temp.c

--------------------------

 参考资料2

关于扇区、簇、块、页等概念的区分_ly510587的博客-CSDN博客_簇和扇区有什么区别1、什么是扇区和(磁盘)块?物理层面:一个磁盘按层次分为 :磁盘组合 -> 单个磁盘 -> 某一盘面 (platter)-> 某一磁道 (track)-> 某一扇区(sector)。磁头(head):读写头,柱面(cylinder):柱面是我们抽象出来的一个逻辑概念,简单来说就是处于同一个垂直区域的磁道称为柱面 ,即各盘面上面相同位置磁道的集合。磁盘读写数据是按柱面...https://blog.csdn.net/ly510587/article/details/100370841?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1.pc_relevant_antiscanv2&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1.pc_relevant_antiscanv2&utm_relevant_index=1

关于扇区、簇、块、页等概念的区分
1、什么是扇区和(磁盘)块?

物理层面:一个磁盘按层次分为 :
磁盘组合 -> 单个磁盘 -> 某一盘面 (platter)-> 某一磁道 (track)-> 某一扇区(sector)。
磁头(head):读写头,
柱面(cylinder):柱面是我们抽象出来的一个逻辑概念,简单来说就是处于同一个垂直区域的磁道称为柱面 ,即各盘面上面相同位置磁道的集合。磁盘读写数据是按柱面进行的,磁头读写数据时首先在同一柱面内从 0 磁头开始进行操作,依次向下在同一柱面的不同盘面(即磁头上)进行操作,只有在同一柱面所有的磁头全部读写完毕后磁头才转移到下一柱面。
硬盘容量 = 柱面数(每个盘面的磁道数)×盘面数 × 扇区数 × 512字节

通常情况下每个扇区的大小是512字节。(由于不断提高磁盘的大小,部分厂商设定每个扇区的大小是4096字节)
逻辑层面: 磁盘块(虚拟出来的)。操作系统与磁盘之间交流的最小单位就是磁盘块,它是一个虚拟的概念。是对于操作系统(软件)来说有意义的概念。如:文件的物理存储都是以磁盘块为单位的。

在这里插入图片描述
在这里插入图片描述

2、什么是簇?和块什么区别?
通俗的来讲,在Windows下如NTFS等文件系统中叫做簇;在Linux下如Ext4等文件系统中叫做块(block)。每个簇或者块可以包括2、4、8、16、32、64…2的n次方个扇区。

3、为什么存在磁盘块?
读取方便:由于扇区的数量比较小,数目众多在寻址时比较困难,所以操作系统就将相邻的扇区组合在一起,形成一个块,再对块进行整体的操作。

分离对底层的依赖:操作系统忽略对底层物理存储结构的设计。通过虚拟出来磁盘块的概念,在系统中认为块是最小的单位。

4、怎么映射磁盘块?
磁盘控制器,其作用除了读取数据、控制磁头等作用外,还有的功能就是映射扇区和磁盘块的关系。

5、磁盘的读写基本单位是什么?
答案:读写基本单位是扇区。磁盘的原理,物理实现,磁盘控制器是按照扇区这个单位读取等操作数据的。操作系统是通过块簇来做为单位读取等操作数据的。此题问磁盘的读写,和操作系统没有关系,千万不要联系到操作系统层面去了。

文件系统就是操作系统的一部分,所以文件系统操作文件的最小单位是块。

6、磁盘块与扇区的大小
既然磁盘块是一个虚拟概念。是操作系统自己"杜撰"的。软件的概念,不是真实的。所以大小由操作系统决定,操作系统可以配置一个块多大。

一个块大小=一个扇区大小*2的n次方。

N是可以修改的。

7、为什么磁盘块大小必须是扇区大小的整数倍呢?
磁盘读取数据的基本单位就是一个扇区的大小,一个块的大小对于磁盘来说就是一次获取数据读取的扇区数*扇区大小,如果是整数倍的扇区数对于磁盘的IO更好,速度更快,也会更合理的利用资源。否则会对扇区进行分割。

一个扇区是512字节。有些硬盘厂商会提供4k大小扇区。这是物理结构。磁盘定下来的结构就是没法修改的。所以必须要将块设置为磁盘的大小。

8、4k对齐
随着时代发展,硬盘容量不断扩展,使得之前定义的每个扇区512字节不再是那么的合理,于是将每个扇区512字节改为每个扇区4096 个字节,也就是现在常说的“4K扇区”。随着NTFS成为了标准的硬盘文件系统,其文件系统的默认分配单元大小(簇)也是4096字节,为了使簇与扇区相对应,即使物理硬盘分区与计算机使用的逻辑分区对齐,保证硬盘读写效率,所以就有了“4K对齐”的概念。

新标准的”4K扇区”的硬盘在厂商为了保证与操作系统兼容的前提下,也将扇区模拟成512B,会默认定义为4096字节大小为一个簇,但因为其引导区占用了一个磁道共63个扇区,真正的文件系统在63号扇区之后。
我们通过计算得出前63个扇区大小为:512Bx63=32256B
并按照默认簇大小得出63扇区为:32256B÷4096B=7.875簇
即从第63个扇区结束,往后的每一个簇都会跨越两个物理单元,占据前一个单元的一小部分和后一个单元的一大部分。

而“4K对齐”主要是将硬盘的模拟扇区(512B)对齐到8的整数倍个“实际”4K扇区,即4096B*8=32768B,其正好跨过了63扇区的特性,从第64个扇区对齐。

9、块与页的关系
操作系统经常与内存和硬盘这两种存储设备进行通信,类似于“块”的概念,都需要一种虚拟的基本单位。所以,与内存操作,是虚拟一个页的概念来作为最小单位。与硬盘打交道,就是以块为最小单位。
 

封面图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只晨兴夜不得寐的运维人

你的打赏,是我今晚餐桌上的鸡腿

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值