5. Linux中磁盘管理--文件系统

349 阅读16分钟

本系列都是是基于RedHat体系的,所以CentOS也可以用,但是Debian系列的可能会有些命令上的出入。

1. 简介

  1. 磁盘类型:
    • 机械硬盘:盘片、磁头、转轴、控制电机
    • 固态硬盘:SSD
  2. 硬盘尺寸(宽度)
    • 2.5英寸
    • 3.5英寸
  3. 接口
    • 插头
    • IDE/SATA
    • 串口/并口
    • 慢/快
    • 老/新
  4. 转速(只有机械硬盘)
    • 每分钟旋转的速度(rpm)
    • 5400r/m
    • 7200r/m
    • 15000r/m
  5. 厂商
    • 西部数据
    • 希捷
  6. 术语(磁盘非固态)
    • 柱面
    • 盘片
    • 磁道:同心圆
    • 扇面
    • 扇区,每个扇区512字节
  7. 命名:计算机自动命名
    • SATA口:/dev/sda /dev/sdb,是一个文件
    • /dev:设备文件目录,
    • s:SATA口 | SCSI口 | USB口,h:IDE口 | ATA口
    • d:disk
    • a b:第一、二块
    • 分区继续编号1, 2, 3... /dev/sda1 /dev/sda2
  8. 分区方式
    • MBR:主引导启动记录(Master Boot Record)位于磁盘最前边的一段引导,占据512字节
      • 前446字节放Boot Loader,引导操作系统的启动;
      • 64字节每16字节标识一个分区,最多支持4个分区;
      • 最后2字节是Magic Number,一定是55AA是分区结束标志;
      • 支持的最大的容量<2TB;
      • 超过4个分区,需要放弃主分区,改为3个逻辑分区和1个扩展分区。
    • GPT:统一分区表(GUID Partition Table)
      • 支持超过2TB的容量
      • 支持128个分区

2. 管理磁盘

2.1 查看磁盘信息

买来磁盘插入,管理之前先查看磁盘的信息。而系统会自动给新插入的磁盘命名,这个不用手动命名。

一个磁盘分区由四个字符组成,前三个字符sd<a>代表是哪块磁盘,最后一个数字代表是哪一块分区。最前面权限前面的b代表是块block设备。

$ ll /dev/sd*				# 查看磁盘信息
brw-rw---- 1 root disk 8, 0 1月   6 11:29 /dev/sda
brw-rw---- 1 root disk 8, 1 1月   6 11:29 /dev/sda1
brw-rw---- 1 root disk 8, 2 1月   6 11:29 /dev/sda2
brw-rw---- 1 root disk 8, 5 1月   6 11:29 /dev/sda5

$ lsblk						# 列出块设备
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0     11:0    1 1024M  0 rom
sda      8:0    0   40G  0 disk
├─sda2   8:2    0    1K  0 part
├─sda5   8:5    0  958M  0 part [SWAP]
└─sda1   8:1    0 39.1G  0 part /
sr1     11:1    1 1024M  0 rom

$ fdisk -l [/dev/sda]

2.2 分区

fdisk指MBR格式分区。gdisk指GPT格式分区。

# fdisk常用子命令
m:help
p:print,查看当前分区信息
n:new 
d:delete
w:save & quit
q:quit
l:查看分区类型信息
t:type,调整分区类型
	L:查看分区的编号

:warning: 请记住,下面操作适合新加硬盘分区,如果是有东西的磁盘,会损坏原有文件。请谨慎操作!!!​​

  1. 创建分区

    $ fdisk /dev/sdb
    欢迎使用 fdisk (util-linux 2.23.2)。
    
    更改将停留在内存中,直到您决定将更改写入磁盘。
    使用写入命令前请三思。
    
    Device does not contain a recognized partition table 
    使用磁盘标识符 0xe99ad669 创建新的 DOS 磁盘标签。
    
    命令(输入 m 获取帮助): n 					# add a new partition
    Partition type:
       p	primary(0 primary, 0 extended, 4 free)
       e	extended
    Select (default p): p
    分区号 (1-4, 默认 1): 1
    起始 扇区 (2048-10485759), 默认为 2048) : 	# 主分区的范围,单位是512Bytes,即一个扇区是512字节。扇区编号从0开始。这里默认即可,即直接回车,0-2047放的是MBR,记录每个分区信息。
    last 扇区, +扇区 or +size{K,M,G} (2048-10485759, 默认为 10485749) : +2G # 这里直接使用这种+nG就可以了。
    分区 1 已设置为 Linux 类型, 大小设为 2 GiB
    
    命令(输入 m 获取帮助): w 				   # 真的要去做分区了,w之后就会真的创建分区
    The partition table has been altered!
    
    Calling ioctl() to re- read partition table.
    正在同步磁盘。
    
  2. 刷新下分区信息,让内核知道有了新的分区并读取。内核已知的分区位于/proc/partitions文件中,可以查看。有时候partprobe也不好使,就需要重新启动计算机了。RHEL 6.x还支持partx命令刷新,重读分区表。

    # 不写参数则是读取整个分区表
    $ partprobe [/dev/sdb] # 分区准备,partition probe,就是刷新下证明分区做好了
    
  3. 查看分区。会发现已经对/dev/sdb做好了一个分区:/dev/sdb1

    $ fdisk -l /dev/sdb
    磁盘 /dev/sdb: 5366 MB, 5368709210 字节, 10485760 个扇区
    Units = 扇区 or 1 * 512 = 512 bytes
    扇区大小(逻辑/物理): 512 字节 / 512 字节
    I/O大小(最小/最佳): 512 字节 / 512 字节
    磁盘标签类型: dos
    磁盘标识符: 0xe99ad669
    
    设备 Boot	   Start	End 	Blocks	Id	System
    /dev/sdb1	2048	 4196351 2097152 83	 Linux
    
    $ lsblk
    NAME			MAJ:MIN	RM	SIZE	RO	TYPE	MOUNTPOINT
    sda			  	  8:0	 0	 20G	 0	disk	
    |-sda1		  	  8:1	 0    1G     0  part	/boot
    |-sda2        	  8:2    0   19G     0  part
     |-centos-root	253:0    0   17G     0  lvm     /
     |-centos-swap  253:1    0    2G     0  lvm     [SWAP]
    sdb               8:16   0    5G     0  disk  
    |-sdb1            8:17   0    2G     0  part 
    

