掘金 后端 ( ) • 2024-04-23 10:42

linux存储与磁盘管理相关

整理自linux就该这么学

1. linux 目录

1.1 目录树

Linux系统中的一切文件都是从“根”目录(/)开始的,并按照文件系统层次标准(FHS)采用倒树状结构来存放文件,以及定义了常见目录的用途。

1.2 目录名称及用途

Linux系统中常见的目录名称以及相应内容:

目录名称 应放置文件的内容 /boot 开机所需文件—内核、开机菜单以及所需配置文件等 /dev 以文件形式存放任何设备与接口 /etc 配置文件 /home 用户主目录 /bin 存放单用户模式下还可以操作的命令 /lib 开机时用到的函数库,以及/bin与/sbin下面的命令要调用的函数 /sbin 开机过程中需要的命令 /media 用于挂载设备文件的目录 /opt 放置第三方的软件 /root 系统管理员的家目录 /srv 一些网络服务的数据文件目录 /tmp 任何人均可使用的“共享”临时目录 /proc 虚拟文件系统,例如系统内核、进程、外部设备及网络状态等 /usr/local 用户自行安装的软件 /usr/sbin Linux系统开机时不会使用到的软件/命令/脚本 /usr/share 帮助与说明文件,也可放置共享文件 /var 主要存放经常变化的文件,如日志 /lost+found 当文件系统发生错误时,将一些丢失的文件片段存放在这里

1.3 绝对路径与相对路径

绝对路径指的是从根目录(/)开始写起的文件或目录名称,而相对路径则指的是相对于当前路径的写法。

2. 物理设备命名规则

在Linux系统中一切都是文件,硬件设备也不例外。既然是文件,就必须有文件名称。系统内核中的udev设备管理器会自动把硬件名称规范起来,目的是让用户通过设备文件的名字可以猜出设备大致的属性以及分区信息等;这对于陌生的设备来说特别方便。另外,udev设备管理器的服务会一直以守护进程的形式运行并侦听内核发出的信号来管理/dev目录下的设备文件。

常见的硬件设备及其文件名称:

硬件设备 文件名称 IDE设备 /dev/hd[a-d] SCSI/SATA/U盘 /dev/sd[a-z] virtio设备 /dev/vd[a-z] 软驱 /dev/fd[0-1] 打印机 /dev/lp[0-15] 光驱 /dev/cdrom 鼠标 /dev/mouse 磁带机 /dev/st0 或 /dev/ht0

由于现在的IDE设备已经很少见了,所以一般的硬盘设备都是以“/dev/sd”开头。而一台主机上可以有多块硬盘,因此系统采用a~z来代表26块不同的硬盘(默认从a开始分配),而且硬盘的分区编号也很有讲究:

主分区或扩展分区的编号从1开始,到4结束;

逻辑分区从编号5开始。

两个常见误区:

  1. 误区1: /dev/sda表示主板上第一个插槽上的存储设备。

实际上/dev目录中sda设备之所以是a,并不是由插槽决定的,而是由系统内核的识别顺序来决定的,而恰巧很多主板的插槽顺序就是系统内核的识别顺序,因此才会被命名为/dev/sda。在使用iSCSI网络存储设备时就会发现,明明主板上第二个插槽是空着的,但系统却能识别到/dev/sdb这个设备—就是这个道理。

  1. 误区2: 对分区名称的理解错误,分区的编号代表分区的个数,比如sda3表示这是设备上的第3个分区

实际上分区的数字编码不一定是强制顺延下来的,也有可能是手工指定的。因此sda3只能表示是编号为3的分区,而不能判断sda设备上已经存在了3个分区。


硬盘用于存放数据。硬盘设备是由大量的扇区组成的,每个扇区的容量为512字节。其中第一个扇区最重要,它里面保存着主引导记录与分区表信息。就第一个扇区来讲,主引导记录需要占用446字节,分区表占用64字节,结束符占用2字节;其中分区表中每记录一个分区信息就需要16字节,这样一来最多只有4个分区信息可以写到第一个扇区中,这4个分区就是4个主分区。

为了解决分区个数不够的问题,可以将第一个扇区的分区表中16字节(原本要写入主分区信息)的空间(称之为扩展分区)拿出来指向另外一个分区。也就是说,扩展分区其实并不是一个真正的分区,而更像是一个占用16字节分区表空间的指针—一个指向另外一个分区的指针。 这样一来,用户一般会选择使用3个主分区加1个扩展分区的方法,然后在扩展分区中创建出数个逻辑分区,从而来满足多分区(大于4个)的需求。

Tips 所谓扩展分区,严格地讲它不是一个实际意义的分区,而仅仅是一个指向其他分区的指针,这种指针结构将形成一个单向链表。因此扩展分区自身不能存储数据,用户需要在其指向的对应分区(称之为逻辑分区)上进行操作。

