linux磁盘与文件系统的管理

本文涉及命令:dumpe2fs、df、du、fdisk、mkfs、mke2fs、fsck、badblocks、mount、umount、e2label、tune2fs、hdparm、parted

概念:

  • 磁盘容量计算公式:
    • 磁头数量(其实是可读写的表面) X 磁柱数量(其实是每个表面的磁轨) X 每条磁轨的磁区数量 X 每个磁区的容量 = 硬碟容量
  • ext2等格式的文件系统为索引式文件系统。通过inode内容一次提取所有block号得到档案内容。fat等格式文件系统没有inode,每个block号码记录在前一个block当中,只能按顺序读取。当过于分散时,效能较差。碎片整理就是将统一档案的离散的block汇整在一起。
  • Ext2、3 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统。
    • superblock:记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
    • inode:记录档案的属性,一个档案占用一个inode,同时记录此档案的数据所在的 block 号码;
    • block:实际记录档案的内容,若档案太大时,会占用多个 block 。
  • 每个block group的内容如下:
    • inode table (inode 表格)-----------记录档案的属性以及该档案实际数据存放的block号
      • 记录的内容如下:
        1. 该档案的存取模式(read/write/excute);
        2. 该档案的拥有者与群组(owner/group);
        3. 该档案的容量;
        4. 该档案建立或状态改变的时间(ctime);
        5. 最近一次的读取时间(atime);
        6. 最近修改的时间(mtime);
        7. 定义档案特性的旗标(flag),如 SetUID...;
        8. 该档案真正内容的指向 (pointer);
      • 特性:
        1. inode 的数量与大小也是在格式化时就已经固定
        2. 每个 inode 大小均固定为 128 bytes;
        3. 每个档案都仅会占用一个 inode 而已;
        4. 因此文件系统能够建立的档案数量与 inode 的数量有关;
        5. 系统读取档案时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,若符合扄能够开始实际读取 block 的内容。
      • 限制及其解决方法:
  1. inode 记录一个 block 号码要花掉 4byte,inode 记录 block 号码的区域被定义为12个直接,一个间接, 一个双间接与一个三间接记录区。
  2. 这样子 inode 能够指定多少个 block 呢?我们以较小的 1K block 来说明好了,可以指定的情况如下:
  • 12 个直接指向: 12*1K=12K
  • 间接: 256*1K=256K  ----一个block为1KB除以存放一个block号码需要4字节,所以可以存放256个,每个1KB
  • 双间接: 256*256*1K=256^2K---------同理
  • 三间接: 256*256*256*1K=256^3K
  • 所以最大单个档案总容量为:12 + 256 + 256*256 + 256*256*256 (K) =16GB
  • data block (资料区块)-------------存放档案内容数据的地方
    1. Ext2文件系统中block支持的大小为 1KB、  2KB、  4KB
      • 对应支持的最大单一档案限制为 16GB、 256GB、2TB  
      • 对应支持的最大文件系统总容量为 2TB、  8TB、  16TB
    2. 原则上,block 的大小与数量在格式化完就与能够再改发了(除非重新格式化);
    3. 每个 block 内最多只能够放置一个档案的数据;
    4. 如果档案大于 block 的大小,则一个档案会占用多个 block 数量;
    5. 档案小于 block ,则该 block 的剩余容量就与能够再被使用了(磁盘空间会浪费)。
  • Superblock (超级区块)------------记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了
    •   一般来说, superblock 的大小为 1024bytes。
    • 一个文件系统应该仅有一个 superblock,但除了第一个block group内有之外,其他block group也可以有备份,这样可以进行 superblock 的救援。
    • 记录的主要信息有:
      • block 与 inode 的总量;
      • 未使用与已使用的 inode / block 数量;
      • block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128 bytes)
      • filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等文件系统的相关信息;
      • 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1
  • Filesystem Description (文件系统描述说明)
    • 这个区段可以描述每个 block group 的开始与结束的 block 号码,以及说明每个区段 (superblock, bitmap, inodemap, data block)分别介于哪一个 block 号码之间。这部分也能够用 dumpe2fs 来观察的。
  • block bitmap (区块对照表)
    • block bitmap记录哪些block是空的,供新建档案分配。删除档案的时候就将对应的block号码标记为『未使用中』
  • inode bitmap (inode 对照表)
    • inode bitmap记录哪些inode是空的,供新建档案分配。删除档案时,先将inode中记录的block标记为『未使用中』,然后将该inode号码标记为『未使用中』
  • block、inode与目录树和档案的关系
    • 当我们在 Linux 下的 ext2 文件系统建立一个目录时, ext2 会分配一个 inode 与至少一块 block 给该目录。其中,inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码; 而 block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据。
    • 当我们在 Linux 下的 ext2 建立一个一般档案时, ext2 会分配一个 inode 与相对于该档案大小的 block 数量给该档案。例如:假设我的一个 block 为 4 Kbytes ,而我要建立一个 100 KBytes 的档案,那么 linux 将分配一个 inode 与 25 个 block 来储存该档案! 但同时请注意,由于 inode 仅有 12 个直接指向,因此还要多一个 block 来作为区块号码的记录喔!
  • EXT2/EXT3 档案的存取与日志式文件系统的功能
    • 新建一个档案或目录时,ext2、3的处理过程:
      1. 先确定用户对于欲新增档案的目录是否具有 w 与 x 的权限,若有的话就能新增;
      2. 根据 inode bitmap 找到没有使用的 inode 号码,并将新档案的权限/属性写入;
      3. 根据 block bitmap 找到没有使用中的 block 号码,并将实际的数据写入 block 中,且更新 inode 的 block 指向数据;
      4. 将刚刚写入的 inode 与 block 数据同步更新 inode bitmap 与 block bitmap,并更新 superblock 的内容。
    • 日志式文件系统 (Journaling filesystem)--------解决同步与一致问题。例如仅有inode和datablock而未关联,同步不一致。
      • filesystem 当中会规划出一个区块记录写入或修订档案时的步骤
        1. 预备:当系统要写入一个档案时,会先在日志记录区块中记录某个档案准备要写入的信息;
        2. 实际写入:开始写入档案的权限与数据;开始更新 metadata 的数据;
        3. 结束:完成数据与 metadata 的更新后,在日志记录区块当中完成该档案的记录。
    • Linux 文件系统的运作:
    1. 系统会将待用的档案数据放置到主存储器的缓冲区,以加速文件系统的读/写;
    2. 承上,因此 Linux 的物理内存最后都会被用光!这是正帯的情况!可加速系统效能;
    3. 你可以主动使用 sync 来强迫内存中设定为 Dirty 的档案回写到磁盘中;
    4. 若正帯关机时,关机指令会主动呼叨 sync 来将内存的数据回写入磁盘内;
    5. 但若不正帯关机(如跳电、当机或其他与明原因),由于数据尚未回写到磁盘内, 因此重新启动后可能会花很多时间在进行磁盘检验甚至可能寻致文件系统的损毁(非磁盘损毁)。
  • 实体链接与符号链接: ln
    • Hard Link (实体链接, 硬式连结或实际连结)
      • 不能跨 Filesystem;不能 link 目录;
      • 仅在目录的block中添加一条记录,不增加inode和block, 删除其中一个,用其他路径依旧可以访问
    • Symbolic Link (符号链接,亦即是快捷方式)
      • 类似于快捷方式。当源文件删除,此档案无法打开。新增一个inode。
  • 磁盘挂载与卸除
    • 单一文件系统不应该被重复挂载在不同的挂载点(目录)中;
    • 单一目录不应该重复挂载多个文件系统;
    • 要作为挂载点的目录,理论上应该都是空目录才是。(否则源目录内容将暂时隐藏)
      • /etc/filesystems:查看系统指定的测试挂载文件系统类型;
      • /proc/filesystems:查看Linux系统已经加载的文件系统类型。
      • /lib/modules/$(uname -r)/kernel/fs/  查看linux支持的文件系统的驱动
      • mount -o remount,rw,auto /  重新挂载根目录
      • mount --bind 目录1 目录2  将目录挂载到其他目录。
      • mount -o loop /root/centos5.2_x86_64.iso /mnt/centos_dvd  特殊装置 loop 挂载 (映象档与刻录就挂载使用)
  • 设定开机挂载--------/etc/fstab (开机挂载内容)及 /etc/mtab(当前挂载情况)
    • 限制:
      • 根目录 / 是必项挂载的﹐而且一定要先于其它 mount point 被挂载进来。
      • 其它 mount point 必项为已建立的目录﹐可任意指定﹐但一定要遵守必项的系统目录架构原则
      • 所有 mount point 在同一时间之内﹐只能挂载一次。
      • 所有 partition 在同一时间之内﹐只能挂载一次。
      • 如若进行卸除﹐您必项先将工作目录移到 mount point(及其子目录) 之外。
    • /etc/fstab 内容解析:------修改后记得用mount -a 测试  是否与配置中的一致,否则可能无法开机
      • 第一栏:磁盘装置文件名或该装置的 Label:(uuid查看命令:blkid)
      • 第二栏:挂载点 (mount point):
      • 第三栏:磁盘分区槽的文件系统:
      • 第四栏:文件系统参数:
        • ro, rw: 挂载文件系统成为只读(ro) 或可擦写(rw)
        • async, sync: 此文件系统是否使用同步写入 (sync) 或异步 (async) 的
        • auto, noauto: 允许此 partition 被以 mount -a 自动挂载(auto)
        • dev, nodev: 是否允许此 partition 上建立装置档案? dev 为可允许。
        • suid, nosuid: 是否允许此 partition 含有 suid/sgid 的文件格式?
        • exec, noexec: 是否允许此 partition 上含有可执行 binary 档案?
        • user, nouser: 是否允许此 partition 让任何使用者执行 mount ?
        • defaults: 默讣值为:rw, suid, dev, exec, auto, nouser, and async
      • 第五栏:能否被 dump 备份指令作用
        • 0 不备份;1 每天备份;2 其他与定期备份
      • 第六栏:是否以 fsck 检验分区:
        • 0 表示不检验     例如内存置换空间(swap)
        • 1 表示最早检验   例如/目录
        • 2 需检验 次于1   例如其他目录
  • 建立大档案以制作loop装置档案
    • 先用dd命令制作一个大档案,再使用mkfs -t ext3 装置名 格式化工具格式化档案,最后利用mount - o loop 装置 目录  挂载!
  • 内存置换空间(swap)之建置
    1. 分割:fdisk /dev/hdc     分割
      • Command (m for help): p   查看分割
      • Command (m for help): t   修改文件系统 ID
      • [root@www ~]# partprobe          更新内核加载分区信息,避免重启
    2. 格式化:利用建立 swap 格式的『mkswap 装置文件名』就能够格式化该分割槽成为 swap 格式
      • [root@www ~]# mkswap /dev/hdc7
    3. 使用:最后将该 swap 装置启动,方法为:『swapon 装置文件名』
      • [root@www ~]# swapon /dev/hdc7
    4. 观察:最终透过 free 这个指令来观察一下内存的用量吧!
      • [root@www ~]# free
    • 建立一个虚拟内存的档案
      1. 使用 dd 这个指令来新增一个 128MB 的档案在 /tmp 底下:
        • dd if=/dev/zero of=/tmp/swap bs=1M count=128
      2. 使用 mkswap 将 /tmp/swap 这个文件格式化为 swap 的文件格式:
        • [root@www ~]# mkswap /tmp/swap
      3. 使用 swapon 来将 /tmp/swap 启动
      4. 使用 swapoff 关掉 swap file
        • [root@www ~]# swapoff /tmp/swap;swapoff /dev/hdc7
    • swap使用上的限制:
      • 在核心 2.4.10 版本以后,单一 swap 量已经没有 2GB 的限制了,但是,最多还是仅能建立到 32 个 swap 的数量!    

    命令:

    1. dumpe2fs [-bh] 装置文件名  ------查看superblock 的信息
      • -b :列出保留为坏轨的部分(一般用不到)
      • -h :仅列出 superblock 的数据,不会列出其他的区段内容!
    2. df [-ahikHTm] [目录或文件名]  -----列出文件系统的整体磁盘使用量
      • -h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
      • -i :不显示硬盘容量,而以 inode 的数量来显示;
      • -a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
      • -T :连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;
    3. du [-ahskm] 档案或目录名称  ---包含本目录以及子目录所有的字节
      • -s :列出总量而已,而不列出每个各别的目录占用容量;
      • -h :以人们较易读的容量格式 (G/M) 显示;
    4. fdisk [-l] 装置名称  --查看分区情况以及建立分区
      • -l :输出后面接的装置所有的 partition 内容。若仅有 fdisk -l 时, 则系统将会把整个系统内能够搜索到的装置的 partition 均列出来
      • 输入fdisk 装置名称(一般为硬盘名称)
        • 提示输入m 进入参数介绍
          • d delete a partition <==删除一个partition
          • n add a new partition <==新增一个partition
          • p print the partition table <==在屏幕上显示分割表
          • q quit without saving changes <==不储存离开fdisk程序
          • w write table to disk and exit <==将刚刚的动作写入分割表
      • partprobe----------更新分区表,不需重启
    5. mkfs [-t 文件系统格式] 装置文件名或磁盘分区  ----格式化磁盘
      • -t :可以接文件系统格式,例如 ext3, ext2, vfat 等(系统有支持就会生效)
      • 文件系统最顶层(挂载点的目录底下)存在的【lost+found】目录记录的就是fsck检查文件系统时若出现问题的记录,一般为空。
    6. mke2fs [-b block大小] [-i block大小] [-L 标头] [-cj] 装置  ---自定义格式化磁盘
      • -b :可以设定每个 block 的大小,目前支持 1024, 2048, 4096 bytes 三种;
      • -i :可以设定每个 inode 的大小。
      • -c :检查磁盘错误,一次-c读取测试;两次-c -c会测试读写,速度会很慢;
      • -L :后面可以接标头名称 (Label),
      • -j :本来 mke2fs 是 EXT2 ,加上 -j 后,会主动加入 journal 而成为 EXT3。
    7. fsck [-t 文件系统] [-ACDafy] 装置名称  -------文件系统检验----检查前请先卸载该分区
      • -A :依据 /etc/fstab 的内容,将需要的装置扫瞄一次。
      • -C :可以在检验的过程当中,使用一个直方图来显示目前的进度!
      • -D :针对文件系统下的目录进行优化配置。
      • -a :自动修复检查到的有问题的扇区
      • -f :强制检查!一般来说,如果 fsck 没有发现任何 unclean 的旗标,不会主动进入细部检查的,如果您想要强制 fsck 进入细部检查,就得加上 -f。
      • y :与 -a 类似,但是某些 filesystem 仅支持 -y 这个参数!
    8. badblocks -[svw] 装置名称  ------检查硬盘或软盘坏道
      • -s :在屏幕上列出进度
      • -v :可以在屏幕上看到进度
      • -w :使用写入的方式来测试,建议不要使用此参数,尤其是待检查的装置已有档案时!
    9. mount-----------磁盘挂载
      1. mount -a 依照配置文件 /etc/fstab 的数据将所有未挂载的磁盘都挂载上来
      2. mount [-l] 单纯的输入 mount 会显示目前挂载的信息。加上 -l 可增列 Label 名称!
      3. mount [-t 文件系统] [-L Label名] [-o 额外选顷][-n] 装置文件名 挂载点
        • -n :在默认的情况下,系统会将实际挂载的情况实时写入 /etc/mtab 中,加此参数就是不写入,例如用于单人维护模式。
        • -L :利用文件系统的标头名称(Label)来进行挂载。
        • -o :后面可以接一些挂载时额外加上的参数!内容为上面/etc/fstab里面的第四栏内容。
        • remount: 重新挂载,这在系统出错,或重新更新参数时,很有用!
      4. 重新挂载根目录:mount -o remount,rw,auto /       ------------单用户模式时发现根目录是只读!
      5. 将目录挂载到其他目录:mount --bind 目录1 目录2
      6. 特殊装置loop挂载:映象档不刻录就挂载使用  mount -o loop /root/centos5.2_x86_64.iso /mnt/centos_dvd
    10. umount [-fn] 装置文件名或挂载点  ------磁盘卸载
      • -f :强制卸除!可用在类似网络文件系统 (NFS) 无法读取到的情况下;
      • -n :不更新 /etc/mtab 情况下卸除。
    11. e2label 装置名称 “新的Label名称”-------修改文件系统标头
    12. tune2fs [-jlL] 装置代号  -----修改文件系统参数
      • -l :类似 dumpe2fs -h 的功能~将 superblock 内的数据读出来
      • -j :将 ext2 的 filesystem 转换为 ext3 的文件系统;
      • -L :类似 e2label 的功能,可以修改 filesystem 的 Label
    13. hdparm -Tt /dev/hdc  ---测试硬盘的读取能力
      • -T :测试暂存区 cache 的存取效能
      • -t :测试硬盘的实际存取效能 (较正确!)
      • -c3:激活32位传输。(-c0取消)
    14. parted -----------------高于2TB的硬盘需要使用parted进行分割。
      1. parted [装置] [挃令 [参数]]
        • 删除分割:rm [partition]
        • 新增分割:mkpart [primary|logical|extended] [ext3|vfat] 开始 结束
        • 查看分割表 :print
      2. 例:
        • [root@www ~]# parted /dev/hdc print 查看分割表
        • parted /dev/hdc mkpart logical ext3 19.2GB 19.7GB   建立分区
        • parted /dev/hdc rm 8   删除8号分割槽

    实例:

    • 删除磁盘分区的时候最好从最后面的磁盘删除起,比如有:/dev/sda7、/dev/sda6,因先删除前者再删除后者,避免因磁盘名引起的其他问题。且该分区不能被使用。在删除分区后,需要确认/etc/fstab里面不存在该分区,否则下次开机有问题。
    • 新建磁盘分区
      • 需求:由于我的系统原本分割的不够好,我的用户希望能够独立一个 filesystem 附挂在 /srv/myproject 目录下。 那你该如何建立新的 filesystem ,并且让这个 filesystem 每次开机都能够自动的挂载到 /srv/myproject , 且该目录是给project 这个群组共享的,其他人不可具有任何权限。且该 filesystem 具有 5GB 的容量。
        1. 建立新分区:『fdisk /dev/sda』--->『 n 』--->『Enter』--->『+5000M』--->『p 』
          • 进入磁盘---新建分区---设置容量---查看分区情况
        2. .避免重新启动,因此使用『 partprobe 』强制核心更新分割表;(如果依旧无法看到该分区设备就重启吧)
        3. 格式化分区:『mkfs -t ext3 /dev/sda6』
        4. 建立挂载点:『 mkdir /srv/myproject 』
        5. 编写自动挂载的配置文件:『 nano /etc/fstab 』,新增一行:
          • /dev/sda6 /srv/myproject ext3 defaults 1 2
        6. 测试自动挂载:『 mount -a 』,然后使用『 df 』观察看看有无挂载即可!
        7. 设定最后的权限,使用:『 chgrp project /srv/myproject 』以及『 chmod 2770 /srv/myproject 』即可。

    提醒:本文为《鸟哥linux私房菜基础篇》的学习笔记,如有不详细的地方可自行查阅该书内容。

    上一篇:利用CMake和OpenCV源代码生成Visual Studio工程


    下一篇:如何使用数据卷在宿主机和docker容器之间共享文件