2.2 格式化

创建好的分区需要格式化之后才能使用,也就是创建文件系统,这里是高级格式化,低级格式化是在出厂的时候就已经做好了。

查看当前内核所支持的文件系统:cat /proc/filesystems

创建文件系统的命令有:mke2fsmkfsmkfs.ext4。其中mkfs.ext4 == mkfs -t ext4后续有关文件系统的命令查看下述文件系统小节

# $ mke2fs [option] [/dev/sdb1] 							# 专门管理EXT类型的文件系统。
#     -j创建EXT3+类型的文件系统
#     -b指定块大小,默认为4096,可用取值1024、2048或4096
#	  -L指定卷标,即分区名称
#     -m指定为超级用户保留的区块大小的百分比,不需要写%,默认是5%
#     -i指定多少个字节一个inode,默认是8192bytes/inode
#     -N指定总共可创建的inode个数
#     -F指定强制创建文件系统
#     -E用户指定额外文件系统属性

# make file system extend4
# 创建    文件系统   扩展系统:是文件系统的类型
# /dev/sdb1 第2块串口硬盘的第一个分区准备格式化了
# $ mkfs.ext4 /dev/sdb1
$ mkfs -t ext4 /dev/sdb1 									# 和上一条命令一样,只是-t指定类型
mke2fs 1.42.9 (28-Dec-2013)
文件系统标签=
OS type: Linux
块大小=4096(log=2)
分块大小=4096(log=2)
Stride=0 blocks, Stripe width=0 blocks
131072 inodes, 524288 blocks
25214 blocks (5.00%) reserved for the super user
第一个数据块=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912
        
Allocating group tables: 完成
正在写入inode表: 完成
Creating journal (16384 blocks): 完成							# 日志功能
Writing superblocks and filesystem accounting information: 完成

This filesystem will be automatically checked every 20 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

2.3 挂载与卸载

挂载就是给创建好的文件系统寻找一个入口。

$ mkdir /mnt/disk1

# 设备可以用:设备文件、LABEL="LABLE_NAME"、UUID="UUID"
# 挂载点要求目录需要事先存在,此目录没有被其它进程使用,目录原有文件将会被暂时屏蔽。
# 没有参数:显示当前系统已经挂载的设备以及挂载点
#      -a:表示挂载/etc/fstab文件中定义的所有文件系统
# 	   -n:默认情况下,mount命令每挂载一个设备,都会把挂载的设备信息保存到/etc/mtab文件,-n表示静默不把信息写入此文件
#      -t:指定要挂载的文件系统类型,可以不指定,mount会自动调用blkid命令获取文件系统类型
#	   -r:只读挂载,挂载光盘常用此选项
# 	   -w:读写挂载,默认挂载方式
#      -o:指定额外的挂载选项,即指定文件系统启用的属性
#        async:异步写入,默认
#        atime:每次更新inode时间戳。调优时最好关闭,noatime
#        auto,可以使用-a选项挂载
#        defaults:rw, suid, dev, exec, auto, nouser, and async
# 		 dev:当前文件系统有其它设备文件系统就启用
# 		 exec:允许二进制文件有执行权限的执行,对于U盘最后不要指定
# 		 _netdev:网络设备映射到本地,网络不可用将可以自动跳过。挂载网络设备时有用
# 		 owner:使得普通非root用户但设备拥有者可以挂载文件系统。同时使用nosuid和nodev
# 		 remount:重新挂载,此时不指定挂载点就挂载在原挂载点
# 		 ro:只读挂载
# 		 rw:读写挂载
# 		 sync:同步方式挂载
# 		 suid:不安全,尽量nosuid
#		 loop:挂载本地回环设备,例如*.iso文件。
# 		 --bind
# 		 --move:
$ mount [options] [-o options] [DEVICE] [MOUNT_POINT]