主分区、扩展分区、逻辑分区规划:

3. 文件系统

3.1 常见文件系统类型

Linux有多种文件系统,每个文件系统都有其特点和用途。以下是Ext2、Ext3、Ext4和XFS的区别与联系:

  1. Ext2: 是Linux的第二代扩展文件系统,最早发布于1993年。它是非日志文件系统,数据丢失可能性较大。在系统崩溃后需要使用fsck等工具手动修复。适合在不需要日志的环境下使用。

  2. Ext3: 是Ext2的升级版,引入了日志机制,减少了崩溃后文件系统修复的时间和复杂性。支持多种日志模式,包括数据日志和元数据日志,增加了数据的可靠性。ext3会把整个硬盘的每个写入动作的细节都预先记录下来,然后再进行实际操作,以便在发生异常宕机后能回溯追踪到被中断的部分。Ext3能够在系统异常宕机时避免文件系统资料丢失,并能自动修复数据的不一致与错误。然而,当硬盘容量较大时,所需的修复时间也会很长,而且也不能100%地保证资料不会丢失。

  3. Ext4: Ext4是Ext3的继承者,带来了许多改进,最大支持1EB容量(1EB=1,073,741,824GB)、延迟分配、块预分配、支持64位文件、文件系统碎片减少等。它还提供更好的性能和可靠性。另外,Ext4文件系统能够批量分配block(块),从而极大地提高了读写效率。现在很多主流服务器也会使用Ext4文件系统。

  4. XFS: 是一种高性能的日志文件系统,支持大文件和高并发。是RHEL 7/8中默认的文件管理系统。它提供了高可扩展性和良好的性能,并具有强大的碎片整理和数据完整性特性。它的优势在发生意外宕机后尤其明显,即可以快速地恢复可能被破坏的文件,而且强大的日志功能只需花费极低的计算和存储性能。XFS适用于大规模数据存储和高负载应用,支持的最大存储容量为18EB

总的来说,Ext2适合不需要日志功能的小型系统,Ext3和Ext4适用于一般Linux系统,Ext4提供更好的性能和功能。XFS则更适用于大型数据存储和高性能场景。

Tips:

18EB等于18,874,368TB。假设每块硬盘的容量是100TB,那么大概需要19万块硬盘才能把18EB的数据都装下。当用了XFS之后,文件的存储上限就不再取决于技术层面。

3.2 inode与block

3.2.1 inode

inode是"index node"的缩写,每个文件和目录都有一个inode,包含了与文件有关的元数据,如文件权限、所有者、文件大小、时间戳、指向文件数据的指针等。inode不包含文件名,文件名保存在目录结构中,并通过目录项与inode相关联。

Linux只是把每个文件的权限与属性记录在inode中,而且每个文件占用一个独立的inode表格,该表格的大小默认为128字节,里面记录着如下信息:

  • 该文件的访问权限(read、write、execute);
  • 该文件的所有者与所属组(owner、group);
  • 该文件的大小(size);
  • 该文件的创建或内容修改时间(Ctime);
  • 该文件的最后一次访问时间(Atime);
  • 该文件的修改时间(Mtime);
  • 文件的特殊权限(SUID、SGID、SBIT);
  • 该文件的真实数据地址(point)。

inode的大小可以根据文件系统的配置和版本而有所不同。在Linux文件系统中,常见的文件系统,如ext4,允许在创建文件系统时指定inode的大小。典型的inode大小是128字节、256字节或512字节,但可能会根据具体的文件系统和需要调整。较大的inode提供了更多空间来存储元数据信息,但也会增加文件系统的整体开销。较小的inode可能节省空间,但在包含额外的扩展属性时可能受到限制。

要查看文件系统的inode大小,您可以使用tune2fs或dumpe2fs或xfs_info等命令查看文件系统的相关信息。

# ext3,ext4文件系统查看
tune2fs -l /dev/sdX | grep "Inode size"

# xfs文件系统查看
xfs_info /dev/vda1

3.2.2 block

block是存储实际文件数据的最小单位。一个文件可能由多个block组成。

文件的实际内容则保存在block块中(大小一般是1KB、2KB或4KB),一个inode的默认大小仅为128字节,记录一个block则消耗4字节。当文件的inode被写满后,Linux系统会自动分配出一个block,专门用于像inode那样记录其他block块的信息,这样把各个block块的内容串到一起,就能够让用户读到完整的文件内容了。

对于存储文件内容的block块,有下面两种常见的情况(以4KB大小的block为例进行说明):

  • 情况1:文件很小(1KB),但依然会占用一个block,因此会潜在地浪费3KB。
  • 情况2:文件很大(5KB),那么会占用两个block(5KB−4KB后剩下的1KB也要占用一个block)。

3.3 VFS

