磁盘存储和文件系统

本文最后更新于:2023年12月5日 晚上

磁盘结构

一切皆文件:open(),read(),write(),close()

设备文件:关联至驱动程序,进而能够与对应的硬件设备进行通信

设备号码

  • 主设备号:major number, 标识设备类型
  • 次设备号:minor number, 标识同一类型下的不同设备

设备类型

  • 块设备:block,存取设备单位“块”,磁盘等
  • 字符设备:char,存取设备单位“字符”,键盘等

机械硬盘的结构有两种,如下图所示:

硬盘寻址方式有两种:CHS 和 LBA

CHS:24 bit 位寻址,其中前 10 位表示柱面,中间 8 位表示磁头,后面 6 位表示扇区,最大寻址空间 8 GB

LBA:逻辑块寻址,LBA 是一个整数,表示从第几个扇区开始,到第几个扇区结束就完了,没有柱面磁头等概念,扇区这个概念也是逻辑上的,一个扇区通常是 512 个字节

创建设备文件

如果两个设备文件的类型、主次号码都相同,那这俩就是同一个设备

touch 创建普通文件,mknod 创建设备文件,删除用 rm,不能 cp 直接拷贝,如果要拷贝,使用cp -a保留属性即可拷贝

[root@centos7 ~]#ll /dev/null /dev/zero
crw-rw-rw-. 1 root root 1, 3 Aug 18 14:39 /dev/null
crw-rw-rw-. 1 root root 1, 5 Aug 18 14:39 /dev/zero
[root@centos7 ~]#mknod ./testnull c 1 3
[root@centos7 ~]#mknod ./testzero c 1 5
[root@centos7 ~]#ll
total 0
crw-r--r--. 1 root root 1, 3 Aug 18 17:16 testnull
crw-r--r--. 1 root root 1, 5 Aug 18 17:17 testzero

分区类型

两种分区方式:mbr、gpt

给虚拟机添加硬盘

虚拟机->添加->硬盘->scsi->虚拟硬盘->单个文件->完成

echo - - - > /sys/class/scsi_host/host0/scan
# 如果lsblk还不显示,再试试host1和host2

MBR

mbr 最多四个主分区,可以 3 个主分区+1 扩展分区(N 个逻辑分区)

主分区和扩展分区对应 1~4,/dev/sda3,逻辑分区从 5 开始,/dev/sda5

每个分区项占 16 个字节。

  • 第 1 个字节:活动分区启动计算机,非活动分区只是数据分区,所以四个分区只有一个 80,其他三个都是 00。
  • 第 2、3、4 个字节:这三个字节说明分区在硬盘上的起始位置,CHS 寻址。
  • 第 5 个字节:说明分区是否使用,0 表示未使用。
  • 第 6、7、8 个字节:这三个字节说明分区在硬盘上的结束位置,CHS 寻址。我们现在已经不使用 CHS 寻址了,虽然仍然给它保留了位置。
  • 第 9、10、11、12 个字节:这四个字节说明分区在硬盘上的起始位置,LBA 寻址。
  • 第 12、13、14、15、16 个字节:最后这四个字节说明分区在硬盘上的结束位置,LBA 寻址。按照每个扇区 512 个字节计算,4 个字节 32 位最多表示 2^32*512=2199023255552 字节=2T,所以 mbr 下 LBA 的寻址范围最大就是 2T,所以 mbr 分区的硬盘容量最大 2T,注意是硬盘 2T,不是分区 2T。

逻辑分区的分区信息储存在自己的分区内,所以逻辑分区可以有无数个。具体分区信息看图:

hexdump -C /dev/sda -n 512 查看硬盘的前 512 个字节,55 aa 这两个字节是结束标志位,高亮的 64 个字节是分区表,每 16 个字节是一个分区项

mbr 中的分区表 DPT:

GPT

gpt 支持 128 个分区,一般来说,windows 只能是 bios+mbr 或者 uefi+gpt 的组合,而 Linux 可以 bios+gpt 通过 grub 启动

磁盘常用命令

df

查看文件系统空间实际占用等信息

df [OPTION]... [FILE]...
  • -H 进制为 1000,而不是 1024
  • -T 显示文件系统类型
  • -h human-readable
  • -i 查看 inodes 的使用情况
  • -P 以 Posix 兼容的格式输出

du

查看某目录总体空间实际占用状态