$ mount [-t ext4] /dev/sdb1 /mnt/disk1
$ df -hT 								# -h人类友好,-T显示类型
Filesystem  Type    Size  	Used 	Avail 	Use% 	Mounted on
/dev/sda1   ext4     39G     32G     4.9G    87%    /
/dev/sdb1	ext4	2.0G	6.0M	 1.8G	  1%	/mnt/disk1

# 卸载要求没有被任何进程使用,否则显示device is busy
$ umount /mnt/disk1					# 卸载,挂载的反向操作

挂载前/mnt/disk1使用的是原来的磁盘,但是挂载之后,将会使用新的磁盘空间,即/dev/sdb1。但是这种挂载的方式,只会本次生效,下次开机就不会在了。如果要永久挂载需要写入到/etc/fstab文件中。

挂载点会屏蔽掉原有目录下的文件和目录,测试如下:

# 1. 先在 /mnt/sda3 目录下创建5个文件
root@basil:/mnt/sda3# ls
file1  file2  file3  file4  file5

# 2. 挂载/dev/sda4到/mnt/sda3
root@basil:/mnt/sda3# mount /dev/sda4 /mnt/sda3

# 3. 再次查看/mnt/sda3目录下的文件
root@basil:/mnt/sda3# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 465.8G  0 disk
├─sda1   8:1    0   200M  0 part /boot/efi
├─sda2   8:2    0  59.2G  0 part
├─sda3   8:3    0   598M  0 part
├─sda4   8:4    0 143.4G  0 part /mnt/sda3
└─sda5   8:5    0 262.4G  0 part /
sr0     11:0    1  1024M  0 rom
root@basil:/mnt/sda3# ls /mnt/sda3
'$RECYCLE.BIN'   DevSft   Document   Download   DTLFolder   ProgramFiles  'System Volume Information'

# 4. 卸载/dev/sda4
root@basil:/mnt/sda3# umount /mnt/sda3

# 5. 再次查看/mtn/sda3
root@basil:/mnt/sda3# ls /mnt/sda3
file1  file2  file3  file4  file5

卸载的时候有时候一直提示device is busy,可以通过fuser -v查看正在使用该文件系统的文件和套接字文件。

$ fuser -v /mnt/swapfile
                     USER        PID ACCESS COMMAND
/mnt/swapfile:       root     kernel swap  /mnt/swapfile

# 杀死进程:终止正在访问此挂载点的所有进程
$ fuser -km /mnt/swapfile

# 再次卸载
$ umount /mnt/swapfile

2.4 相关/etc/下文件

  1. /etc/fstab

    是文件系统的配置文件。OS在开机初始化时,会自动挂载此文件中定义的每个文件系统。其格式是:设备 挂载点 文件系统类型 挂载选项 转储频率(没多少天做一次完全备份,0不备份,1每天,2每2天,...) 文件系统检测次序(只有根为1,0表示不检查)。设备可以用设备目录、UUID、卷标来指定。mount -a可以挂载定义在该文件的所有文件系统。

    $ cat /etc/fstab
    # /etc/fstab: static file system information.
    #
    # Use 'blkid' to print the universally unique identifier for a device; this may
    # be used with UUID= as a more robust way to name devices that works even if
    # disks are added and removed. See fstab(5).
    #
    # <file system>             <mount point>  <type>  <options>  <dump>  <pass>
    UUID=C14D-581B                            /boot/efi      vfat    umask=0077 0 2
    UUID=5938cf13-d43f-4f50-bdbe-3b8349413419 /              ext4    defaults   0 1
    /mnt/swapfile 							  swap 			 swap 	 defaults 	0 0
    

    其中修改挂载options对应的可以在defaults后面加上","继续添加,如defaults,acl

  2. /etc/mtab:文件系统挂载后的相关信息会写入/etc/mtab,挂载时使用mount -n将不会写入该文件。

3. 逻辑卷LVM

3.1 MBR

MBR(Master Boot Record)主引导启动记录,位于0磁道的0扇区的512字节,不属于操作系统,属于磁盘自己。

  • 前446字节放Boot Loader,引导操作系统的启动;
  • 64字节每16字节标识一个分区,最多支持4个分区,所以最大支持2TB的磁盘;
  • 最后2字节是Magic Number,一定是55AA是分区结束标志。

对于上面一个5G磁盘,继续划分后续3GB的空间,需要重新进行上面的步骤,但是实际进行操作的时候,需要一次性划分完毕。

要是需要超过4个分区,需要放弃一个主分区,采用扩展分区,即n之后选择e,extend分区。主分区和扩展分区在存储数据的时候没有区别,但是主分区才能装系统,而扩展分区不能安装系统。