计算机系统在发展过程中产生了众多的文件系统,为了使用户在读取或写入文件时不用关心底层的硬盘结构,Linux内核中的软件层为用户程序提供了一个虚拟文件系统(Virtual File System,VFS)接口,这样用户实际上在操作文件时就是统一对这个虚拟文件系统进行操作了。

VFS的架构示意图:

4. 磁盘分区、格式化及挂载

4.1 分区

fdisk命令用于新建、修改及删除磁盘的分区表信息。

参数 作用 m 查看全部可用的参数 n 添加新的分区 d 删除某个分区信息 l 列出所有可用的分区类型 t 改变某个分区的类型 p 查看分区表信息 w 保存并退出 q 不保存直接退出
# 
[root@linuxprobe ~]# fdisk /dev/sdb

Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x88b2c2b0.

# 打印分区信息
Command (m for help): p
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x88b2c2b0

# 创建主分区
Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p

# 设置分区编号,起止扇区或者根据容量大小划分分区
Partition number (1-4, default 1): 1
First sector (2048-41943039, default 2048): 此处敲击回车即可
Last sector, +sectors or +size{K,M,G,T,P} (2048-41943039, default 41943039): +2G

Created a new partition 1 of type 'Linux' and of size 2 GiB.

# 查看分区信息
Command (m for help): p
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x88b2c2b0

Device     Boot Start     End Sectors Size Id Type
/dev/sdb1        2048 4196351 4194304   2G 83 Linux

# 写入分区表
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

