目录

磁盘分区

Linux 的硬盘分区标识:

  • IDE 接口硬盘:/dev/hd[a-z]X
  • SCSI 接口的硬盘:/dev/sd[a-z]X

其中 [a-z] 代表硬盘号,X 代表硬盘内的分区号。

以 MBR 类型分区为例,硬盘分区一共有三种:

  1. 主分区(Primary Partion):可以马上被使用但不能再分区。
  2. 扩展分区(Extension Partion):必须再进行分区后才能使用,也就是说它必须还要进行二次分区。
  3. 逻辑分区(Logical Partion):由扩展分区建立起来的分区,逻辑分区没有数量上限制。

如果分区标号 X 的值是 1 到 4,表示硬盘的主分区(包含扩展分区);逻辑分区从是从 5 开始的,比如:/dev/hda5。注意,主分区和扩展分区的数目之和不能大于四个。扩展分区只不过是逻辑分区的 “容器”,实际上只有主分区和逻辑分区进行数据存储。

Linux 中磁盘分区和目录结构的关系如下:

  • 根目录是所有 Linux 文件和目录所在的地方,需要挂载上一个磁盘分区。
  • 磁盘分区都必须挂载到目录树中的某个具体的目录上才能进行读写操作。
  • 目录是逻辑上的区分,分区是物理上的区分。
MBR 与分区表

磁盘的 0 号分区称为主引导记录(Master Boot Record,MBR),用来引导(Boot)计算机。在 MBR 的结尾是分区表(Partition table)。每个分区表给出每个分区由开始到结束的地址。系统管理员使用一个称为分区编辑器的程序来创建,调整大小,删除和操作分区。这种方式的一个缺点是很难适当调整分区的大小,导致一个分区具有很多可用空间,而另一个分区几乎完全被分配。

MBR 可以用在 DOS 、Microsoft Windows 和 Linux 操作系统中。从 2010 年开始,大多数新计算机都改用 GUID 分区表(GPT)分区方案。

  • MBR 格式:兼容性好,一个磁盘最多有 4 个主分区、1 个扩展分区、若干个在扩展分区下的逻辑分区。
  • GPT 格式:容量大于 2TB,可以有 128 个主分区。

创建 MBR 分区

fdisk –l 显示磁盘分区信息。
swapon –s 显示 swap 分区的信息。

步骤

fdisk –cu /dev/sda:进入磁盘分区交互式操作。交互式控制台输入项:

  • p 查看分区表
  • n 新建分区
  • e 新建扩展分区
  • 选择默认分区起始位置
  • 选择分区的结束位置
  • 新建一个 512M 的逻辑分区:
  • n 新建分区
  • 回车 选择分区默认起始位置
  • +512M 设定逻辑分区大小
  • p 查看分区表
  • t 进入分区类别选择
  • 5 对 sda5 进行操作
  • 82 将 sda5 转换成 Swap 交换分区
  • p 再次查看分区表
  • w 保存 sda5 分区类型

在退出交互式分区操作控制台后执行:partx –a /dev/sda 刷新 sda 分区表,需要执行 2 次。

处理 Swap,还有以下分区类型以及各自的编号:

    type:   code:
    NTFS 
    xfs      83
    ext4
    ext3  
    swap     82 
    lvm      8e 
    raid     fd 
    extend   5

创建 GPT 分区

  • parted /dev/sdX
  • mkpart partName
  • 输入起始 MB
  • 输入结束 MB
  • parted 刷新生效
  • gdisk /dev/sdX
分区的格式化

磁盘分区完毕后还需要进行格式化(Format),之后操作系统才能够使用这个分区。格式化的目的是能使操作系统可以使用的文件系统格式,即我们上面提到文件系统类型。可见,Linux 的每个分区都有独立的文件系统,每块分区的文件系统可以不同。

  • 格式化 Swap 分区:
