14 磁盘及文件系统管理详解

  这一节内容我们一起来详细了解磁盘的工作原理;

磁盘管理

  首先,我们知道计算机的三大组建:CPU、内存、和I/O设备;其中磁盘就是属于外部的I/O设备,用于永久的存储文件数据;相对于CPU和内存而言,当前使用较多的机械磁盘还是处于“上一个阶段”的产品,对比起CPU内存这样的电子产品而言,速度可想而知。

  我们常见的外部存储设备有:U盘、光盘、软盘、磁盘、磁带等;其中U盘(闪存)为深圳朗科研发出来的,这些设备都是可以实现数据的永久存储的。

  其中,我们着重介绍磁盘的工作原理。

磁盘的物理组成

  巨磁电阻效应的发明:

  1988年,费尔和格林贝格尔各自独立发现了“巨磁电阻”效应:非常弱小的磁性变化就能导致古大的电阻变化。

  当硬盘体积不断变小,容量却不断变大时,势必要求磁盘上每一个被划分出来的独立区域越来越小,这些区域所记录的磁信号也就越来越弱。借助“巨磁电阻”效应,人们才得以制造出更加灵活的数据读出头,是越来越弱的磁信号依然能够被清晰读出,并且转换成清晰的电流变化。

  1997年,第一个基于“巨磁电阻”效应的数据读出头问世,并很快引发了硬盘的“大容量、小型化”革命。

  1、磁盘的大概结构:磁盘、轴与r/w head磁头中间

  用于数据存储的为盘片(platters),盘片都是围绕着主轴(spindle)进行旋转,数据的读取与写入都是通过磁头(read/write head)来完成,而读写横向看来的磁盘结构(actuator arm assembly)如下图:

  2、磁盘常见的几个基本概念

  扇区(Sector),磁道(Track)、以及柱面(Cylinder);

    磁道(Track):在一个盘片上,将其划分成n各同心圆,而这一个同心圆就叫做一个磁道;

    扇区(Sector):在一个磁道上,将其划分为多个512bytes大小的磁盘的扇形区域,这每一个扇形区域就叫做一个扇区;

    柱面(Cylinder):在多个磁盘上处于同一个地方的扇区的结合,就是柱面;

    【数据存储,磁盘分区都是根据柱面来进行分区的】

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

  分区(partition):在我们的windows系统上,C盘/D盘,这些概念实际上就是分区,而分区,实际上就是我们在磁盘上建立起一个逻辑边界,这就叫做分区(partition)

  分区是一个动作,分好的区我们需要为其写入文件系统,这个过程我们叫做格式化,只有写入文件系统的分区,才能够进行数据存储。格式化的内容我们在后面再进行介绍;

  这里,我们了解一个最为特殊的区域--MBR(master boot record)主引导记录MBR也就是我们磁盘上的第一个分区,它是属于物理概念,它是我们磁盘上处于最外面的一个扇区,大小为512bytes,它的主要作用就是加载主引导程序

    在MBR上,446bytes的大小为BootLoader引导程序【主引导分区对于系统而言至关重要,如果主引导分区故障,系统是无法启动的】

    64byter大小为磁盘标识符,1个磁盘标识符为16bytes,所以Linux最多只能有4个磁盘标识符,而这里所说的是主分区标识符,如果将这四个标识符空间做一个扩展标识,则又能够添加多个逻辑分区,所以这里我们不必担心磁盘的分区不够的问题;

      【这里需要记住:1、主分区加扩展分区最多有四个;2、扩展分区最多有一个;3、逻辑分区可以有任意个,前提是先划分一个扩展分区】

    最后2bytes是作为魔数,magic number,它用来标记MBR分区是否有效;

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

  这里,我们再介绍下系统的启动过程

    在系统启动的时候,内存为空,而CPU读取数据只能从内存中读取,此时,我们的电脑会将BIOS芯片中的一段启动程序自动加载到内存中来,完成如下两个工作:1、硬件设备的自检;2、自检无误,查找可以启动的系统。一般就是按照BIOS设置的查找顺序来查找系统,如果读取到的硬盘的系统文件,就会首先加载MBR分区中的BootLoader代码。通过读取BootLoader指定对应的分区信息,以及分区内容,找到操作系统加载到内存中来。内存再加载系统内核文件,内核文件关联具体程序,一步一步将所有需要的程序启动起来;

  【BIOS-->1、自检;2、加载BootLoader-->读取分区,加载系统内核-->系统内核启动应用程序】

  这就是我们系统启动的过程;

  3、磁盘的读写延迟从屋里角度来说

  磁盘分区是根据柱面来实现分区的。一般柱面越是靠外,则读取速度就越快。读取数据的时候,我们需要等待磁头到达对应的柱面,如果数据转过去了,就得等待数据再次转回来,而这个寻道时间,就是我们的延迟时间

  所以,如果盘片的转速越快,则延迟越小,这样的话读取数据的速度就越快;一般电脑磁盘的转速为5400rpm(转/分)或则是7200rpm,因为磁盘旋转速度太快,所以磁盘都要求在无尘的环境下进行工作;