du [OPTION]... DIR
  • -h human-readable
  • -s summary 只显示目录占用的空间,不一一列出目录下所有的文件
  • –max-depth=# 指定显示的目录层级,该选项和-s 冲突
  • -x 忽略不在同一个文件系统的目录

问题:如果 df 和 du 统计的结果差距过大,是为什么?

如果差距比较小,只有几十或者几十百m,是正常情况。如果差距过大,则是因为删除大文件导致。df直接统计分区,du对目录下的文件逐个统计,如果删除大文件,但是还有进程引用这个文件,此时df还会统计到它,而du是统计不到它的,这样就会造成df和du统计的结果差距过大

解决方法:`lsof | grep delete` 找出占用已删除文件的进程,然后杀掉就行了

dd

从目标文件 1 拷贝内容写入到目标文件 2

dd if=/PATH/FROM/SRC of=/PATH/TO/DEST bs=# count=#
  • if=file1:in file = file1 从 file1 读取内容
  • of=file2:out file=file2 将读取的内容写入到 file2
  • bs=size:block size 指定块的大小,默认单位是字节
  • count=# 读取#个块,如果要读取 1G 的内容,可以bs=1024M count=1,也可以bs=1M count=1024,或者bs=64M count=16。不指定 bs 和 count,可以理解为备份
  • skip=# 读 file1 的时候,忽略前#个块,从#+1 个块开始读取
  • seek=# 写 file2 的时候,忽略前#个块,从#+1 个块开始写入
  • conv=conversion[,conversion…] 用指定的参数转换文件
    • conversion 转换参数:
    • ascii 转换 EBCDIC 为 ASCII
    • ebcdic 转换 ASCII 为 EBCDIC
    • lcase 把大写字符转换为小写字符
    • ucase 把小写字符转换为大写字符
    • nocreat 不创建输出文件
    • noerror 出错时不停止
    • notrunc 不截短输出文件,file2 被写入内容的位置开始,默认先截断成 0 字节大小,这个参数可以保证不截断。例如 file2 内容是 123456789,从开头位置写入 ab,默认从开头往后,都截断成 0 字节,然后再写入 ab,添加 notrunc 参数,写完后是 ab3456789。
    • sync 把每个输入块填充到 ibs 个字节,不足部分用空(NUL)字符补齐
    • fdatasync 写完成前,物理写入输出文件

范例:

#备份MBR
dd if=/dev/sda of=/tmp/mbr.bak bs=512 count=1

#破坏MBR中的bootloader
dd if=/dev/zero of=/dev/sda bs=64 count=1 seek=446

#有一个大与2K的二进制文件fileA。现在想从第64个字节位置开始读取,需要读取的大小是128Byts。又有fileB, 想把上面读取到的128Bytes写到第32个字节开始的位置,替换128Bytes,实现如下
dd if=fileA of=fileB bs=1 count=128 skip=63 seek=31 conv=notrunc

#将本地的/dev/sdx整盘备份到/dev/sdy
dd if=/dev/sdx of=/dev/sdy

#将/dev/sdx全盘数据备份到指定路径的image文件
dd if=/dev/sdx of=/path/to/image

#备份/dev/sdx全盘数据,并利用gzip压缩,保存到指定路径
dd if=/dev/sdx | gzip >/path/to/image.gz

#将备份文件恢复到指定盘
dd if=/path/to/image of=/dev/sdx

#将压缩的备份文件恢复到指定盘
gzip -dc /path/to/image.gz | dd of=/dev/sdx

#将内存里的数据拷贝到root目录下的mem.bin文件
dd if=/dev/mem of=/root/mem.bin bs=1024

#拷贝光盘数据到root文件夹下,并保存为cdrom.iso文件
dd if=/dev/cdrom of=/root/cdrom.iso

#销毁磁盘数据
dd if=/dev/urandom of=/dev/sda1

#通过比较dd指令输出中命令的执行时间,即可确定系统最佳的block size大小
dd if=/dev/zero of=/root/1Gb.file bs=1024 count=1000000
dd if=/dev/zero of=/root/1Gb.file bs=2048 count=500000
dd if=/dev/zero of=/root/1Gb.file bs=4096 count=250000

#测试硬盘写速度
dd if=/dev/zero of=/root/1Gb.file bs=1024 count=1000000