partx –a /dev/sda		# 刷新磁盘 sda 的分区表
mkswap /dev/sda5		# 格式化 sda5 分区为 Swap 分区
swapon /dev/sda5 		# 开启使用 swap 分区
swapon –s 					# 显示 swap 分区列表信息
  • 格式化 XFS 分区:
xfs_info  /dev/sdx							# 查看 xfs 分区的属性,必须要挂载后才能查看。
mkfs.xfs -b size=1024 /dev/sdx       # 格式话为 XFS 分区,-b 指定 data block Size;-i 指定 inode Size。
xfs_admin -u  /dev/sdx                    # 查看 UUID,UUID 每次格式化后都会变化。

# 为已经格式化的分区修改 UUID
uuidgen
xfs_admin -U "0db55c77-5706-4b96-9573-fb9700185492" /dev/sdX
xfs_admin -L xxxxxx /dev/sdx  # 设置 xfs 分区的卷标
xfs_admin -l /dev/sdx

xfs_info /dev/sdaX 		 # 查看 XFS 文件系统

  • 格式化 Ext4 分区:
mkfs.ext4 /dev/myvg/mylv

tune2fs -l /dev/sdaX	 # 查看 EXT 文件系统
分区的特性

磁盘分区的布局是随着文件系统的不同而变化的。通常文件系统会包含一些属性,如下:
Linux 操作系统原理 — 文件系统 — 存储布局_Linux 操作系统原理

每种操作系统能够使用的文件系统并不相同,如:Windows 98 以前的微软操作系统主要利用的文件系统是 FAT (或 FAT16),Windows 2000 以后的版本有所谓的 NTFS 文件系统,至于 Linux 的正统文件系统则为 Ext2X(Linux second extended file system,ext2fs)这一个。此外,在默认的情况下,Windows 操作系统是不会认识 Linux 的 ExtX 的。

引导块

MBR 做的第一件事就是确定活动分区,读入它的第一个块,称为引导块(boot block)并执行。引导块中的程序将加载分区中的操作系统。为了一致性,每个分区都会从引导块开始,即使引导块不包含操作系统。引导块占据文件系统的前 4096 个字节,从磁盘上的字节偏移量 0 开始。引导块可用于启动操作系统。

在计算机中,引导就是启动计算机的过程,它可以通过硬件(例如:按下电源按钮)或者软件命令的方式来启动。开机后,电脑的 CPU 还不能执行指令,因为此时没有软件在主存中,所以一些软件必须先被加载到内存中,然后才能让 CPU 开始执行。也就是计算机开机后,首先会进行软件的装载过程。

空闲空间块

可以用位图或者指针列表的形式标识。

  • 位图(Bit Map)或位向量(Bit Vector):是一系列位或位的集合,其中每个位对应一个磁盘块,该位可以采用两个值 0 和 1:0 表示已分配该块;而 1 表示一个空闲块。下图中的磁盘上给定的磁盘块实例(分配了绿色块)可以用 16 位的位图表示为:0000111000000110。
    Linux 操作系统原理 — 文件系统 — 存储布局_Linux 操作系统原理_02
  • 使用链表进行管理:在这种方法中,空闲磁盘块链接在一起,即一个空闲块包含指向下一个空闲块的指针。第一个磁盘块的块号存储在磁盘上的单独位置,也缓存在内存中。
    Linux 操作系统原理 — 文件系统 — 存储布局_Linux 操作系统原理_03

inode 区块、data block 区块与超级块

文件系统是如何运行的与操作系统的文件数据有关。较新的操作系统的文件数据除了文件的实际数据外,通常还包含了非常多的属性,例如:Linux 操作系统的文件权限(rwx)与文件属性(拥有者、群组、时间参数等)。

Linux 的文件系统 ExtX 主要将硬盘分区划分为了超级块、inode 区块和 data block 区块空间。权限与属性放置到 inode 区块中,至于实际数据则放置到 data block 区块中。 另外,还有一个超级区块(Super block)会记录整个文件系统的整体信息,包括 inode 与 block 的总量、使用量、剩余量等等。一个文件由一个超级块、inode 和 data block 组成。当查看某个文件时,会先从inode table中查出文件属性及数据存放点,再从数据块中读取数据。