文件系统

  对磁盘做了分区以后,如何来进行数据存储呢?我们说,如果不对磁盘进行分区格式化,则这个分区是无法存储数据的,而格式化是做了什么操作呢?

  格式化就是对分区做了文件系统的安装!!!

  分好的区,就好像一个图书馆,如果没有人管理,直接就把一大堆的书任意放置在图书馆里,则当用户需要查找某一本书的时候,将会是一个非常困难的事,而文件系统,就是管理数据的一个系统;就类似于图书馆对于图书管理的整个系统体系!

  文件系统:简单的来说,它就是一种软件,它并不是直接存储在这个分区上,我们可以将其理解为一个分区的管理软件,专门用来做数据管理;

文件系统结构

  文件系统是如何来管理数据的呢?我们先看下图:

 

    我们将分区分为两个部分,数据存储区和元数据存储区,数据存储区主要用来进行存储,而元数据存储区,则是用来存储数据的元数据,例如数据大小、数据类型、数据存储的时间等等!

    元数据存储区

      1、iNode信息(index node):通过 ls -i 我们可以查看到数据的iNode号,而这些iNode号,就与数据存储区的块信息对应,我们通过iNode信息来查找真实的数据所存储的位置,它就类似于书本的目录,包含了书本的所有类容;【同时,iNode信息也存放了数据的元信息,例如权限、属主与属组、时间戳等等信息,就是没有文件名

      2、iNode位图(bitmap):iNode信息是有限的,我们如何知道哪些iNode信息没有被使用,哪些iNode的信息已经使用了呢?如果通过遍历元数据存储区来查找则会非常麻烦,所有我们就有了iNode位图,只需要通过iNode位图来判断iNode信息的使用情况;

      3、块位图(block bitmap):同理,如果想查找哪些块没有被使用,则不需要去遍历整个数据存储区,而是只需要查看块位图即可;

    数据存储区

      在数据存储区中,我们会将空间大小分配为大小相等的块(block),而块的大小为2^n,一般为4096,可以自己调整为1024或者2048或者更大;

      数据块一般用来存储普通数据,普通的文本文件“-”,使用数据块较多,另外一类则是目录文件“d”,使用数据块较多;“p”管道文件,“s”套接字文件,以及“d”“c”设备文件都不占用块的大小;目录文件的块的数据则存放的为,iNode信息和对应iNode信息的目录名或者文件名

文件查找、新建、删除、复制与移动

  *查找:例如查找 /etc/log/message 的过程

    首先,根是自引用的;此时,我们从根开始查找,找到 / 所对应的块,这时候,在这个块下面存放的是 / 下的所有文件目录的名称以及iNode信息,此时就会看到 log 目录的 iNode 信息;第二步,通过查找 log 目录的iNode信息找到 log 对应的块,这个里面存放了 log 目录下对应的文件目录的名称和iNode信息,包括 message 文件;第三步,通过message 文件的iNode信息找到message文件对应的块,这时候就能找到message文件对应的数据了;

    最后,在查找到数据以后,我们会将目录信息进行缓存,保存一份,再下次查找该文件的时候就可以直接查找缓存信息;

  新建:新建文件,则会查看iNode位图与块位图,0表示该iNode位图或者块没有被占用,可以用来新建文件;

  删除:同理,在删除文件的时候,则是将iNode位图和块位图对应的位置置位为0,则表示对应的块和iNode条目没有被使用;【所以,数据在磁盘存储的时候是没有被清除的,通过数据恢复工具是可以将数据恢复的;】

  复制:在同一个分区下,不同的目录上的数据复制,会很快,因为这里我们只是将对应的iNode数据指向修改了,如果是不同的分区之间的数据复制,则会很慢,因为它将整个块中的数据都要进行复制;

  移动:移动的原理和复制相同;