#测试硬盘读速度
dd if=/root/1Gb.file bs=64k | dd of=/dev/null

练习:

  1. 创建一个 2G 的文件系统,块大小为 2048byte,预留 1%可用空间,文件系统 ext4,卷标为 TEST,要求
    此分区开机后自动挂载至/test 目录,且默认有 acl 挂载选项
  2. 写一个脚本,完成如下功能:
    (1) 列出当前系统识别到的所有磁盘设备
    (2) 如磁盘数量为 1,则显示其空间使用信息
    否则,则显示最后一个磁盘上的空间使用信息
  3. 将 CentOS6 的 CentOS-6.10-x86_64-bin-DVD1.iso 和 CentOS-6.10-x86_64-bin-DVD2.iso 两个文件,
    合并成一个 CentOS-6.10-x86_64-Everything.iso 文件,并将其配置为 yum 源

管理分区

lsblk

列出块设备

lsblk [options] [<device> ...]
  • -f:列出文件系统相关信息

blkid

查看块设备(包括交换分区)所使用的文件系统类型、LABEL、UUID 等信息

blkid [OPTION]... [DEVICE]

-U UUID 根据指定的 UUID 来查找对应的设备
-L LABEL 根据指定的 LABEL 来查找对应的设备

fdisk

管理 mbr 分区。交互式,根据提示操作即可。

m:查看帮助
p:查看分区
n:增加分区
d:删除分区
w:保存并退出
q:不保存并退出

对硬盘进行分区操作,如果硬盘上已有其他已经挂载的分区,w 保存操作后,centos7 及以前的系统识别不到分区更改,需要手动通知内核重新读取硬盘分区表

硬盘增加分区,前提是硬盘要有未分配的空间

重新加载分区表

centos7 和 centos5:

partprobe

centos6:

# 增加分区
partx -a /dev/DEVICE
# 删除分区
partx -d --nr M-N /dev/DEVICE

gdisk

管理 gpt 分区,操作和 fdisk 雷同

parted

高级分区操作,可以使交互式或非交互式,parted 的操作都是实时生效的,所以一般不用

管理文件系统

文件系统组成

以 ls 命令为例,它的作用是列出文件,它并不会与 ext4、xfs 等文件系统直接交互,而是和 vfs 进行交互,由 vfs 处理各种文件系统的兼容性

  • 内核中的模块:ext4, xfs, vfat
  • Linux 的虚拟文件系统:VFS
  • 用户空间的管理工具:mkfs.ext4、mkfs.xfs、mkfs.vfat

新硬盘,先 fdisk 分区,然后 mkfs 创建文件系统,最后 mount 挂载

文件系统是操作系统用于明确存储设备或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件结构称为文件管理系统,简称文件系统从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,安全控制,日志,压缩,加密等

当前系统支持的文件系统:

[root@centos7 ~]# rpm -qf /lib/modules/3.10.0-1127.el7.x86_64/kernel-3.10.0-1127.el7.x86_64

上面显示的不全,我不知道为什么,通过查看内核包可以看到所有支持的文件系统,每个 xz 压缩包都是对应文件系统的驱动。

# centos7
[root@centos7 ~]# rpm -qf /lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/
kernel-3.10.0-1127.el7.x86_64
[root@centos7 ~]# rpm -ql `!!` | grep '/fs/'
rpm -ql `rpm -qf /lib/modules/3.10.0-1127.el7.x86_64/` | grep '/fs/'
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/binfmt_misc.ko.xz
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/btrfs
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/btrfs/btrfs.ko.xz
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/cachefiles
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/cachefiles/cachefiles.ko.xz
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/ceph
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/ceph/ceph.ko.xz
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/cifs
/lib/modules/3.10.0-1127.el7.x86_64/kernel/fs/cifs/cifs.ko.xz
...
...