# 分区信息中第6个字段的Id值是一个编码,用于标识该分区的作用,可帮助用户快速了解该分区的作用,一般没必要修改。
# 使用l参数查看一下磁盘编码都有哪些,然后在6.6节进行SWAP操作时再修改吧:
Command (m for help): l  

 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris        
 1  FAT12           27  Hidden NTFS Win 82  Linux swap / So c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  84  OS/2 hidden or  c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     85  Linux extended  c7  Syrinx         
 5  Extended        41  PPC PReP Boot   86  NTFS volume set da  Non-FS data    
 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility   
 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt         
 9  AIX bootable    4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access     
 a  OS/2 Boot Manag 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O        
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor      
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi ea  Rufus alignment
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         eb  BeOS fs        
 f  W95 Ext'd (LBA) 54  OnTrackDM6      a6  OpenBSD         ee  GPT            
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        ef  EFI (FAT-12/16/
11  Hidden FAT12    56  Golden Bow      a8  Darwin UFS      f0  Linux/PA-RISC b
12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f1  SpeedStor      
14  Hidden FAT16 <3 61  SpeedStor       ab  Darwin boot     f4  SpeedStor      
16  Hidden FAT16    63  GNU HURD or Sys af  HFS / HFS+      f2  DOS secondary  
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fb  VMware VMFS    
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fc  VMware VMKCORE 
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fd  Linux raid auto
1c  Hidden W95 FAT3 75  PC/IX           bc  Acronis FAT32 L fe  LANstep        
1e  Hidden W95 FAT1 80  Old Minix       be  Solaris boot    ff  BBT   

保存后,可以输入partprobe命令手动将分区信息同步到内核:

[root@linuxprobe ]# file /dev/sdb1
/dev/sdb1: cannot open `/dev/sdb1' (No such file or directory)
[root@linuxprobe ]# partprobe
[root@linuxprobe ]# partprobe
[root@linuxprobe ]# file /dev/sdb1
/dev/sdb1: block special

4.2 格式化

如果硬件存储设备没有进行格式化,则Linux系统无法得知怎么在其上写入数据。因此,在对存储设备进行分区后还需要进行格式化操作。在Linux系统中用于格式化操作的命令是mkfs。

[root@linuxprobe ~]# mkfs
mkfs         mkfs.ext2    mkfs.ext4    mkfs.minix   mkfs.vfat    
mkfs.cramfs  mkfs.ext3    mkfs.fat     mkfs.msdos   mkfs.xfs

[root@linuxprobe ~]# mkfs.xfs /dev/sdb1
meta-data=/dev/sdb1              isize=512    agcount=4, agsize=131072 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=524288, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

4.3 挂载

格式化后挂载才能使用文件系统,mount命令用于挂载文件系统,格式为“mount文件系统 挂载目录”。

[root@linuxprobe ~]# mkdir /newFS
[root@linuxprobe ~]# mount /dev/sdb1 /newFS
[root@linuxprobe ~]# df -h
Filesystem             Size  Used Avail Use% Mounted on
devtmpfs               969M     0  969M   0% /dev
tmpfs                  984M     0  984M   0% /dev/shm
tmpfs                  984M  9.6M  974M   1% /run
tmpfs                  984M     0  984M   0% /sys/fs/cgroup
/dev/mapper/rhel-root   17G  3.9G   14G  23% /
/dev/sr0               6.7G  6.7G     0 100% /media/cdrom
/dev/sda1             1014M  152M  863M  15% /boot
tmpfs                  197M   16K  197M   1% /run/user/42
tmpfs                  197M  3.5M  194M   2% /run/user/0
/dev/sdb1              2.0G   47M  2.0G   3% /newFS

推荐用UUID(Universally Unique Identifier,通用唯一识别码)进行挂载操作。UUID是一串用于标识每块独立硬盘的字符串,具有唯一性及稳定性,特别适合用来挂载网络设备。

blkid命令用于显示设备的属性信息,例如:blkid sdb

mount b6d19903-8bfa-4301-9ce8-ca3ac36804a6 /mnt

4.4 挂载信息写入

将磁盘挂载信息写/etc/fstab,否则系统重启后挂载就会失效。

cat /etc/fstab
...
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=b6d19903-8bfa-4301-9ce8-ca3ac36804a6 /boot                   xfs     defaults        0 0
/dev/mapper/centos-home /home                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0
/dev/cdrom                                /media/cdrom   iso9660    defaults       0 0
字段 意义 设备文件 一般为设备的路径+设备名称,也可以写唯一识别码(UUID,Universally Unique Identifier) 挂载目录 指定要挂载到的目录,需在挂载前创建好 格式类型 指定文件系统的格式,比如Ext3、Ext4、XFS、SWAP、iso9660(此为光盘设备)等 权限选项 若设置为defaults,则默认权限为:rw, suid, dev, exec, auto, nouser, async 是否备份 若为1则开机后使用dump进行磁盘备份,为0则不备份 是否自检 若为1则开机后自动进行磁盘自检,为0则不自检

写入到/etc/fstab文件中的设备信息并不会立即生效,需要使用mount -a命令进行自动挂载.

对于网络存储设备,建议您在fstab文件挂载信息中加上_netdev参数。加上后系统会等联网成功后再尝试挂载这块网络存储设备,从而避免了开机时间过长或失败的情况:

[root@centos~]# vim /etc/fstab
...
/dev/mapper/rhel-root                       /              xfs       defaults            0 0
UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b   /boot          xfs       defaults            0 0
/dev/mapper/rhel-swap                       swap           swap      defaults            0 0
/dev/lun1                                   /backup        ext4      defaults,_netdev    0 0
/dev/cdrom                                  /media/cdrom   iso9660   defaults            0 0

4.5 常用命令

通过df -Th,lsblk -f, du -sh /*等命令查看目录挂载等信息。

5. 交换分区

Swap分区,即交换分区,是Linux系统中的一种特殊分区。它类似于Windows的虚拟内存,主要用于在物理内存(RAM)不足时,将一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。当系统需要更多的内存空间时,会把内存中暂时不用的数据移到Swap分区中,以便为其他程序腾出内存空间。

5.1 创建Swap分区

  1. 查看当前的Swap分区情况

使用free命令可以查看当前系统中是否已有Swap分区以及Swap分区的使用情况。

  1. 使用dd命令创建Swap分区

假设我们想要创建一个2G大小的Swap分区,可以使用以下命令:

dd if=/dev/zero of=/path/to/swapfile bs=1M count=2048

这里的/path/to/swapfile是Swap分区的文件路径,可以根据你的需求进行修改。bs=1M表示每次写入1M的数据,count=2048表示写入2048次,总共就是2G的数据。

除了可以使用文件作为swap分区,也可以使用物理分区作为swap分区:

# 修改硬盘的标识码,这里将其改成82(Linux swap)
Command (m for help): t
Partition number (1,2, default 2): 2
Hex code (type L to list all codes): 82

Changed type of partition 'Linux' to 'Linux swap / Solaris'.

Command (m for help): p 
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x88b2c2b0

Device     Boot   Start      End  Sectors Size Id Type
/dev/sdb1          2048  4196351  4194304   2G 83 Linux
/dev/sdb2       4196352 14682111 10485760   5G 82 Linux swap / Solaris
  1. 格式化Swap分区

使用mkswap命令对刚才创建的文件进行格式化:

mkswap /path/to/swapfile
  1. 激活Swap分区

使用swapon命令激活Swap分区:

swapon /path/to/swapfile

激活后,你可以再次使用free命令查看Swap分区是否已经被成功添加并使用。

  1. 关闭Swap分区

如果你需要关闭Swap分区,可以使用swapoff命令:

swapoff /path/to/swapfile
  1. 保存设置使其永久生效

为了让Swap分区在系统重启后仍然生效,你需要在/etc/fstab文件中添加相应的设置。使用文本编辑器打开/etc/fstab文件,并添加如下一行:

/path/to/swapfile swap swap default 0 0

这样,当系统启动时,就会自动挂载并激活这个Swap分区。

5.2 注意事项

  • 在创建Swap分区时,需要确保选择的磁盘空间足够大,并且有足够的I/O性能。
  • Swap分区的大小应该根据系统的实际需求来设定。一般来说,Swap分区的大小可以设置为物理内存的1~2倍。
  • 虽然Swap分区可以解决内存不足的问题,但是频繁地使用Swap分区会导致系统性能下降,因为硬盘的I/O速度远低于内存。因此,在可能的情况下,还是应该尽量增加物理内存。

6. 磁盘容量配额

root管理员就需要使用磁盘容量配额服务来限制某位用户或某个用户组针对特定文件夹可以使用的最大硬盘空间或最大文件个数,一旦达到这个最大值就不再允许继续使用。可以使用quota技术进行磁盘容量配额管理,从而限制用户的硬盘可用容量或所能创建的最大文件个数。quota技术还有软限制和硬限制的功能。

软限制:当达到软限制时会提示用户,但仍允许用户在限定的额度内继续使用。 硬限制:当达到硬限制时会提示用户,且强制终止用户的操作。

RHEL 8系统中已经安装了quota磁盘容量配额服务程序包,但存储设备却默认没有开启对quota技术的支持,此时需要手动编辑配置文件并重启一次系统,让系统中的启动目录(/boot)能够支持quota磁盘配额技术。

[root@linuxprobe ~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Tue Jul 21 05:03:40 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/rhel-root                        /             xfs        defaults         1 1
UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b    /boot         xfs        defaults,uquota  1 2
/dev/mapper/rhel-swap                        swap          swap       defaults         0 0
/dev/cdrom                                   /media/cdrom  iso9660    defaults         0 0 
/dev/sdb1                                    /newFS        xfs        defaults         0 0 
/dev/sdb2                                    swap          swap       defaults         0 0 
[root@linuxprobe ~]# reboot

对于学习过早期的Linux系统,或者具有RHEL 5/6系统使用经验的读者来说,这里需要特别注意。早期的Linux系统要想让硬盘设备支持quota磁盘容量配额服务,使用的是usrquota参数,而RHEL 7/8系统使用的则是uquota参数。在重启系统后使用mount命令查看,即可发现/boot目录已经支持quota磁盘配额技术了:

[root@linuxprobe ~]# mount | grep boot
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,usrquota)

接下来创建一个用于检查quota磁盘容量配额效果的用户tom,并针对/boot目录增加其他人的写权限,保证用户能够正常写入数据

[root@linuxprobe ~]# useradd tom
[root@linuxprobe ~]# chmod -R o+w /boot

xfs_quota命令用于管理设备的磁盘容量配额,语法格式为“xfs_quota [参数] 配额 文件系统”。

这是一个专门针对XFS文件系统来管理quota磁盘容量配额服务而设计的命令。其中,-c参数用于以参数的形式设置要执行的命令;-x参数是专家模式,让运维人员能够对quota服务进行更多复杂的配置。接下来使用xfs_quota命令来设置用户tom对/boot目录的quota磁盘容量配额。具体的限额控制包括:硬盘使用量的软限制和硬限制分别为3MB和6MB;创建文件数量的软限制和硬限制分别为3个和6个。

[root@linuxprobe ~]# xfs_quota -x -c 'limit bsoft=3m bhard=6m isoft=3 ihard=6 tom' /boot
[root@linuxprobe ~]# xfs_quota -x -c report /boot
User quota on /boot (/dev/sda1)
                               Blocks                     
User ID          Used       Soft       Hard    Warn/Grace     
---------- -------------------------------------------------- 
root           114964          0          0     00 [--------]
tom                 0       3072       6144     00 [--------]

上面所使用的参数分为两组,分别是isoft/ihard与bsoft/bhard。在Linux系统中每个文件都会使用一个独立的inode信息块来保存属性信息,一个文件对应一个inode信息块,所以isoft和ihard就是通过限制系统最大使用的inode个数来限制了文件数量。bsoft和bhard则是代表文件所占用的block大小,也就是文件占用的最大容量的总统计。

soft是软限制,超过该限制后也只是将操作记录写到日志中,不对用户行为进行限制。而hard是硬限制,一旦超过系统就会马上禁止,用户再也不能创建或新占任何的硬盘容量。

当配置好上述各种软硬限制后,尝试切换到一个普通用户,然后分别尝试创建一个体积为5MB和8MB的文件。可以发现,在创建8MB的文件时受到了系统限制:

[root@linuxprobe ~]# su - tom
[tom@linuxprobe ~]$ cd /boot
[tom@linuxprobe boot]$ dd if=/dev/zero of=/boot/tom bs=5M count=1
1+0 records in
1+0 records out
5242880 bytes (5.2 MB, 5.0 MiB) copied, 0.00298178 s, 1.8 GB/s
[tom@linuxprobe boot]$ dd if=/dev/zero of=/boot/tom bs=8M count=1
dd: error writing '/boot/tom': Disk quota exceeded
1+0 records in
0+0 records out
4194304 bytes (4.2 MB, 4.0 MiB) copied, 0.00398607 s, 1.1 GB/s

edquota命令用于管理系统的磁盘配额,英文全称为“edit quota”,语法格式为“edquota [参数] 用户名”。

在为用户设置了quota磁盘容量配额限制后,可以使用edquota命令按需修改限额的数值。其中,-u参数表示要针对哪个用户进行设置;-g参数表示要针对哪个用户组进行设置。

edquota命令中可用的参数以及作用:

参数 作用 -u 对某个用户进行设置 -g 对某个用户组进行设置 -p 复制原有的规则到新的用户/组 -t 限制宽限期限

edquota命令会调用vi或vim编辑器来让root管理员修改要限制的具体细节,记得用wq保存退出。下面把用户tom的硬盘使用量的硬限额从5MB提升到8MB:

[tom@linuxprobe ~]$ exit
[root@linuxprobe ~]# edquota -u tom
Disk quotas for user tom (uid 1001):
  Filesystem                   blocks       soft       hard     inodes     soft     hard
  /dev/sda1                      4096       3072       8192          1        3        6
[root@linuxprobe ~]# su - tom
[tom@linuxprobe ~]$ cd /boot
[tom@linuxprobe boot]$ dd if=/dev/zero of=/boot/tom bs=8M count=1
1+0 records in
1+0 records out
8388608 bytes (8.4 MB, 8.0 MiB) copied, 0.0185476 s, 452 MB/s

7. VDO虚拟数据优化

VDO(Virtual Data Optimize,虚拟数据优化)是一种通过压缩或删除存储设备上的数据来优化存储空间的技术。VDO是红帽公司收购了Permabit公司后获取的新技术,并与2019-2020年前后,多次在RHEL 7.5/7.6/7.7上进行测试,最终随RHEL 8系统正式公布。VDO技术的关键就是对硬盘内原有的数据进行删重操作,它有点类似于我们平时使用的网盘服务,在第一次正常上传文件时速度特别慢,在第二次上传相同的文件时仅作为一个数据指针,几乎可以达到“秒传”的效果,无须再多占用一份空间,也不用再漫长等待。除了删重操作,VDO技术还可以对日志和数据库进行自动压缩,进一步减少存储浪费的情况。VDO针对各种类型文件的压缩效果如表所示。

对各种类型文件压缩效果汇总表:

文件名 描述 类型 原始大小(KB) 实际占用空间(KB) dickens 狄更斯文集 英文原文 9953 9948 mozilla Mozilla的1.0可执行文件 执行程序 50020 33228 mr 医用resonanse图像 图片 9736 9272 nci 结构化的化学数据库 数据库 32767 10168 ooffice Open Office.org 1.01 DLL 可执行程序 6008 5640 osdb 基准测试用的MySQL格式示例数据库 数据库 9849 9824 reymont 瓦迪斯瓦夫·雷蒙特的书 PDF 6471 6312 samba samba源代码 src源码 21100 11768 sao 星空数据 天文格式的bin文件 7081 7036 webster 辞海 HTML 40487 40144 xml XML文件 HTML 5220 2180 x-ray 透视医学图片 医院数据 8275 8260

VDO技术支持本地存储和远程存储,可以作为本地文件系统、iSCSI或Ceph存储下的附加存储层使用。红帽公司在VDO介绍页面中提到,在部署虚拟机或容器时,建议采用逻辑存储与物理存储为10∶1的比例进行配置,即1TB物理存储对应10TB逻辑存储;而部署对象存储时 (例如使用Ceph)则采用逻辑存储与物理存储为3∶1的比例进行配置,即使用1TB物理存储对应3TB逻辑存储。

简而言之,VDO技术能省空间!

有两种特殊情况需要提前讲一下。其一,公司服务器上已有的dm-crypt之类的技术是可以与VDO技术兼容的,但记得要先对卷进行加密再使用VDO。因为加密会使重复的数据变得有所不同,因此删重操作无法实现。要始终记得把加密层放到VDO之下,如图所示。

其二,VDO技术不可叠加使用,1TB的物理存储提升成10TB的逻辑存储没问题,但是再用10TB翻成100TB就不行了。左脚踩右脚,真的没法飞起来。

RHEL/CentOS 8系统中默认已经启用了VDO技术。VDO技术现在是红帽公司自己的技术,兼容性自然没得说。如果您所用的系统没有安装VDO的话可以用dnf命令即可完成安装:

[root@linuxprobe ~]# dnf install kmod-kvdo vdo
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Last metadata expiration check: 0:01:56 ago on Wed 06 Jan 2021 10:37:19 PM CST.
Package kmod-kvdo-6.2.0.293-50.el8.x86_64 is already installed.
Package vdo-6.2.0.293-10.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!

首先,创建一个全新的VDO卷。

新添加进来的物理设备就是使用vdo命令来管理的,其中name参数代表新的设备卷的名称;device参数代表由哪块磁盘进行制作;vdoLogicalSize参数代表制作后的设备大小。依据红帽公司推荐的原则,20GB硬盘将翻成200GB的逻辑存储:

[root@linuxprobe ~]# vdo create --name=storage --device=/dev/sdc --vdoLogicalSize=200G
Creating VDO storage
Starting VDO storage
Starting compression on VDO storage
VDO instance 0 volume is ready at /dev/mapper/storage

在创建成功后,使用status参数查看新建卷的概述信息:

[root@linuxprobe ~]# vdo status --name=storage
VDO status:
  Date: '2021-01-06 22:51:33+08:00'
  Node: linuxprobe.com
Kernel module:
  Loaded: true
  Name: kvdo
  Version information:
    kvdo version: 6.2.0.293
Configuration:
  File: /etc/vdoconf.yml
  Last modified: '2021-01-06 22:49:33'
VDOs:
  storage:
    Acknowledgement threads: 1
    Activate: enabled
    Bio rotation interval: 64
    Bio submission threads: 4
    Block map cache size: 128M
    Block map period: 16380
    Block size: 4096
    CPU-work threads: 2
    Compression: enabled
    Configured write policy: auto
    Deduplication: enabled
    ...

有上可见,在输出信息中包含了VDO卷创建的时间、主机名、版本、是否压缩(Compression)及是否删重(Deduplication)等关键信息。

接下来,对新建卷进行格式化操作并挂载使用。

新建的VDO卷设备会被乖乖地存放在/dev/mapper目录下,并以设备名称命名,对它操作就行。另外,挂载前可以用udevadm settle命令对设备进行一次刷新操作,避免刚才的配置没有生效:

[root@linuxprobe ~]# mkfs.xfs /dev/mapper/storage 
meta-data=/dev/mapper/storage    isize=512    agcount=4, agsize=13107200 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=52428800, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=25600, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@linuxprobe ~]# udevadm settle
[root@linuxprobe ~]# mkdir /storage
[root@linuxprobe ~]# mount /dev/mapper/storage /storage

如果想查看设备的实际使用情况,使用vdostats命令即可。human-readable参数的作用是将存储容量自动进位,以人们更易读的方式输出(比如,显示20G而不是20971520K):

[root@linuxprobe ~]# vdostats --human-readable
Device                    Size      Used Available Use% Space saving%
/dev/mapper/storage      20.0G      4.0G     16.0G  20%           99%

这里显示的Size是实际物理存储的空间大小(即20.0GB是硬盘的大小),如果想看逻辑存储空间,可以使用df命令进行查看:

[root@linuxprobe ~]# df -h
Filesystem             Size  Used Avail Use% Mounted on
devtmpfs               969M     0  969M   0% /dev
tmpfs                  984M     0  984M   0% /dev/shm
tmpfs                  984M  9.6M  974M   1% /run
tmpfs                  984M     0  984M   0% /sys/fs/cgroup
/dev/mapper/rhel-root   17G  3.9G   14G  23% /
/dev/sr0               6.7G  6.7G     0 100% /media/cdrom
/dev/sda1             1014M  152M  863M  15% /boot
tmpfs                  197M   16K  197M   1% /run/user/42
tmpfs                  197M  3.5M  194M   2% /run/user/0
/dev/sdb1              2.0G   47M  2.0G   3% /newFS
/dev/mapper/storage    200G  2.4G  198G   2% /storage

随便复制一个大文件过来,看看占用了多少容量,以及空间节省率(Space saving)是多少:

[root@linuxprobe ~]# ls -lh /media/cdrom/images/install.img 
-r--r--r--. 1 root root 448M Apr 4 2019 /media/cdrom/images/install.img
[root@linuxprobe ~]# cp /media/cdrom/images/install.img /storage/
[root@linuxprobe ~]# ls -lh /storage/install.img 
-r--r--r--. 1 root root 448M Jan  6 23:06 /storage/install.img
[root@linuxprobe ~]# vdostats --human-readable
Device                    Size      Used Available Use% Space saving%
/dev/mapper/storage      20.0G      4.4G     15.6G  22%           18%

效果不明显,再复制一份相同的文件过来,看看这次占用了多少空间:

[root@linuxprobe ~]# cp /media/cdrom/images/install.img /storage/rhel.img
[root@linuxprobe ~]# vdostats --human-readable
Device                    Size      Used Available Use% Space saving%
/dev/mapper/storage      20.0G      4.5G     15.5G  22%           55%

原先448MB的文件这次只占用了不到100MB的容量,空间节省率也从18%提升到了55%。当然这还仅仅是两次操作而已,好处就已经如此明显了。

最后,将设备设置成永久挂载生效,一直提供服务。

VDO设备卷在创建后会一直存在,但需要手动编辑/etc/fstab文件后才能在下一次重启后自动挂载生效,为我们所用。对于这种逻辑存储设备,其实不太建议使用/dev/mapper/storage作为设备名进行挂载。不如试试前面所说的UUID吧:

[root@linuxprobe ~]# blkid /dev/mapper/storage 
/dev/mapper/storage: UUID="cd4e9f12-e16a-415c-ae76-8de069076713" TYPE="xfs"

打开/etc/fstab文件,把对应的字段填写完整。建议再加上_netdev参数,表示等系统及网络都启动后再挂载VDO设备卷,以保证万无一失。

[root@linuxprobe ~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Tue Jul 21 05:03:40 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/rhel-root                        /             xfs        defaults           1 1
UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b    /boot         xfs        defaults,uquota    1 2
/dev/mapper/rhel-swap                        swap          swap       defaults           0 0
/dev/cdrom                                   /media/cdrom  iso9660    defaults           0 0 
/dev/sdb1                                    /newFS        xfs        defaults           0 0 
/dev/sdb2                                    swap          swap       defaults           0 0 
UUID=cd4e9f12-e16a-415c-ae76-8de069076713    /storage      xfs        defaults,_netdev   0 0 

8. 软硬连接

Linux系统中存在软链接和硬链接两种不同的类型。

软链接(soft link):也叫符号链接(symbolic link),仅仅包含所链接文件的名称和路径,很像一个记录地址的标签。当原始文件被删除或移动后,新的链接文件也会随之失效,不能被访问。可以针对文件、目录设置软链接,跨文件系统进行链接也不是问题。从这一点来看,它与Windows系统的“快捷方式”具有一样的性质。用户访问软链接的效果如下图所示。

硬链接(hard link):可以将它理解为一个“指向原始文件block的指针”,系统会创建出一个与原来一模一样的inode信息块。所以,硬链接文件与原始文件其实是一模一样的,只是名字不同。每添加一个硬链接,该文件的inode个数就会增加1;而且只有当该文件的inode个数为0时,才算彻底将它删除。换言之,由于硬链接实际上是指向原文件block的指针,因此即便原始文件被删除,依然可以通过硬链接文件来访问。需要注意的是,由于技术的局限性,不能跨分区对目录文件进行硬链接。用户访问硬链接的效果如下图所示。

ln命令用于创建文件的软硬链接,英文全称为“link”,语法格式为“ln [参数]原始文件名 链接文件名”。

ln命令中可用的参数以及作用:

参数 作用 -s 创建“符号链接”(如果不带-s参数,则默认创建硬链接) -f 强制创建文件或目录的链接 -i 覆盖前先询问 -v 显示创建链接的过程

创建软连接:

[root@linuxprobe ~]# echo "Welcome to linuxprobe.com" > old.txt
[root@linuxprobe ~]# ln -s old.txt new.txt
[root@linuxprobe ~]# cat old.txt 
Welcome to linuxprobe.com
[root@linuxprobe ~]# cat new.txt 
Welcome to linuxprobe.com
[root@linuxprobe ~]# ls -l old.txt 
-rw-r--r-- 1 root root 26 Jan 11 00:08 old.txt

原始文件名为old,新的软链接文件名为new。删掉原始文件后,软链接文件立刻就无法读取了:

[root@linuxprobe ~]# rm -f old.txt 
[root@linuxprobe ~]# cat new.txt 
cat: readit.txt: No such file or directory

接下来针对原始文件old创建一个硬链接,即相当于针对原始文件的硬盘存储位置创建了一个指针。这样一来,新创建的这个硬链接就不再依赖于原始文件的名称等信息,也不会因为原始文件的删除而导致无法读取了。同时可以看到创建硬链接后,原始文件的硬盘链接数量增加到了2。

[root@linuxprobe ~]# echo "Welcome to linuxprobe.com" > old.txt
[root@linuxprobe ~]# ln old.txt new.txt
[root@linuxprobe ~]# cat old.txt 
Welcome to linuxprobe.com
[root@linuxprobe ~]# cat new.txt 
Welcome to linuxprobe.com
[root@linuxprobe ~]# ls -l old.txt 
-rw-r--r-- 2 root root 26 Jan 11 00:13 old.txt

这是一个非常有意思的现象。创建的硬链接文件竟然会让文件属性第二列的数字变成了2,这个数字表示的是文件的inode信息块的数量。即便删除了原始文件,新的文件也会一如既往地可以读取,因为只有当文件inode数量被“清零”时,才真正代表这个文件被删除了。

[root@linuxprobe ~]# rm -f old.txt 
[root@linuxprobe ~]# cat new.txt 
Welcome to linuxprobe.com

参考

第6章 存储结构与管理硬盘

本文由mdnice多平台发布