常见的文件系统类型

  可以说,Linux几乎支持所有的文件系统类型;我们要知道,文件系统功能是属于内核功能,我们通过mkfs应用进程,将内核对应的文件系统功能写入到磁盘中,这就是格式化的过程;

  格式化分为两种:1、低级格式化,这一般是在磁盘出厂的时候由厂家来为我们完成, 它是用来创建磁道的;2、高级格式化,例如 mkfs -t ext3 /dev/sda3 ,这就是我们常见的格式化操作,用来为 /dev/sda3 这个磁盘分区写入文件系统;

  常见的文件系统:

    windows系统下常见的文件系统为fat32、NTFS、cifs(网络文件系统、网上邻居使用的);

    Linux下常见的文件系统ext2、ext3、ext4、xfs、reiserfs、jfs(IBM)、vfat(windows系统的fat32)、NTFS;集群文件系统ocfs2;网络文件系统nfs;全局文件系统gfs2;

  既然有这么多文件系统,那么每一个文件系统对于存储上它上面的文件的操作是不尽相同的,这样的话,对于开发人员而言,就需要为每一种文件系统开发一套文件的处理方式,这是很不合理的!

  为了避免这种情况,我们通过VFS,虚拟文件系统作为接口,来处理数据这样就避免了为每个文件系统开发不同的处理方式了;【虚拟文件系统VFS功能也是属于内核功能!】

链接文件与设备文件

  在我们了解了文件系统以后,我们着重了解两类文件--链接文件和设备文件;

  链接文件--l:链接文件分为两类,软链接与硬链接;

    软链接:也叫做符号链接;这个类似于windows系统下的快捷方式,软链接的iNode详细指向其他文件的iNode信息,而不是指向数据存储区的块信息;

      ln -s 参数为新建软连接,而 -v 参数表示显示创建链接的详细信息;

      我们可以看到文件b.txt是以“l”开头,同时在原本为文件大小的地方,存放的是 a.txt 文件的字符长度;

      如果删除原文件 a.txt 则 b.txt 的连接文件也会失效,但是如果从新有新建一个 a.txt 而这个 a.txt 已经不是原来的文件了(iNode号不同),则这个 b.txt链接文件是依然有效的;

    【总结:1、软链接可应用于目录;2、可以跨越文件系统;3、不会增加文件被链接的次数;4、其大小为指定的路径所包含的字符个数;】 

    硬链接:硬链接是将多个文件指向同一个block。只有在删除所有的链接文件后,这个文件才会被删除;

      ln 不加 -s 即是创建硬链接文件;

      我们可以看到在在权限后面有一个“2”,这里就表示文件的连接数,只有删除所有链接文件才会被删除;

      硬链接的iNode信息是相同的,说明他们指向的就是同一个文件;

  【总结:1、硬链接只能对文件创建,不能应用与目录;2、不能夸文件系统创建;3、创建硬链接会增加你文件链接数】

  设备文件--b,c:b 表示块设备文件,是按照块为单位,随机访问的设备,例如硬盘;c 表示字符设备文件,是按照字符为单位,是线性设备,例如键盘;

    /dev 主要就是用来存放设备文件的目录;

    设备文件主要包含两个内容,主设备号(major number)和次设备号(minor number),主设备号用来表示设备类型,此设备号用来区分同种类型设备的不同设备;

    我们可以通过mknod来创建设备文件,例如:

    mknod [option] ... NAME TYPE [MAIOR MINOR]

      -m MODE  #指定设备权限 -m 640 就是指定设备权限为 rw-r-----

 

    *这里我们有一个小技巧:可以通过重定向,将输入内容传递到其他终端,如下图:

    w 命令查看有哪些终端连接在该系统上,在通过 >> 将对应的信息在别的 pts 终端上面输出;

磁盘管理操作

 硬盘设备的命名

  硬盘设备的设备名,首先判断是什么类型的磁盘:IDE、ATA的磁盘为 hd;SATA、SCSI、USB的磁盘为sd;

  如果有多块磁盘,则用 a、b、c ... 来进行区分;

  若果是同一块磁盘上的多个分区,则用 1、2、3 ... 来进行区分;

  例如:sda 为第一个磁盘,sdb 则为第二个磁盘,sda1, 为第一个磁盘的第一个分区,sdb2 则为第二个磁盘的第二个分区;

  【逻辑分区可以有多个,扩展分区只能有一个,主分区最多有四个】

磁盘分区--fdisk

  fdisk命令用来对磁盘进行分区操作;

    -l  查看分区情况