# ubuntu18.04
lujinkai@Z510:~$ dpkg -S /lib/modules/5.4.0-42-generic/kernel/fs/
linux-modules-extra-5.4.0-42-generic, linux-modules-5.4.0-42-generic: /lib/modules/5.4.0-42-generic/kernel/fs
lujinkai@Z510:~$ dpkg -L linux-modules-extra-5.4.0-42-generic | grep '/fs/'
/lib/modules/5.4.0-42-generic/kernel/fs/9p
/lib/modules/5.4.0-42-generic/kernel/fs/adfs
/lib/modules/5.4.0-42-generic/kernel/fs/adfs/adfs.ko
/lib/modules/5.4.0-42-generic/kernel/fs/affs
/lib/modules/5.4.0-42-generic/kernel/fs/affs/affs.ko
/lib/modules/5.4.0-42-generic/kernel/fs/afs
/lib/modules/5.4.0-42-generic/kernel/fs/afs/kafs.ko
/lib/modules/5.4.0-42-generic/kernel/fs/aufs
/lib/modules/5.4.0-42-generic/kernel/fs/autofs
/lib/modules/5.4.0-42-generic/kernel/fs/befs
/lib/modules/5.4.0-42-generic/kernel/fs/befs/befs.ko
/lib/modules/5.4.0-42-generic/kernel/fs/bfs
/lib/modules/5.4.0-42-generic/kernel/fs/bfs/bfs.ko
...
...
...

或者查看 /proc/filesystems,nodev 标注的文件系统不需要块文件,也就是说不需要硬盘,文件就可以

[root@centos7 ~]# cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev ramfs
nodev bdev
nodev proc
nodev cgroup
nodev cpuset
nodev tmpfs
nodev devtmpfs
nodev debugfs
nodev securityfs
nodev sockfs
nodev dax
nodev bpf
nodev pipefs
nodev configfs
nodev devpts
nodev hugetlbfs
nodev autofs
nodev pstore
nodev mqueue
nodev selinuxfs
 xfs
 iso9660
 ext3
 ext2
 ext4
 vfat

超级块和 inode table

[root@centos7 ~]# mkfs.ext4 /dev/sdb5
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
128016 inodes, 512000 blocks
25600 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=34078720
63 block groups
8192 blocks per group, 8192 fragments per group
2032 inodes per group
Superblock backups stored on blocks:
 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

文件系统把每个分区分成多个块组(block group),每个块组中有很多块,每个块的大小通常为 4K,具体块组的组成看下图。超级块(super block)中存储了所有块组的元数据,超级块存储在块组 0 中,并在其他部分块组有备份;块组描述符表(GDT)是块组描述符的集合,和超级组一样,也是储存块组 0 中,在其他部分块组中备份;块位图(block bitmap)描述了块的使用情况;节点位图(inode bitmap)描述了节点的使用情况。节点表(inode table)存储节点;数据块(data blocks)存储数据

块组描述符
Ext3 文件系统的每个块组描述符占用 32 字节,用以描述块组中的位图起始地址、i-节点表起始地址、空闲块数、空闲 i-节点数等信息,每个块组都有这样的一个块组描述符,所有的块组描述符集中存放,组成块组描述符表。

mkfs

创建文件系统

mkfs.FS_TYPE /dev/DEVICE

FS_TYPE:ext4、xfs 等,具体 tab 可以提示

tune2fs 、dumpefs、xfs_info

tune2fs 查看超级块信息,dumpe2fs 查看超级块和各个块组的信息,tune2fs 和 dump2fs 只适用于 ext 文件系统,xfs 文件系统使用 xfs_info 命令

[root@centos7 ~]# tune2fs -l /dev/sdb5
[root@centos7 ~]# dumpe2fs /dev/sdb5
[root@centos7 ~]# xfs_info /dev/sda1

fsck、e2fsck、xfs_repair

tune2fs、dumpe2fs 查看分区的 ext 文件系统信息,Filesystem state 标记为 no clean,说明文件系统发生故障。使用 e2fsck 可以修复。如果是 xfs 文件系统发生故障,使用 xfs_repair 修改。fsck 通用,不管什么文件系统都可以修复

注意:1. 修复之前一定要 umount 先取消挂载

  1. 数据不一定能恢复
fsck.FS_TYPE  /dev/DEVICE
e2fsck  /dev/DEVICE
xfs_repair /dev/DEVICE

挂载设备

mount

mount  device MOUNT_POINT

mount [-lhV]
mount -a [-fFnrsvw] [-t vfstype] [-O optlist]
mount [-fnrsvw] [-o option[,option]...]  device|dir
mount [-fnrsvw] [-t vfstype] [-o options] device dir

device:设备文件:例如:/dev/sda5、伪文件系统名称:proc, sysfs, devtmpfs, configfs

MOUNT_POINT:挂载点目录必须事先存在,建议使用空目录