Linux 操作系统原理 — 文件系统 — 存储布局_Linux 操作系统原理_04

  • 超级块:这是整个文件系统的第一块空间。紧跟在引导块后面的是超级块(Super Block),超级块的大小为 4096 字节,从磁盘上的字节偏移 4096 开始。超级块包含了整个文件系统的所有关键参数,例如:文件系统的大小、inode、data block 区块的总量、使用量、剩余量,指向空间 inode 和数据块的指针等相关信息。在计算机启动或者文件系统首次使用时,超级块会被读入内存。

  • inode 块:作为文件系统中某个文件的索引节点,记录了文件的属性。它是文件系统的最基本单元,是文件系统连接任何子目录、任何文件的桥梁。每个子目录和文件只有唯一的一个 inode 块,文件的属性也存在 inode 记录中。它包含了文件系统中文件的基本属性,例如:模式/权限(保护)、所有者 ID、组 ID、文件大小、文件的硬链接数、上次访问时间、最后修改时间、inode 上次修改时间。硬连接和源文件具有相同的 inode 。

ls -i fileName	# 查看文件的 inode 号
  • data block 块:记录文件的实际内容。每个 block 都有一个编号,大小为 4k-16k,是在格式化时确定,由 inode 号来记录 block 在磁盘中存储的位置。若文件太大时,会占用多个 block,为了提高目录访问效率,Linux 还提供了表达路径与 inode 对应关系的 Dentry(目录项)结构,包括了各种目录信息,还指向了 inode 和超级块。

就像一本书有封面、目录和正文一样。在文件系统中,超级块就相当于封面,从封面可以得知这本书的基本信息;inode 块相当于目录,从目录可以得知各章节内容的位置;而数据块则相当于书的正文,记录着具体内容。

我们将 inode 与 data block 区块用图解来说明一下,如下图所示,文件系统先格式化出 inode 与 data block 的区块,假设某一个文件的属性与权限数据是放置到 inode 4 号(下图较小方格内),而这个 inode 记录了文件数据的实际放置点为 2, 7, 13, 15 这四个 data block 号码,此时我们的操作系统就能够据此来排列磁盘的阅读顺序,可以一口气将四个 block 内容读出来。那么数据的读取就如同下图中的箭头所指定的模样了。

Linux 操作系统原理 — 文件系统 — 存储布局_Linux_05
这种数据存取的方式称为索引式文件系统(Indexed Allocation)。区别于闪存,闪存使用的文件系统一般为 FAT 格式。FAT 这种格式的文件系统并没有 inode 存在,所以 FAT 没有办法将这个文件的所有 data block 在一开始就读取出来。每个 data block 号码都记录在前一个 data block 当中, 其读取方式有点像下图所示:

Linux 操作系统原理 — 文件系统 — 存储布局_Linux_06

可见,FAT 文件系统中,如果同一个文件数据写入的 data block 分散的太过厉害,则磁盘读取头将无法在磁盘转一圈就读到所有的数据, 因此磁盘就会多转好几圈才能完整的读取到这个文件的内容。

对比两者常见的一种常见就是 “碎片整理”:需要碎片整理的原因就是文件写入的 data block 太过于离散了,此时文件读取的效能将会变的很差所致。这个时候可以透过碎片整理将同一个文件所属的 data blocks 汇整在一起,这样数据的读取会比较容易啊。可见,FAT 的文件系统需要经常的碎片整理一下的。相对的,因为 ExtX 是索引式文件系统,所以基本上不太需要常常进行碎片整理。但是如果文件系统使用太久了,常常删除/编辑/新增文件时,那么还是可能会造成文件数据太过于离散的问题,此时或许会需要进行重整一下的,但很少见。