fdisk还可以对磁盘进行管理,包括创建分区,删除分区等操作;
创建新的分区:
  fdisk /dev/sda #开启一个交互式命令
  m 获取帮助
  p 显示当前硬盘上面的分区、包括没有保存的改动
  n 创建新分区
  e 扩张分区
  p 表示主分区,去指定分区大小即可 +10G 它就会自动给我们指定柱面
  d 删除一个分区
  w 保存并退出
  q 不保存退出
  t 修改分区类型
  L 显示所有支持的分区类型
  l 显示所支持的所有类型
 
分区做好以后,可能内核还无法识别,我们通过查看 cat /proc/partitions 这个目录来判断内核是否识别我们新的磁盘信息。同时,如果没有识别,我们通过 partprobe 或者 partx [dev] 来让内核识别;

分区格式化(写入文件系统)--mkfs,mke2fs

   mkfs  make file system创建文件系统

    /proc/partitions  #查看系统所支持的文件系统;其中大部分为伪文件系统;

    -t FSTYPE  指定所需要创建文件系统的类型

      例如:mkfs -t ext2 /dev/sdb1

    这里我们要注意, -t 参数可以有对应的命令来替代;

      例如:mkfs -t ext2 = mkfs.ext2; mkfs -t ext3 = mkfs.ext3

  mke2fs  make ext2 file system创建ext类型的文件系统

    -j  则是指定创建ext3的文件系统,不指定默认的ext2文件系统

      例如:mke2fs -j /dev/sdb2

    -b  指定块大小,默认为4096,块大小只能为2^n;

    -L  指定卷标

    -m NUMBER  指定给root用户预留的磁盘空间百分比,默认为5%

    -i BYTE  用户指定为多少字节空间创建一个iNode,默认为8192;这里给出的这个数值应该为块大小的2^n倍;

      例如:mke2fs -i 4096

    -N NUMBER  指定创建iNode的个数;

    -F  强制创建文件系统,一般如果问价系统已经被挂载,则无法写入文件系统,使用 -F 则表示强制创建文件系统,不管分区是否被挂载;

    -E  用户指定额外文件系统属性;

  【这里提到的所有的参数,在mkfs命令下都能运行;】

  blkid  查询或者查看磁盘设备的相关属性

    例如:blkid /dev/sdb1  #查看/dev/sdb1的uuid、卷标、文件系统类型等基本信息

  e2label  为分区添加卷标

    e2label 设备文件 卷标

    例如:e2label /dev/sdb1 Test-lvm

  tune2fs  调整文件系统的相关属性

    -j  将ext2文件系统转换为ext3类型的文件系统,ext2可以转ext3 但不可以转回,转回数据丢失

      例如:tune2fs -j ext3 /dev/sdb1  #将原本的文件系统类型调整为ext3

    -L  为分区设定卷标;

    -m  调整root用户预留的空间百分比,用法与mke2fs相同;

    -r  指定root用户的预留空间的块数,不能和 -m 一起使用;

    -o  设定默认的挂载选项;

      acl  指定文件系统的acl功能,有点类似于setfacl文件的过滤功能;

    -c  指定挂载次数达到多少次后进行自检,0或者-1表示关闭此功能;

    -i  指定每隔多少天后进行自检,0或者-1表示关闭此功能;

    -l  显示超级块中的信息

      例如:tun2efs -l /dev/sdb1

  dumpe2fs  显示文件属性

    例如:dumpe2fs /dev/sdb1  #这里显示了分区从哪个组到哪组,起始块是多少,结束块是多少,那些块里面是有备份的那些没有;

    -h  和tune2fs一样,也是显示超级块信息的

  fsck  检测并修复文件系统

    -t fstype  指定文件系统类型,也可以不指定,fsck能够自动识别文件系统,但是一定不能指错了;

    -a  进行文件系统的自动修复;

  e2fsck  专门用来检查并修复ext2和ext3的命令

    -a  自动修复,不用询问

    -f  强制检查

      例如:e2fsck -f /dev/sdb1

    -p  也是自动修复,-a 是为了兼容fsck命令