# 查看当前已挂载的所有设备
[root@centos7 ~]# mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,seclabel,size=487128k,nr_inodes=121782,mode=755)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,seclabel)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,seclabel,gid=5,mode=620,ptmxmode=000)
...
...
...
# 通过查看/etc/mtab文件显示当前已挂载的所有设备
[root@centos7 ~]# ll /etc/mtab
lrwxrwxrwx. 1 root root 17 Aug 14 19:22 /etc/mtab -> /proc/self/mounts

# 查看内核追踪到的已挂载的所有设备
[root@centos7 ~]# ll /proc/mounts
lrwxrwxrwx. 1 root root 11 Aug 20 18:06 /proc/mounts -> self/mounts

mount -o options

挂载不同的文件系统,-o 的 options 是不同的,具体有哪些 option,参考对应的文件系统的挂载选项,例如:要挂载 nfs,man mount.nfs 查看对应 option,要挂载 cifs,man mount.cifs查看对应的 option …

umount

umount MOUNT_POINT|device

findmnt

查看挂载点信息

findmnt MOUNT_POINT|device

lsof、fuser

查看正在访问指定文件系统的进程

lsof MOUNT_POINT

终止所有正在访问指定挂载点的进程

fuser -km MOUNT_POINT

持久挂载

mount 命令是临时挂载,将挂载信息写入到/etc/fstab 中可以下次开机时自动启用挂载。

[root@centos7 ~]# cat /etc/fstab

#
# /etc/fstab
# Created by anaconda on Wed Jul 29 17:08:37 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
#
UUID=28eb957c-1e98-4175-9a00-3efdef247355 /                       xfs     defaults        0 0
UUID=25ea1f67-ee88-44b1-935e-8af77eadf856 /boot                   xfs     defaults        0 0
UUID=91664c04-1540-4e35-8711-c3f183a556ca /data                   xfs     defaults        0 0
UUID=a1966abb-acf9-4f53-8a86-733a93c2d576 swap                    swap    defaults        0 0

/dev/sr0 /data/repo/centos/7/x86_64 iso9660 defaults 0 0

注意/etc/fstab 中 device 一般用 UUID 指代,而不是路径,因为 UUID 稳定,一般不会更改,/dev/sr0 这种不是特别合适。

man 5 fstab可以查看/etc/fstab 文件的格式,最后两个选项:

  • 转储频率:0:不做备份 1:每天转储 2:每隔一天转储
  • fsck 检查的文件系统的顺序:允许的数字是 0 1 2
    • 0:不自检
    • 1:首先自检;一般只有 rootfs 才用
    • 2:非 rootfs 使用

添加新的挂载项,执行mount -a使挂载生效

管理 swap 空间

交换分区实现过程

  1. 创建交换分区或者文件
  2. 使用 mkswap 写入特殊签名
  3. 在/etc/fstab 文件中添加适当的条目
  4. 使用swapon -a 激活交换空间

范例:以文件实现 swap 功能

[root@centos7 /]# dd if=/dev/zero of=/swapfile bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 2.04882 s, 524 MB/s

[root@centos7 /]# mkswap /swapfile
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=8ae1b7bc-7038-4f6a-9940-b75ec91beb21

[root@centos7 /]# chmod 600 /swapfile
[root@centos7 /]# swapon /swapfile

[root@centos7 /]# swapon -s
Filename    Type      Size            Used Priority
/dev/sda5               partition 2097148       0          -2
/swapfile                file             1048572        0      -3

swap 的使用策略

/proc/sys/vm/swappiness 的值决定了当内存占用达到一定的百分比时,会启用 swap 分区的空间,例如 swappiness 的值为 30,说明当物理内存使用到 70%,就开始使用 swap,应该将这个值设置为 0

# 临时修改
[root@centos7 /]# echo 0 > /proc/sys/vm/swappiness

# 永久修改
# centos7
[root@centos7 /]# echo 'vm.swappiness=0' >> /etc/sysctl.conf
[root@centos7 ~]# sysctl -p
vm.swappiness = 0

# ubuntu18.04
lujinkai@Z510:~$ echo 'vm.swappiness=0' | sudo dd of=/etc/sysctl.conf oflag=append conv=notrunc
[sudo] password for lujinkai:
0+1 records in
0+1 records out
16 bytes copied, 0.000102837 s, 156 kB/s
lujinkai@Z510:~$ sudo sysctl -p
vm.swappiness = 0