MBR位于磁盘的0柱面0磁头l扇区处,其中前446字节存储Boot Loader信息,中间64bytes用来存储分区信息,以及其起始扇区号,后2字节存储MBR是。这里只能存储这么多分区。而为了扩展,用户需要放弃一块主分区(一般是最后一块主分区),设置为扩展分区,扩展分区不能存放数据。该扩展分区,再次划分,即为逻辑分区,逻辑分区才能存放数据。

最佳实践:一块硬盘使用MBR方式划分分区,数量上选择:

  • 4个主分区
  • 3个主分区+1个扩展分区(N个逻辑分区)

3.2 逻辑分区

扩展分区一定占用4号分区。

如果已经画好了4个分区,需要在fdist /dev/sdb中删除一个分区(第4个分区,如有数据做好备份)。

$ fdisk /dev/sdb
命令(输入 m 获取帮助): p

磁盘 /dev/sdb: 5368 MB, 5368709120 字节, 10485760 个扇区
Units = 扇区 or 1 * 512 = 512 bytes
扇区大小(逻辑/物理): 512 字节 / 512 字节
I/O大小(最小/最佳): 512 字节 / 512 字节
磁盘标签类型: dos
磁盘标识符: 0xe99ad669

Device Boot	   		Start			End 	 Blocks		Id		System
/dev/sdb1	  		 2048	 	4196351 	2097152 	83	 	 Linux
/dev/sdb2 		  4196352       4605951      204800     83       Linux
/dev/sdb3 		  4605952       5015551      204800     83       Linux

命令(输入 m 获取帮助): d
分区号(1-4, 默认 4): 4
分区 4 已删除

命令(输入 m 获取帮助): n
Partition type:
   p	primary(0 primary, 0 extended, 4 free)
   e	extended
Select (default p): e
已选择分区 4
起始 扇区 (5015552-10485759), 默认为 5015552) : 
将使用默认值 5015552
last 扇区, +扇区 or +size{K,M,G} (5015552-10485759, 默认为 10485749) : # 因为没有分区号了,所以这里一定需要回车,不然后续也没法使用了
分区 4 已设置为 Extended 类型, 大小设为 2.6 GiB

命令(输入 m 获取帮助): n # 但是扩展分区不能直接挂载,需要继续划分逻辑分区
All primary partitions are in use
添加逻辑分区 5
起始 扇区 (5017600-10485759), 默认为 5017600) : 
将使用默认值 5017600
last 扇区, +扇区 or +size{K,M,G} (5017600-10485759, 默认为 10485749) : +200M
分区 5 已设置为 Linux 类型,大小设为 200 MiB

命令(输入 m 获取帮助): n # 但是扩展分区不能直接挂载,需要继续划分逻辑分区
All primary partitions are in use
添加逻辑分区 6
起始 扇区 (5429248-10485759), 默认为 5429248) : 
将使用默认值 5429248
last 扇区, +扇区 or +size{K,M,G} (5429248-10485759, 默认为 10485749) :
分区 6 已设置为 Linux 类型,大小设为 2.4 GiB

命令(输入 m 获取帮助): p

磁盘 /dev/sdb: 5368 MB, 5368709120 字节, 10485760 个扇区
Units = 扇区 or 1 * 512 = 512 bytes
扇区大小(逻辑/物理): 512 字节 / 512 字节
I/O大小(最小/最佳): 512 字节 / 512 字节
磁盘标签类型: dos
磁盘标识符: 0xe99ad669

Device Boot	   		Start			End 	 Blocks		Id		System
/dev/sdb1	  		 2048	 	4196351 	2097152 	83	 	 Linux
/dev/sdb2 		  4196352       4605951      204800     83       Linux
/dev/sdb3 		  4605952       5015551      204800     83       Linux
/dev/sdb4		  5015552      10485759     2735104      5    Extended
/dev/sdb5		  5840896       6252543      204800     83       Linux
/dev/sdb6         6252544      10485759     2530304     83       Linux
命令(输入 m 获取帮助): w  # 已经不能继续划分了
$ partprobe /dev/sdb
$ lsblk
$ mkfs -t ext4 /dev/sdb3 # 不能挂载/dev/sdb4因为它就只有500B是逻辑分区信息,逻辑分区同样挂载,但是就不能挂在/dev/sdb4
$ mount -t ext4 /dev/sdb3 /mnt/disk3
$ df -hT

3.3 逻辑卷管理

传统方式下不同的磁盘之间不能混用。即一个超级大的文件(如单个蓝光电影)要跨磁盘存储不可行,即磁盘A和磁盘B剩余空间大于这个文件,但是单个磁盘的空间不足够。物理磁盘的空间是固定的,不便于管理(拷贝、删除、授权)。

逻辑卷(LVM,logic volume manager)是管理磁盘的一种方式,它的特点是随意扩展磁盘的大小,不限制。基本磁盘的过程是购买物理磁盘之后,进行分区、格式化、挂载,LVM的过程是买来物理磁盘之后,变成物理卷,加入卷组,在卷组中抽调空间制作逻辑卷,再格式化、挂载。

术语:

  1. 物理卷,physical volume,PV
  2. 卷组,volume group,VG
  3. 逻辑卷,logic volume,LV
