linux基础之磁盘管理与文件系统

上面一篇文章(https://www.cnblogs.com/ckh2014/p/7224851.html)介绍了硬盘的基本结构,那么一块磁盘如何应用取存储数据呢?

它的步骤是这样的: 

识别硬盘 --> 磁盘分区 --> 分区格式化 --> 挂载 --> 写入/存储数据

识别硬盘

这是linux内核的事情,在之前博文CentOS启动流程(https://www.cnblogs.com/ckh2014/p/9571066.html)中介绍系统启动时内核会初始化加载硬盘的驱动程序,所以我们登录系统后fdisk会查看到硬盘的相关信息。

 磁盘分区

分区模式有MBR和GPT两种模式:

MBR:Master Boot Record,主引导记录模式,也称为MSDOS模式
MBR模式是在硬盘的第一个扇区(512bytes)中,将前446bytes用来记录引导程序,后面64bytes用来记录分区表(partition table),最后2bytes为结束符号。
分区表(64bytes)中每16个bytes标识一个分区,所以只能标识四个主分区,存储容量最大约2.2TB
linux基础之磁盘管理与文件系统_第1张图片
GPT:GUID Partition table,全局唯一标识磁盘分区表

GPT模式打破了MBR的限制,可以设置多达128个分区,分区的大小根据操作系统的不同有所变化,但是都突破了2T空间的限制。支持高达 18EB (1EB=1024PB,1PB=1024TB) 的卷大小,允许将主磁盘分区表和备份磁盘分区表用于冗余,还支持唯一的磁盘和分区 ID (GUID)。

与 MBR 分区的磁盘不同,GPT的分区信息是在分区中,而不象MBR一样在主引导扇区。为保护GPT不受MBR类磁盘管理软件的危害,GPT在主引导扇区建立了一个保护分区 (Protective MBR)的MBR分区表,这种分区的类型标识为0xEE,这个保护分区的大小在Windows下为128MB,Mac OS下为200MB,在Window磁盘管理器里名为GPT保护分区,可让MBR类磁盘管理软件把GPT看成一个未知格式的分区,而不是错误地当成一个未分区的磁盘。
在MBR硬盘中,分区信息直接存储于主引导记录(MBR)中(主引导记录中还存储着系统的引导程序)。但在GPT硬盘中,分区表的位置信息储存在GPT头中。但出于兼容性考虑,硬盘的第一个扇区仍然用作MBR,之后才是GPT头。

linux基础之磁盘管理与文件系统_第2张图片
GPT使用34个LBA,最后33个用来做分区信息备份。
逻辑区块位址中,LBA0(MBR相容区块)中446bytes用来存放开机管理程式(boot loader),原本用来存放分区表信息的地方只存放一个特殊标志,用来表示磁盘为GPT分区格式。
         LBA1(GPT表头记录)中记录了分区表的位置和大小,同时记录了备份用的GPT分区存放位置。
          LBA2-33(实际记录分区信息处),每个LBA默认有4个分区,总共512bytes,每个分区信息用到128bytes,这之中除了识别码和相关记录外,会有64bits来记录开始/结束的磁区号码。

分区格式化

硬盘分区后,如果想要实现对文件的快速存取以及访问,还要依赖文件系统,需要在分区上面创建文件系统。文件系统是一个软件,此处以ext文件系统为。文件储存在硬盘上,硬盘的最小存储单位叫扇区(Sector)。每个扇区储存512字节(相当于0.5KB)。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个块(block)。这种由多个扇区组成的块是文件存取的最小单位,块的大小,最常见的是4KB,即连续八个sector组成一个block,文件数据都储存在块中,而每个数据文件存在哪些块中,从哪个块开始,到哪个块结束,那么很明显,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存元信息的区域叫做inode,中文译名为”索引节点”。

linux基础之磁盘管理与文件系统_第3张图片     

每一个inode有一个全局唯一的ID(这里的全局指的是某个分区下,某分区下不同文件的inode号不可能相同,不同分区的inode号有可能相同),每个inode中存放了对应文件的inode号,文件类型、属主属组、权限、大小、时间、以及文件数据存储在哪些磁盘块等信息(元数据中没有当前文件的文件名,当前文件的文件名存放在父目录的数据块中),如果一个文件过大,那么他需要的块就会很多,inode中存储的对应块信息就会很多,但是如果文件很大,成千上万的块信息的存储空间就会很大,它可以利用指针,指向另一个更大的空间,存储这些块信息。

 inode详细结构示意图如下:

linux基础之磁盘管理与文件系统_第4张图片

文件系统格式化,也就是将分区分成多个块组,有些是超级块,后面的块组中有些会有超级块的备份。块组的详细示意图如下:

linux基础之磁盘管理与文件系统_第5张图片

超级块包含信息要比普通块组多一些,下面详细介绍下超级块包含的信息。

超级块详细信息:

1.引导块(boot sector):
   如果没有引导代码,这两个扇区内容为空,全部用0填充

 2. 超级块(Super Block): 
    这个块是用来保存该磁盘上所有的块组的信息,比如每一个块组从哪一个块开始,到哪一个块结束等信息,  
  还包括各种meta信息, 块大小, 每个块组包含块数, 总块数, 第一个块前保留块数, inode节点数, 每个块组的inode节点数, 卷名, 最后挂载时间, 挂载路径, 
  文件系统是否干净, 是否要调用一致性检查标识,空间inode节点和空闲块的记录信息等, 在分配inode节点和新块的时候使用。
  因此一旦超级块坏掉了,其他所有块组的信息都无法读取了,所以超级块有很多备份,存放于其他块组中,但使用时只使用块组0中的超级块,一旦坏了就从其他块组中找一个加以恢复。

3. 块组描述表(Group Description Table)
    块组描述符表中包含了所有块组的描述信息,它存放的是块位图(Block Bitmap)和 inode位图(Inode Bitmap),即哪些块是已用的,哪些块是空闲的;哪些inode是已用的,哪些inode是空闲的,这样  的位图比整个磁盘的位图要小得多,故扫描效率会提高很多。而通过Inode表(Inode Table)就可以找到相应的磁盘块(Data Blocks)。组描述符和超级块在每个块组中都有一个备份, 但是激活了稀疏超级块特  征的情况除外。稀疏超级块即不是在所有块组中都存储超级块和组描述符的备份, 默认该策略被激活, 其策略类似当块组号是3,5,7的幂的块组才存副本。  
4.数据块位图
  每个块对应一个bit, 只包含了本块组的信息。而文件系统创建的时候, 默认每个块组包含的块数跟每个块包含的bit数是一样的。
而该位图表的块的起始位置会在组描述符表中指定, 大小则为块组中包含块数个bit。
5.inode位图
  跟块位图类似, 通常情况他也只占用一个块。通常一个块组中的inode节点数会小于block数量。
6.inode节点表
  每个inode都占用128位的一个描述信息, 起始位置在组描述符表中表示。
7.数据区
  这就是真正存储数据的区域。

inode详细信息:

上面提到inode表是存放每个文件元数据信息的,每一条元数据用一个inode表示,inode结构示意图如下

linux基础之磁盘管理与文件系统_第6张图片

这里介绍下块指针的概念

直接块指针:
    12个直接指针,直接指向存储数据的块。假设一个block块大小为4k,那么直接块指针指向的块的大小总和为4k*12 = 48k,也就是说如果一个文件的数据大小不超过48k,
   使用直接块指针指向的块就能满足数据存储的需求。 间接块指针: 
   如果一个文件的大小大于48k,'直接块指针'指向的块大小无法满足存储需求,这时候就会用到‘间接块指针’,‘间接块指针’指向一个数据块,我们暂且称这个被‘间接块指针’指向的块为‘间接块’,
   ‘间接块’中不存放数据,而是存放指针,这些存放在‘间接块’中的指针再指向真正存放数据的块,我们还按照上述假设,每个块4k大小,
   假设每个指针占用4个字节的空间,那么一个4k的块能存放1024个指针,也就是间接块中能存放1024个指针,这些指针每个再指向一个4k的块,
   那么所有能指向的块的大小为4k * 1024 = 4M ,也就是说能够存放小于4M大小的文件。
双重间接块指针: 同理,如果文件大于4M,‘间接块指针’能够指向的所有块的大小总和无法满足要求,这时候就会用到 ‘双重间接块指针’ ,‘双重间接块指针’的原理跟‘间接块指针’的原理相同,
   只是又多间接了一层,‘双重间接块指针’先指向一个‘间接块’,这个间接块里存放了1024个指针,‘间接块’里的每个指针再指向一个‘二重间接块’,因为每个块的大小都是4k
   所以每一个‘二重间接块’又能分化出1024个指针,这些来自‘二重间接块’的指针再指向真正存放数据的块。所以,总共算下来,能够存放1024 * 1024 * 4k = 4G 的数据。
三重间接块指针: 三重间接块指针的原理同上,以此类推。三级指针可以储存文件数据大小为1024*1024*1024*4=4TB

Linux中cp、rm、mv 、ln对inode的影响:

 cp命令

  •         分配一个未被使用的inode号,在inode表中添加一个新项目,(注意:如果是cp文件到已经存在的文件,则inode号采用被覆盖之前的目标文件的inode号)

  •         在目录中新建一个目录项,并指向步骤1中的inode

  •         把数据复制到block中

    rm命令

  •         减少链接数量,如果链接数为0,释放inode(inode号被重新使用);

  •         如果inode被释放,则数据块放到可用空间列表中;

  •         删除目录中的目录项

    mv命令

       1. 如果mv命令的目标文件和源文件所在的文件系统相同:

        使用新文件名建立目录项;

        删除带有原来文件名的目录项;

        注意:该操作对inode表没有影响(除时间戳),对数据的位置也没有影响,不移动任何数据。(即使是mv到一个已经存在的目标文件,新目录指向源文件inode,会先删除目标文件的目录项)

       2. 如果目标文件和源文件所在的文件系统不相同,就是cp和rm;

    ln命令

        符号(软)链接:

        符号链接的内容是它引用文件的名称,可以是任意文件或目录,也可以链接不同文件系统的文件,甚至可以链接不存在的文件,这就产生一般称为断裂的问题,还可以不断的循环链接源文,但是其大小为指向的路径字符串的长度;不增加或减少目标文件inode 的引用计数。

        使用ln -s source_file softlink_file (注意:源文件(source_file)的路径是相对路径(也可以是绝对路径,通常使用的是相对路径),一定是相对于软链接文件的路径,而非相对于当前工作目录的路径)创建符号链接,在对符号链接进行读写操作的时候,系统会自动把该操作转换为对源文件的操作,但是删除链接文件时,系统仅仅删除符号链接文件,而不是删除源文件本身。

    硬链接:

        不允许给目录创建硬链接,创建硬链接会增加inode的引用计数(不能跨驱动或分区创建硬链接),硬链接件对应于同一文件系统上的一个物理文件,硬链接节点编号是相同的,创建硬链接链接数递增,删除文件时:rm命令递减计数的链接,文件如果存在,至少有一个链接数,当链接数为0时,该文件被删除。

        使用ln existfile newfile 命令创建硬链接

        硬链接于软连接的区别:

        1、本质不同:硬链接是指向同一个文件,软链接指向的不是同一个文件

        2、删除时:硬链接不受影响,软链接失效

        3、创建链接时:创建硬链接链接数加1,创建软链接连接数不变

        4、是否可以跨分区:硬链接不可以跨分区,软链接可以跨分区

        5、目录是否可以创建链接:硬链接不可以对目录创建,软链接可以对目录创建

        6、硬链接的inode号相同,软链接inode号不同

挂载

Linux中的根目录以外的文件要想被访问,需要将其“关联”到根目录下的某个目录来实现,这种关联操作就是“挂载”,这个目录就是“挂载点”,解除关联关系的过程称之为“卸载”。

  注意:“挂载点”的目录需要以下几个要求:

    (1)目录事先存在,可以用mkdir命令新建目录;

    (2)挂载点目录不可被其他进程使用到;

    (3)挂载点下原有文件将被隐藏。

最后介绍下磁盘管理和文件系统的相关命令:

1.分区相关的命令

对硬盘分区:只能管理15个分区  

  # fdisk -l  //显示当前系统上所有的磁盘分区情况
  # fdisk DEVICE: //对某个设备分区,比如硬盘sdb
     自命令:管理功能
        p:  print,显示已有分区
        n: new,创建一个分区
        d: delete, 删除一个分区
        t: 调整分区id
        l: 列表显示分区id
        w: write: 写入磁盘并退出
        q:quit, 放弃更新并退出            

通过上面的命令创建好分区后,需要重新读取硬盘分区表

有三种命令可以实现:
   1. partx -a /dev/device        -n M:N 读取哪几个分区
   2. kpartx -a /dev/device        -f: force
   3. partprobe [/dev/device]

查看内核是否已经识别新分区 

cat /proc/partitions
有些时候重新读取新分区后,旧的已经删除的分区还在,这时可通过 partprobe重新读取分区信息,会删除旧的记录。

2、文件系统格式化相关命令

mkfs命令:
    # mkfs.FS_TYPE /dev/DEVICE
    # mkfs -t FS_TYPE /dev/DEVICE         -l 'LABEL': //设定卷标
        FS_TYPE文件系统类型有 ext2、ext3、ext4、xfs、btrfs、vfat
mke2fs: ext系列文件系统专用管理工具
      -t {ext2 | ext3 | ext4}  // 文件系统类型
      -b {1024 | 2048 | 4096}  // 块大小
      -L 'LABEL'    // 设定卷标
      -j: 相当于 -t ext3    // 开启日志功能
      -i   #:   // 为数据空间中每多少个字节创建inode
      -N # :   // 为数据空间创建多少个inode
      -m # :   // 为管理人员预留的空间占用的百分比,默认为百分之5
      -O FEATURE[...]:   // 启用指定特性
      -O ^FEATURE:   // 关闭指定特性
mkswap: 创建交换分区       -L 'LABEL'
blkid: 块设备属性信息查看
      -U UUID: 根据指定的UUID来查找对应的设备
      -L LABEL: 根据指定的LABEL来查找对应的设备
e2label: 管理ext系列文件系统的LABEL
   #e2label DEVICE [LABEL]
tune2fs: 重新设置ext系列文件系统可调整参数的值
      -l: 查看指定文件系统超级块信息
      -L 'LABEL':修改LABEL
      -m #: 修改预留给管理员的空间百分比
      -j: ext2升级为ext3
      -O: 文件系统属性启用或禁用
      -o: 调整文件系统的默认挂载选项
      -U UUID:修改UUID号
dumpe2fs:  // 查看卷组信息
      -h: 查看超级块信息
文件系统检测:
      fsck.FS_TYPE
      fsck -t FS_TYPE
        -a: 自动修复错误
        -r: 交互式修复错误

      e2fsck: ext系列文件专用的检测修复工具
        -y: 自动回答yes
        -f: 强制修复

3. 挂载与卸载相关命令

挂载命令:mount

卸载命令: umount

挂载命令:mount

  mount命令: 通过查看/etc/mtab文件显示当前系统已挂载的所有设备

  查看内核追踪到的已挂载的所有设备: cat /proc/mounts

  mount [-fnrsvw] [-t vfstype] [-o options] device dir  //注意: 挂载点下原有文件在挂载完成后会被临时隐藏  

    device:指明要挂载的设备
      (1)设备文件:例如:/dev/sda5
      (2)卷标:-L 'LABEL' 例如 -L "MYDATA"
       (3) UUID,-U 'UUID' 例如 -U 'ABD12ds12'
      (4)伪文件系统名称:proc,sysfs,devtmpfs,configfs
    dir:挂载点
      事先存在:建议使用空目录:
      进程正在使用中的设备无法被卸载(/application/htdocs)

    常用选项:
      -t vfstype: 指定要挂载的设备上的文件系统类型
      -r: readonly,只读挂载
      -w: read and write,读写挂载
      -n: 不更新/etc/mtab
      -a: 自动挂载所有支持自动挂载的设备:(定义在了 /etc/fstab文件中,且挂载选项中有“自动挂载”功能)
      -U 'UUID': 以UUID指定要挂载的设备
      -B,--bind: 绑定目录到另一个目录上

    -o options: (挂载文件系统的选项)
        async: 异步模式:
        sync: 同步模式:
        atime/noatime:
        diratime/nodiratime:目录的访问时间戳
        auto/noauto: 是否支持自动挂载
        exec/noexec:是否支持将文件系统上应用程序运行为进程
        dev/nodev: 是否支持在此文件系统上使用设备文件
        suid/nosuid:
        remount:重新挂载
        ro:
        rw:
        user/nouser:是否运行普通用户挂载此设备
        acl: 启用此文件系统上的acl功能

  注意:上述选项可多个同时使用,彼此使用逗号分隔
  默认挂载选项:defaults(rw,suid,dev,exec,auto,nouser,and async)

卸载命令:umount DEVICE
挂载交换分区:
      启用:swapon
         swapon [OPTION]...[DEVICE]
            -a: 激活所有的交换分区
            -p: PRIORITY:指定优先级
      禁用: swapoff [OPTION]...[DEVICE]
查看正在访问指定文件系统的进程:
        fuser -v MOUNT_POINT
        fuer -km MOUNT_POINT  终止所有正在访问指定文件系统的进程
内存空闲使用状态:
        free [OPTION]
          -m: 以MB为单位
          -g: 以GB为单位
文件系统空间占用等信息的查看工具:
        df [OPTION]
          -h: human-readable
          -l: inodes instead of blocks
          -P: 以Posix兼容的格式输出
查看某目录总体空间占用状态:
        du [OPTIONS] DIR
          -h: human-readable
          -s: summary

要实现开机自动挂载,则要修改挂载的配置文件: /etc/fstab

每行定义一个要挂载的文件系统:
      1.要挂载的设备或伪文件系统: 设备文件、LABEL(LABEL="")、UUID(UUID="")、伪文件系统名称(proc、sysfs) 
      2.挂载点
      3.文件系统类型
      4.挂载选项: defaults
      5.转储频率:
         0:不做备份
         1:每天转储
         2:每隔一天转储
      6.自检次序:
         0:不自检
         1:首先自检,一般只有rootfs才用1

四、实例

1.创建一个20G的文件系统,块大小为2048,文件系统为ext4,卷标为TEST,要求此分区开机后自动挂载至/testing目录,且默认有acl挂载选项
      a. 创建20G的分区
      b. mke2fs  -t ext4 -b 2048 -L TEST /dev/DEVICE
      c. 编辑/etc/fstab: 增加一行:LABEL="TEST" /testing ext4 defaults,acl 0 0 
2.创建一个5G的文件系统,卷标HUGE,要求此分区开机自动挂载至/mogdata目录,文件系统类型为ext3
      a. 创建5G分区
      b. mkfs.ext3 -L HUGE /dev/DEVICE
      c. 修改配置文件/etc/fstab: 增加一行:LABEL='HUGE' /mogdata ext3 defaults 0 0 
3.写一个脚本:
   (1)列出当前系统识别到的所有磁盘设备
    # fdisk -l | grep -o "^Disk /dev/[sh]d[a-z]"
   (2)如磁盘数量为1,则显示其空间使用信息,如果大于1则显示最后一条
    #!/bin/bash
    #
    disknum=$(fdisk -l | grep -o "^Disk /dev/[sh]d[a-z]" | wc -l)
    if [ $disknum -eq 1  ]: then
    fdisk -l `fdisk -l | grep -o "^Disk /dev/[sh]d[a-z]" | cut -d' ' -f2`
    else
      fdisk -l `fdisk -l | grep -o "^Disk /dev/[sh]d[a-z]" | tail -1 | cut -d' ' -f2 ` 
    fi       

 

转载于:https://www.cnblogs.com/ckh2014/p/10813097.html

你可能感兴趣的:(linux基础之磁盘管理与文件系统)