RAID 管理

RAID:独立硬盘冗余阵列,简称磁盘阵列,利用虚拟化存储技术把多个硬盘组合起来,成为一个或多个硬盘阵列组,目的为提升性能或数据冗余,或是两者同时提升。

简单来说,RAID 把多个硬盘组合成为一个逻辑硬盘,因此,操作系统只会把它当作一个实体硬盘。

RAID 层级不同,数据会以多种模式分散于各个硬盘,常用的 RAID 层级:RAID 0、RAID 1、RAID 5、RAID 6、RAID 10、RAID 50、RAID 60

raid0

数据分散在多个硬盘,读写速度都有提升,但是一个硬盘坏了,所有数据都被破坏

raid 1

数据备份到多个硬盘,有几个硬盘,就有几个备份,理论上,两个硬盘组 raid1,空间利用率有 50%,三个硬盘组 raid 1,空间利用率只有 33%

raid 4

设置单独校验盘,数据分散在其他的硬盘,其他硬盘通过亦或运算得出的值,最多允许一块硬盘损坏,当存储数据的盘有坏的,其他盘可以计算出丢失的那部分数据。缺点是校验盘最容易坏。

raid 5

是 raid 4 的升级版,校验不是单独一块盘,而是将校验分散在所有硬盘,最多允许一块硬盘损坏

raid 6

是 raid 5 的升级版,校验由一份升级为两份,增加容错性,允许两块硬盘损坏。

生产中,通常会准备热备盘,例如 raid5 就需要额外 1 块盘做热备

raid 10

是 raid1 和 raid0 的组合,解决 raid 0 没有容错能力的缺点。

raid 50

是 raid 5 和 raid 0 的组合,对比 raid 10,读写的速度更快

raid 60

是 raid 6 和 raid 0 的组合,增加 raid 50 的容错能力

JBOD

将多块磁盘的空间合并一个大的连续空间使用

raid7

RAID 7 并非公开的 RAID 标准,而是 Storage Computer Corporation 的专利硬件产品名称,RAID 7 是以 RAID 3 及 RAID 4 为基础所发展,但是经过强化以解决原来的一些限制。另外,在实现中使用大量的缓冲存储器以及用以实现异步数组管理的专用即时处理器,使得 RAID 7 可以同时处理大量的 IO 要求,所以性能甚至超越了许多其他 RAID 标准的实际产品。但也因为如此,在价格方面非常的高昂.RAID7 可以理解为一个独立存储计算机,自身带有操作系统和管理工具,可以独立运行,理论上性能最高的 RAID 模式。

软件实现 raid

可以通过软件实现 raid,但是企业中不用,所以略过。。。

LVM 管理和 LVM 快照

LVM 逻辑卷管理器,本质上是一个虚拟设备驱动,在磁盘分区和文件系统之间添加一个逻辑层。底层的物理磁盘不再由内核直接控制,而是由 LVM 层来控制。LVM 维持着逻辑盘区和物理盘区之间的映射。LVM 逻辑设备向上层应用提供了和物理磁盘相同的功能,如文件系统的创建和数据的访问等

基本术语准备

  • 物理存储介质(PhysicalStorageMedia)
    指系统的物理存储设备:磁盘,是存储系统最底层的存储单元

  • 物理卷(Physical Volume,PV)
    物理卷是由磁盘分区转化而来

  • 卷组(Volume Group,VG)
    类似于非 LVM 系统中的物理磁盘,其由一个或多个物理卷 PV 组成。可以在卷组上创建一个或多个 LV(逻辑卷)

  • 逻辑卷(Logical Volume,LV)
    类似于非 LVM 系统中的磁盘分区,逻辑卷建立在卷组 VG 之上。在逻辑卷 LV 之上可以建立文件系统

  • 物理块(Physical Extent,PE)
    PE 是物理卷 PV 的基本划分单元,具有唯一编号的 PE 是可以被 LVM 寻址的最小单元。PE 的大小是可配置的,默认为 4MB。所以物理卷(PV)由大小等同的基本单元 PE 组成

  • 逻辑块(Logical Extent,LE)
    逻辑卷 LV 也被划分为可被寻址的基本单位,称为 LE。在同一个卷组中,LE 的大小和 PE 是相同的,并且一一对应