# 1. 买磁盘
# 2. 创建物理卷,把磁盘插入然后转为物理卷
# pvcreate 磁盘位置
$ pvcreate /dev/sdf
 Physical volume "/dev/sdf" successfully created.
# 3. 创建卷组
# vgcreate 卷组名 物理卷
$ vgcreate vg1 /dev/sdf
 Volume group "vg1" successfully created.
# 4. 创建逻辑卷,必须从卷组名称去拿空间
# lvcreate -L 大小 -n 逻辑卷名 卷组
$ lvcreate -L 200M -n lv1 vg1
 Logical volume "lv1" created.
# 5. 格式化
# 先卷组名后逻辑卷名
$ mkfs.ext4 /dev/vg1/lv1
# 6. 挂载
$ mount /dev/vg1/lv1 /mnt/lv1
# 7. 验证
$ df -hT

接下来进行扩容。

# 1. 创建物理卷
$ pvcreate /dev/sdg
# 查看物理卷
$ pvs
PV	 		VG		Fmt		Attr 	PSize		PFree
/dev/sdf	vg1		lvm2	a--		<5.00g		1020.00m
/dev/sdg			lvm2	---		<5.00g		5.00g		# 还没有加入卷组
# 2. 加入卷组(扩展)
# vgextend 卷组名 物理卷
$ vgextend vg1 /dev/sdg 
# 查看卷组
$ vgs
VG		#PV		#LV		#SN		Attr	VSize	VFree
vg1		2		1		0		wz--n-	9.99g	5.99g

# 3. lv扩容(逻辑卷扩容)
$ lvextend -L +4G /dev/vg1/lv1

# 4. fs扩容(文件系统扩容)
$ resize2fs /dev/vg1/lv1
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/vg1/lv1/ is mounted on /mnt/lv1; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/vg1/lv1 is now 2097152 blocks long.

不要轻易卸载磁盘,否则会出现问题,如果一定需要卸载磁盘,则需要反着来。

4. 交换分区管理SWAP

4.1 简介

物理内存分页(page frame)进行管理,虚拟地址使得程序以为自己可以使用完整的内存空间,OS自动完成虚拟地址和物理地址的映射关系。

SWAP就是一个普通的分区,防止OOM(Out Of Memory),可以“提升”内存容量,其实就是虚拟内存,只不过Linux换了叫法。经常需要使用的数据就可以放到交换分区,可以提升数据的读取速度。

Linux有物理内存就不会使用交换分区。

:star:最佳实践

  1. 一般SWAP的空间是物理内存的2倍。
  2. 大于4GB小于16GB内存的系统,最小需要4GB的交换分区;
  3. 大于16GB小于64GB内存的系统,最小需要8GB的交换分区;
  4. 大于64GB小于256GB内存的系统,最小需要16GB的交换分区;

4.2 创建交换分区

4.2.1 使用空闲磁盘

这里使用的是新的磁盘或者一份不再使用的磁盘分区。

$ free -m
              total        used        free      shared  buff/cache   available
Mem:           3782        1523         243          95        2015        1882
Swap:             0           0           0

Linux系统下磁盘设备的类型主要使用(fdist /dev/sdcm显示帮助,L显示类型,t更换类型)

  • 82:Linux Swap
  • 83:Linux
  • 85:Linux Extend
  • 8e:LVM
# 1. 创建SWAP分区
$ fdisk /dev/sdc

命令(输入 m 获取帮助): n
Partition type:
   p	primary(0 primary, 0 extended, 4 free)
   e	extended
Select (default p): p
分区号(1-4, 默认 1) : 
起始 扇区 (2048-10485759), 默认为 2048) : 
将使用默认值 2048
Last 扇区, +扇区 or +size{K,M,G} (2048-10485759, 默认为 10485749) : +2G
分区 1 已设置为 Linux 类型, 大小设为 2 GiB

命令(输入 m 获取帮助): t  			# 更改分区的类型,这个可以不改,也就是不需要下面的82
已选择分区 1
Hex 代码(输入 L 列出所有代码): 82    # 使用的是82代表的是 Linux 交换分区,这里一定需要修改!!!
已将分区"Linux"的类型更改为"Linux swap / Solaris"

命令(输入 m 获取帮助): w			# 保存即可

$ partprobe /dev/sdc
$ ll /dev/sdc*

# 2. 格式化,创建SWAP文件系统
$ mkswap /dev/sdc1				# 格式化,创建文件系统
正在设置交换空间版本 1, 大小 = 2097148 KiB
无标签, UUID=51bd294d-7fb1-49c7-8807-696d74b3b74b

# 3. 挂载
# -a:启用所有定义在/etc/fstab中的交换设备
$ swapon /dev/sdc1				# 挂载swap分区
$ swapoff /dev/sdc1				# 卸载swap分区

# 4. 验证现在的交换分区
$ free -m						# -m表示以Mb为单位查看

4.2.2 使用本地回环文件