磁盘分区挂载与卸载--mount,umount

  挂载:将新的文件系统关联至当前根文件系统;这个动作就是为磁盘分区找一个接入入口,有了这个访问的入口后,就能够访问到这个分区上的所有文件内容;

  卸载:将某文件系统与当前文件系统的关联关系移除掉;

  mount  挂载

    用法:mount 设备名 挂载点

    设备名:可以是设备文件名,也可以是卷标(LABEL=""),也可以是UUID(UUID="");

    挂载点:也就是一个目录

      【但是,这个目录最好是一个空目录,同时,这个目录没有被任何进程调用,如果这个目录里面存在其他文件,当挂载设备后,这些原有的文件就会别隐藏;】

    例如:mount /dev/sdb1 /mnt/test  #这样,你在/mnt/test目录下编辑的所有文件,都保存于/dev/sdb1这个分区下,默认情况下会有一个lost+found目录;

  mount  直接回车,不带任何参数,就是查看系统的挂载情况;

    参数以及用法:mount [option] [-o option] device mount_point

      -a  直接指定挂载 /dev/fstab 目录下的所有文件,这里是我们做开机自动挂载的默认目录;

      -n  默认情况下,mount命令没挂载一个设备,都会把挂载的设备信息保存至 /etc/mtab 文件下;使用 -n选项,就是说挂载设备后,不把信息写入到 /etc/mtab 这个文件里面来;

      -t fstype  指定正在挂载的设备上的文件系统的类型,不适用此选项,则mount命令能够自动识别;

      -r  只读挂载,一般在挂载磁盘的时候会使用到;

      -w  读写挂载,默认情况下,磁盘挂载的时候就是读写挂载;

      -o  指定额外的挂载选项,也可指定问价那系统启用的属性;

        async  异步写入(默认就是异步)

        atime  指定时间戳

        auto  自动挂载,can be mounted with the -a option

        default  使用默认参数挂载

        dev  指定固定设备文件

        exec  容许挂载二进制的文件

        _netdev  映射文件系统

        owner  容许普通用户挂载这个磁盘

        remount  从星挂载当前文件系统

          例如:mount -o remount,ro /dev/sdb1  #重新挂载/dev/sdb1同时指定为只读权限;

        ro  只读挂载

        rw  读写挂载

        sync  同步挂载

        suid  挂载的时候提供suid权限

  umount  卸载文件系统

    用法:umount 设备名  或者  umount 挂载点  

    卸载要注意:挂载的设备没有被进程使用;

swap分区--mkswap,swapon/swapoff与dd

  swap是系统的交换分区,是用来弥补内存不足的时候,占时顶替内存的分区空间;

  free  查看系统内存的使用情况

  fdisk /dev/sdb2  #先创建一个交换分区

    注意,这里我们一定要将 /dev/sdb2 分区的分区类型修改为 82 Linux swap分区才行;

    mkswap /dev/sdb2  #创建swap磁盘分区

      -L LABEL  可以添加卷标

    swapon /dev/sdb2  启用这个磁盘分区,同理 swapoff /dev/sdb2 就是关闭这个磁盘分区,注意:交换分区是不用挂载的;

  本地虚拟回环设备:

    如果我们内存不够,可以通过将磁盘的空间划分为swap分区来临时解决,如果磁盘空间也不够了,又不能添加新的磁盘,这时候我们该如何解决这个问题呢?

    我们可以创建一个镜像文件,比如:模拟一个100G的空间,这100G的空间就可以用来进行数据存储,但是这100G的空间实际上只占有1m甚至更小的物理空间;

    dd  convert and copy a file 装换或者复制一个文件

      例如:dd if=/etc/inittab of=/root/inittab  将文件/etc/inittab复制到/root/inittab

      这里我们需要注意一下dd与copy的区别,他们都是用来对文件进行复制的,但是,dd是直接对磁盘上的内容进行操作,所以,它可以复制一个文件的部分内容;而copy则是将要复制的文件移动到内存中,再由cpu进行复制操作后,放回到对应的磁盘位置中;所以,dd的效率要高很多;

      if=源数据    #input file

      of=目标数据  #output file

      bs=数值    #一次复制多大的单位

      count=数值    #将复制的文件转换为多少个字节来进行存储

        例如:dd if=/dev/sdb of=/mnt/usb/mbr.backup bs=512 count=1

          dd if=/mnt/usb/mbr.backup of=/dev/sdb bs=512 count=1

          #这就是使用dd命令来做磁盘备份,备份MBR分区,又可以通过dd命令将MBR分区还原;

          dd if=/dev/zero of=/var/swapfile bs=1M count=1024

          #/dev/zero 文件叫做泡泡文件,可以凭空创建磁盘空间【/dev/null 黑洞设备,只要指向这个文件的内容都会被删除】

    

原文地址:https://www.cnblogs.com/BurnovBlog/p/10432203.html