LVM 与 RAID

在传统的磁盘与文件系统的应用中,一个分区就是只能够被格式化成为一中类型的文件系统,所以我们可以说一个 Filesystem 就是一个 Partition。但是随着新技术的发展,例如:LVM 与软件磁盘阵列(Software RAID), 这些技术可以将一个分区格式化为多个相同或不同类型的文件系统(e.g. LVM),也能够将多个分区合成一个文件系统(e.g. LVM、RAID)。所以说,目前我们在格式化时已经不再说:针对某个 Partition 来格式化了,而是称呼一个可被挂载的数据盘设备为一个文件系统。

LVM 逻辑卷管理

  1. 把物理分区初始化为物理卷
pvcreate /dev/sdX1 /dev/sdb1
pvs  # 查看物理卷,还可以使用 pvdisplay、pvscan
  1. 创建卷组 :把物理卷分组,卷组的最小存储单位是 PE,默认 PE 的大小为 4M。
vgcreate 卷组名 /dev/sdX1 /dev/sdb1  
vgs		# 查看卷组vgdisplay、vgscan 
vgcreate -s xM 卷组名 /dev/sdX1 /dev/sdb1		# 创建VG并指定PE大小
  1. 建立逻辑卷
lvcreate -L 容量 卷组名 -n 逻辑卷名 
lvcreate -l PE的个数 卷组名 -n 逻辑卷名  
lvs  # 查看逻辑卷大小 lvdisplay、lvscan
  1. 格式化
mkfs.xfs /dev/卷组名/逻辑卷名
  1. 挂载
mount /dev/卷组名/逻辑卷名  /挂载点
  • vg 的扩展:
 vgextend  卷组名    物理卷
  • vg 的缩小
vgreduce     卷组名    物理卷
  • vg 的改名
 vgrename   老的卷组名  新的卷组名
  • vg 的迁移
 vgexport  #导出,vg 在导出前要停止 vg 的使用 
 vgchange -an 卷组名
 vgimport   #导入
  • lv 扩展
lvextend -L 5500M /dev/myvg1/mylv
xfs_growfs /dev/myvg1/mylv   

NOTE:XFS 格式的 LVM 卷都只能增大,不能缩小。而 Ext4 格式的 LVM 卷可以增大/缩小。

  • lv的缩小
umount  #卸载
resize2fs  /dev/extvg/extlv  500M   
lvreduce  -L 500M /dev/extvg/extlv
mount   # 重新挂载
  • LVM 的修复
vgcfgrestore -l  卷组名
vgcfgrestore -f 文件名  卷组名 
lvchange -an /dev/卷组名/逻辑卷名
lvchange -ay /dev/卷组名/逻辑卷名
  • LVM 的快照
lvcreate -L 10M -n mys1 -s /dev/extvg/extlv   #创建
lvconvert --merge  /dev/extvg/mys1   #还原,还原后快照消失

RAID 磁盘阵列

  • 软 RAID:用操作系统实现的冗余 消耗 CPU、内存

  • 硬 RAID:用服务器上的 RAID 卡实现的冗余(有 CPU、内存)

RAID 类型:

  • RAID0 条带化:至少 2 块磁盘,优点:写速度快;缺点:没有冗余。

  • RAID1 镜像:至少 2 个磁盘,优点:提高了冗余;缺点:写的速度没有提升,磁盘的使用率 1/N。

  • RAID5 条带冗余:至少 3 块硬盘,优点:提高了冗余性,同时提高了写的速度。缺点:修改数据速度慢 磁盘的使用率 N-1/N。

建立 RAID

mdadm -C /dev/mdX -a yes -l 级别 -n 磁盘的数量  /dev/sdb1    /dev/sdc1   
mkfs.xfs  /dev/mdX  
mount /dev/mdX /123

停止 RAID

mdadm -S /dev/md1   

恢复 RAID

 mdadm -As /dev/md1