参考这个Linux SWAP分区和虚拟内存。临时救急还行,正常使用性能差。

# 1. 创建一个由连续空间的swap文件
# 如备份MBR数据:dd if=/dev/sda of=/mnt/usb/mbr.backup bs=512 count=1
# 如还原MBR数据:dd if=/mnt/usb/mbr.backup of=/dev/sda bs=512 count=1
# dd:用于复写命令,类似cp命令,但是cp以文件为单位,dd是流数据,可以只复制文件的某些字节
#   if=/src:复写的是哪里的信息,这里是/dev/zero是一个全0文件,就是0
#   of=/dst:写到哪里去,这里是/mnt下的swapfile文件,swapfile为自己创建,这个路径也可以换成别的
#   bs=#:block size,就是块大小,这里是1MB
#   count=#:复写次数,count * bs ≈ 4GB
#   seek=#:从哪里开始,之前的都跳过了。
$ dd if=/dev/zero of=/mnt/swapfile bs=4M count=1000
1000+0 records in
1000+0 records out
4194304000 bytes (4.2 GB, 3.9 GiB) copied, 93.8471 s, 44.7 MB/s

# 2. 创建Linux swapfile
$ mkswap /mnt/swapfile 	# 可以使用LABLE="SWAP_FILE_LABLE"来指定卷标
Setting up swapspace version 1, size = 3.9 GiB (4194299904 bytes)
no label, UUID=6bd404bf-620e-432a-9544-7e09081496fe

# 3. 激活swap文件,到这里已经可以使用了
$ swapon /mnt/swapfile

# 4. 验证启用情况,-m表示以MB为单位
$ free -m
              total        used        free      shared  buff/cache   available
Mem:           3782        1564         119          95        2098        1849
Swap:          3999           0        3999

但是下次开机又没有了,所以需要写入/etc/fstab文件,其中包括文件的名字和swap类型:

# 写入/etc/fstab
echo "/mnt/swapfile swap swap defaults 0 0" >> /etc/fstab

校验下swap文件是否加上

$ swapon -s

删除类似于磁盘的

# 1. 取消swapfile
$ swapoff /mnt/swapfile
# 2. 编辑/etc/fstab文件,去掉此swap文件对应记录
# 3. 删除该swapfile
$ rm /mnt/swapfile

5. 文件系统

文件系统是需要OS内核操作的。

格式化的过程是创建文件系统,EXT4将4096字节(4KB)作为一个block。挂载是给磁盘找到一个入口。

每个磁盘分区都是一个文件系统,在Linux中最后都挂载到根目录/下。

文件系统分类

  • Windows:FAT16,FAT32,NTFS,CIFS(网络),光盘:ISO9660
  • Linux: VFAT,EXT2,EXT3,EXT4(索引型文件系统),XFS,reiserfs,jfs,jfs2,nfs(网络),ocfs(集群),gfs2
    • Linux为了支持众多的文件系统类型,对其又进行了一次封装,称为VFS(Virtual File System),对应用程序提供统一接口来管理文件。

EXT2和EXT3+的区别:

  • EXT3/EXT4也叫做日志文件系统(journal file system)。磁盘分为了:元数据区、数据区和日志区。修复文件的时候需要查找日志区,缩减了开机检查时间,但是需要多读多写一次inode到日志区。
  • EXT2的完整性不高,但是速度很快。

5.1 Linux文件系统重要概念

首先声明,下面是EXT类型的文件系统,是Linux常用的文件系统,不同的文件系统类型,管理方式有所不同。

5.1.1 块

Linux OS存储数据的时候,分开存储块的可用性和块内容,每个块4KB。块的可用性使用**块位图(bitmap)**标识,1为占用,0为可用。块block是具体存储信息的,而索引是如何快速找到空闲块(可用块)及已占用的块(不可用块),块是最基本的存储单位,一个块是4KB,10KB的文件占用的是3个块,而不能用的2KB不能被其他文件信息占用,这也就产生了文件碎片。

5.1.2 inode

文件的元数据和文件的内容分开存放。文件的元数据存储在inode(index node,索引节点),占用128字节,有一个唯一的inode编号,引用一个文件,有对应的属主属组,文件权限,时间戳,连接数,文件大小(一个文件系统会指明单个文件最大的大小。),所在块数量和编号,但是没有文件名。inode的可用性使用inode位图进行管理。Linux中目录也是一个文件,存储inode号以及对应的文件名,每一条称为一个d-entry,创建文件和删除文件都相当于操作d-entry

一个EXT4文件系统中可能的inode位图样式:

image.png

现在EXT3和EXT4类型的文件系统支持最大16TB,XFS文件系统支持最大100TB。mkfs [-t ext4]执行过多少次,计算机就有多少个文件系统。

# 查看文件的inode编号
$ ls -li 1
3698361 -rw-rw-r-- 1 basil basil 12769 12月 27 17:29 1

df -i可以查看inode的总数量、已经使用的数量以及未使用的数量。如果inode使用完毕了,则将不能继续在该磁盘创建文件。但是只要磁盘还有空间(block),仍然可以向其中写入数据,如果block被占用完了,inode也占用完了,则不能继续向该磁盘写入数据。