物理卷:还是/dev/sda、/dev/sdb 等,名称系统分配

逻辑卷:/dev/vg0/lv1 等,名称自定义

实现过程

1. 安装 lvm2 包

[root@centos7 ~]# yum -y install lvm2

2. 将设备指定为物理卷

  • pvs 简要显示 pv 信息
  • pvdisplay 详细显示 pv 信息
  • pvcreate /dev/DEVICE 创建 pv
  • pvremove /dev/DEVICE 删除 pv
  • pvmove 搬移 PV 中的资料(只限于同一 VG 中)
    • pvmove /dev/hda5 /dev/hda6 将 VG 中 pv hda5 的内容搬移到 hda6 中
    • pvmove /dev/hda5 也可以这样,lvm 决定 hda5 的内容被复制到哪里
[root@centos7 ~]# pvcreate /dev/sdb
WARNING: dos signature detected on /dev/sdb at offset 510. Wipe it? [y/n]: y
  Wiping dos signature on /dev/sdb.
  Physical volume "/dev/sdb" successfully created.
[root@centos7 ~]# pvcreate /dev/sdc
  Physical volume "/dev/sdc" successfully created.
[root@centos7 ~]# lsblk -f
NAME   FSTYPE   LABEL           UUID                                   MOUNTPOINT
sda
|-sda1 xfs                      25ea1f67-ee88-44b1-935e-8af77eadf856   /boot
|-sda2 xfs                      28eb957c-1e98-4175-9a00-3efdef247355   /
|-sda3 xfs                      91664c04-1540-4e35-8711-c3f183a556ca   /data
|-sda4
|-sda5 swap                     a1966abb-acf9-4f53-8a86-733a93c2d576   [SWAP]
|-sda6
`-sda7
sdb    LVM2_mem                 F4zIYp-IM1g-gJS6-ktqS-OZOD-u46a-z6YrQd
sdc    LVM2_mem                 rAL8Wi-ln8P-LmUK-FaQn-40Mk-iGw4-ocXIUe
sr0    iso9660  CentOS 7 x86_64 2020-04-22-00-51-40-00                 /data/repo/
[root@centos7 ~]# pvs
  PV         VG Fmt  Attr PSize  PFree
  /dev/sdb      lvm2 ---  10.00g 10.00g
  /dev/sdc      lvm2 ---   5.00g  5.00g
[root@centos7 ~]# pvdisplay
  "/dev/sdb" is a new physical volume of "10.00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb
  VG Name
  PV Size               10.00 GiB
  Allocatable           NO
  PE Size               0
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               F4zIYp-IM1g-gJS6-ktqS-OZOD-u46a-z6YrQd

  "/dev/sdc" is a new physical volume of "5.00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sdc
  VG Name
  PV Size               5.00 GiB
  Allocatable           NO
  PE Size               0
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               rAL8Wi-ln8P-LmUK-FaQn-40Mk-iGw4-ocXIUe

3. 用一个或多个物理卷来创建一个卷组

  • vgs 显示卷组
  • vgdisplay 显示卷组
  • vgcreate 卷组名 物理卷列表 创建卷组
# 指定PE大小为16M,默认4M
[root@centos7 ~]# vgcreate -s 16M vg0 /dev/sdb /dev/sdc
  Volume group "vg0" successfully created
[root@centos7 ~]# vgs
  VG  #PV #LV #SN Attr   VSize   VFree
  vg0   2   0   0 wz--n- <14.97g <14.97g
[root@centos7 ~]# vgdisplay
  --- Volume group ---
  VG Name               vg0
  System ID
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               <14.97 GiB
  PE Size               16.00 MiB
  Total PE              958
  Alloc PE / Size       0 / 0
  Free  PE / Size       958 / <14.97 GiB
  VG UUID               zszcPb-urGs-jKX8-ZOCu-Xlb8-JPrD-b5bVt8
  • vgextend 卷组名 物理卷列表 向卷组中添加物理卷
  • vgreduce 卷组名 物理卷列表 从卷组中删除物理卷
  • vgremove 卷组名 删除卷组
    • 删除卷组之前应该先使用 pvmove 将数据迁移

4. 在卷组上创建逻辑卷

  • lvs

  • lvdisplay

  • lvcreate 创建逻辑卷

    • n 后面跟逻辑卷名
    • s 创建快照
    • l 指定逻辑卷的大小(LE 数)
    # 卷组vg0分配100个PE给新建逻辑卷lv0,这样lv0的大小就是100个LE
    [root@centos7 ~]# lvcreate -l 100 -n lv0 vg0
    # 其他范例
    lvcreate -l 60%VG -n mylv testvg
    lvcreate -l 100%FREE -n yourlv testvg
    • L 指定逻辑卷的大小,单位为“kKmMgGtT”
    # 卷组vg0分配1G给新建逻辑卷lv1
    [root@centos7 ~]# lvcreate -L 1G -n lv1 vg0
  • lvremove 逻辑卷 删除逻辑卷

    [root@centos7 ~]# lvs
      LV   VG  Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
      lv0  vg0 -wi-a-----   1.56g
      lv1  vg0 -wi-a-----   1.00g
      lv2  vg0 -wi-a----- <12.41g
    [root@centos7 ~]# lvremove lv2
      Volume group "lv2" not found
      Cannot process volume group lv2
    [root@centos7 ~]# lvremove /dev/vg0/lv2
    Do you really want to remove active logical volume vg0/lv2? [y/n]: y
      Logical volume "lv2" successfully removed
    [root@centos7 ~]# lvs
      LV   VG  Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
      lv0  vg0 -wi-a----- 1.56g
      lv1  vg0 -wi-a----- 1.00g
  • lvextend 扩展逻辑卷

    • -L [+]kKmMgGtT 没有+表示扩展至指定大小,有+表示增加指定大小
    • -l [+]Number[PERCENT]
    • -r 如果逻辑卷上已经有文件系统,同步扩展文件系统
    # 两步实现:
    # 1. 实现逻辑卷的空间扩展
    lvextend -L [+]#[mMgGtT] /dev/VG_NAME/LV_NAME
    # 2. 实现文件系统的扩展
    resize2fs /dev/VG_NAME/LV_NAME # 针对ext
    # 或:
    xfs_growfs MOUNTPOINT   # 针对xfs
    
    # 一步实现
    lvresize -r -l +100%FREE /dev/VG_NAME/LV_NAME
    [root@centos7 ~]# lvextend -r -L +1G /dev/vg0/lv1
  • lvreduce 缩减逻辑卷,只针对 ext 文件系统,xfs 不支持缩减,缩减有风险,最好先备份数据

    • -l 同 lvextend
    • -L 同 lvextend

5. 在逻辑卷上创建文件系统并挂载

mkfs.ext4 /dev/vg0/lv1
mount /dev/vg0/lv1 /mnt/lv1/

6. 跨主机迁移卷组

  1. 在旧系统中,umount 所有卷组上的逻辑卷

  2. 禁用卷组

    vgchange 用于修改卷组的属性,经常被用来设置卷组是处于活动状态或者非活动状态。

vgchange –a n vg0
lvdisplay
  1. 导出卷组
vgexport vg0
pvscan
vgdisplay
  1. 拆下旧硬盘在目标计算机上,并导入卷组
vgimport vg0
  1. 启用
vgchange –ay vg0
  1. mount 所有卷组上的逻辑卷

7. 拆除指定的 pv 存储设备

  1. pvmove 迁移物理卷数据,注意只能迁移到同一卷组下的其他物理卷
  2. vgreduce 从卷组中移除物理卷
  3. pvremove 从机器上移除物理卷

逻辑卷快照

范例:

mkfs.xfs /dev/vg0/data
mount /dev/vg0/data/ /mnt/data

#为现有逻辑卷创建快照,快照大小一般指定为十分之一
#  -p|--permission rw|r
lvcreate -l 64 -s -n data-snapshot -p r /dev/vg0/data

#挂载快照
mkdir -p /mnt/snap
mount -o ro,nouuid /dev/vg0/data-snapshot /mnt/snap  #  -o ro,nouuid 只读,不校验重复uuid

#恢复快照
umount /dev/vg0/data-snapshot
umount /dev/vg0/data
lvconvert --merge /dev/vg0/data-snapshot

#删除快照
umount /mnt/snap
lvremove /dev/vg0/data-snapshot

磁盘存储和文件系统
http://blog.lujinkai.cn/运维/基础/磁盘/磁盘存储和文件系统/
作者
像方便面一样的男子
发布于
2020年12月9日
更新于
2023年12月5日
许可协议