5.1.3 超级块和块组

磁盘管理中,把一个分区继续划分为block group块组,然后Super Block存储这些块组的基本信息元数据。Super Block是索引和块的结合体,代表的是block和inode的总量:未使用的与已使用的inode和block数量。举例就是超市门口的储物柜,索引就是显示器给配发的小条,箱子就是块,而一整套储物柜就是一个superblock。块组描述符表用来存储块组的信息。

每个分区第一个块(编号为0),预留出来作为Boot Block引导块,多系统共存的时候有必要用到,被MBR中的Boot Loader调用,各自引导不同系统启动。后续块进行划分为块组。如下格式存储:

image.png

  • Super Block不一定每个块组都有,需要备份,但是不需要所有块组都备份
  • GDT: Group Description Table,块组描述符表,存储块组信息,需要备份

5.2 相关操作

5.2.1 创建文件系统

创建文件系统的命令有:mke2fsmkfsmkfs.ext4。其中mkfs.ext4 == mkfs -t ext4

  1. mke2fs

    $ mke2fs [option] [/dev/sdb1] 							# 专门管理EXT类型的文件系统。
    #     -j创建EXT3+类型的文件系统
    #     -b指定块大小,默认为4096,可用取值1024、2048或4096
    #	  -L指定卷标,即分区名称
    #     -m指定为超级用户保留的区块大小的百分比,不需要写%,默认是5%
    #     -i指定多少个字节一个inode,默认是8192bytes/inode
    #     -N指定总共可创建的inode个数
    #     -F指定强制创建文件系统
    #     -E用户指定额外文件系统属性
    
  2. mkfs

    # make file system extend4
    # 创建    文件系统   扩展系统:是文件系统的类型
    # /dev/sdb1 第2块串口硬盘的第一个分区准备格式化了
    # $ mkfs.ext4 /dev/sdb1
    $ mkfs -t ext4 /dev/sdb1 									# 和上一条命令一样,只是-t指定类型
    

5.2.1 文件系统信息

  1. 查看创建好的文件系统

    $ blkid [/dev/sdb]										# 查询文件系统的属性
    #     UUID
    #     TYPE
    #     LABEL
    /dev/sda5: UUID="5938cf13-d43f-4f50-bdbe-3b8349413419" TYPE="ext4" PARTUUID="1a370aa8-6503-ae4c-b0ab-16498612443c"
    
    $ e2label [/dev/sdb] [lable name]                         # 查看或者定义卷标 
    
  2. 文件系统的相关属性

    $ tune2fs /dev/sda5										# 调整文件系统的相关属性,不需要重新格式化
    #   -j:不损害原有数据,将ext2升级为ext3,反过来降级不行
    #   -L LABEL:设定卷标label
    #   -m #:调整预留给超级用户的百分比
    #   -r #:指定预留块数
    #   -o:设定默认挂载选项,常用的是acl
    #	-c #:设定多少次挂载后自检,0或-1表示关闭此功能
    # 	-i #:每挂载多少天后自检,0或-1表示关闭此功能
    # 	-l: 显示超级块中的信息
    # 	-C:
    
    $ dumpe2fs /dev/sda5 									# 显示文件属性信息
    #   -h:只显示超级块信息
    

5.2.3 修复文件系统

:warning:下述命令有些适用于CentOS 6,有些适用于CentOS 7,不同的类型系统命令可能不同。

$ fsck /dev/sda5										# 检查并修复文件系统
#   -t:FS_TYPE:指定文件系统,千万不要指定错了,不指定系统会自动检测。
#   -a:自动修复,不会询问

$ e2fsck /dev/sda5										# 专门修复EXT文件系统
#   -p:自动修复
#   -f:强制检测

5.3 文件链接

5.3.1 软链接(符号链接)

symbol link,符号链接,类似于Windows中的快捷方式。在d-entry中存储的不是文件名和inode,而是文件名和另一个文件路径。需要根据此路径再查找文件。

$ ln -s /src/path  /dst/path							 # -s代表的是符号链接
root@basil-2020:/home/basil# ll /proc/1/fd				 # 下面只看标准的输入输出
lrwx------ 1 root root 64 1月   8 09:30 0 -> /dev/null	# 标准输入
lrwx------ 1 root root 64 1月   8 09:30 1 -> /dev/null	# 标准输出
lrwx------ 1 root root 64 1月   8 09:30 2 -> /dev/null	# 标准错误输出

这里权限之前的l代表的就是这是一个链接文件。

修改源文件,查看符号链接文件也随之而改变,修改符号链接文件,源文件也被修改(其实本来就是一个文件)。

删除符号链接不影响源文件,删除源文件,符号链接也将失去作用。

软链接可以跨分区(文件系统)。

软链接不影响链接数,就是ll中第2列。

软链接可以对文件和目录做软链接。

其大小指定的是路径所包含的字符个数。

其权限和最终要访问的文件权限不一定一致,最终访问权限取决于最终文件的权限。

5.3.2 硬链接

指向同样的inode编号的不同文件路径。

$ ln /src/path /dst/path								# 和符号链接只差一个 -s

硬链接不能跨分区,只能在同一分区做硬链接。

硬链接会修改链接数。只有当链接数为1并且再次删除的时候才能完全删除该文件。

硬链接不能对目录来做,只能对文件做。

子目录数越多,硬链接越多。

6. RAID(廉价磁盘冗余阵列)

6.1 简介

RAID,Redundant Array of Independent Disks,用于容错和提升读写速度。级别仅代表磁盘组织方式不同,没有上下之分。

RAID0,RAID0是条带集,需要2块磁盘以上,主要用于读写速率快100%*N,就是可以并发写入。但是不能容错。(不重要的数据

RAID1,俗称镜像卷或者镜像集,只需要两块硬盘(最好是容量一致),读性能上升(可以交替读),写性能下降,同时写入相同数据,最终空间利用率是50%,读写速率一般,主要是为了容错。(操作系统

RAID2

RAID3

RAID4

RAID5,带有奇偶校验。至少三块硬盘(最好容量一致),N块硬盘只有(N-1)块存储具体数据,另一块用于存储奇偶校验和(另外一般还有一块硬盘作为热备盘)。坏一块可以找到出错的数据并恢复,两块坏就恢复不了了。空间利用率是(N-1)/N,读写性能都有提升,也用于容错。(重要数据

10: 性能表现:读、写提升 冗余能力:有 空间利用率:1/2 至少需要4块 01: 性能表现:读、写提升 冗余能力:有 空间利用率:1/2 至少需要4块 50:

​ 性能表现:读、写提升 ​ 冗余能力:有 ​ 空间利用率:(n-2)/n ​ 至少需要6块 jbod: ​ 性能表现:无提升 ​ 冗余能力:无 ​ 空间利用率:100% ​ 至少需要2块

6.2 不同场景

  • 硬RAID:需要RAID卡,有自己的CPU,处理速度快,有电池和无电池。
  • 软RAID:通过操作系统实现,例如Windows、Linux。是逻辑RAID,md代表multi disks。尽量减少使用

mdadm模式化的命令

  • 创建模式

    • -C,后面的专用选项
    • -l:级别
      • -n #: 设备个数
      • -a {yes|no}: 是否自动为其创建设备文件
      • -c: CHUNK大小, 2^n,默认为64K
      • -x #: 指定空闲盘个数
  • 管理模式

    • --add, --remove, --fail
    • mdadm /dev/md# --fail /dev/sda7
  • 监控模式

    • -F
  • 增长模式

    • -G
  • 装配模式

    • -A

cat /proc/mdstat查看RAID信息。

# 创建RAID,支持将任何块设备作为RAID
#        创建        RAID名字   级别       RAID数量      热备数量    要使用的磁盘
# mdadm -C(reate)	RAID名字   -l(evel)   -n(umber)    热备数量    要使用的磁盘,也可以分开写出/dev/sdb, /dev/sdc, /dev/sdd, /dev/sde
# 需要将磁盘分区指定为fd类型,即Linux raid autodetect,fdisk时使用t和L。
$ mdadm -C 			/dev/md0   -l5       -n3          -x1         /dev/sd{b,c,d,e}
# 格式化(创建文件系统)
$ mkfs.ext4 /dev/md0
# 挂载
$ mount /dev/md0 /mnt/raid5
# 验证,如果使用的4块磁盘都是相同1G的数量,这里就只会看到只有2G可用,因为1G奇偶校验,1G热备。
$ df -hT
# 查看
# -D(etail),查看详细信息
$ mdadm -D 			/dev/md0
/dev/md0:
           Version: 1.2
     Creation Time: Mon Feb 24 11:56:42 2020
        Raid Level: raid5
        Array Size: 2095104 (2046.00 MiB 2145.39 MB)
     Used Dev Size: 1047552 (1023.00 MiB 1072.69 MB)
      Raid Devices: 3
     Total Devices: 4
       Persistence: Superblock is persistent
       
       Update Time: Mon Feb 24 11:59:14 2020
             State: clean
    Active Devices: 3
   Working Devices: 4
    Failed Devices: 0
     Spare Devices: 1
     
            Layout: left-symmetric
        Chunk Size: 512K
        
Consistency Policy: resync

              Name: localhost.localdomain:0 (local to host localhost. localdomain)
              UUID: 96105589:ef4bbbf2:8efa4eac:ab2240e4
            Events: 18
   Number   Major   Minor   RaidDevice  State
   0		8		16		0			active sync /dev/sdb								# 数据组
   1		8		16		1			active sync /dev/sdc								# 数据组
   4		8		16		2			active sync /dev/sdd								# 数据组

   3		8		64		-			spare /dev/sde										# 热备组

强制移除磁盘:mdadm /dev/md0 -f /dev/sdb -r /dev/sdb

参考资料

  1. inode structure in EXT4 filesystem