linux文件系统小结

文件系统

Linux

Linux:存在几十个文件系统类型:ext2,ext3,ext4,xfs,brtfs,zfs(man 5 fs可以取得全部文件系统的介绍)

不同文件系统采用不同的方法来管理磁盘空间,各有优劣;文件系统是具体到分区的,所以格式化针对的是分区,分区格式化是指采用指定的文件系统类型对分区空间进行登记、索引并建立相应的管理表格的过程。

  • ext2具有极快的速度和极小的CPU占用率,可用于硬盘和移动存储设备
  • ext3增加日志功能,可回溯追踪
  • ext4日志式文件系统,支持1EB(1024*1024TB),最大单文件16TB,支持连续写入可减少文件碎片。rhel6默认文件系统
  • xfs可以管理500T的硬盘。rhel7默认文件系统
  • brtfs文件系统针对固态盘做优化,

注:EXT(Extended file system)是延伸文件系统、扩展文件系统,ext1于1992年4月发表,是为linux核心所做的第一个文件系统。

1
2
3
格式化命令:mkfs -t <文件系统类型> <分区设备文件名>

      mkfs.xfs /dev/sdb1

windows

  • FAT16:MS—DOS和win95采用的磁盘分区格式,采用16位的文件分配表,只支持2GB的磁盘分区,最大单文件2GB,且磁盘利用率低
  • FAT32:(即Vfat)采用32位的文件分配表,支持最大分区128GB,最大文件4GB
  • NTFS:支持最大分区2TB,最大文件2TB,安全性和稳定性非常好,不易出现文件碎片。

其他

  • RAMFS:内存文件系统
  • ISO 9660:光盘
  • NFS:网络文件系统
  • SMBAFS/CIFS:支持Samba协议的网络文件系统
  • Linux swap:交换分区,用以提供虚拟内存。

磁盘分区基本概念

硬盘分区的划分标准:

硬盘分区由主分区、扩展分区和逻辑分区组成

在一块硬盘上,如果是MBR分区方式,那么它的主分区最多只能有4个,或者3个主分区和1个扩展分区;在扩展分区上我们可以创建多个逻辑分区

分区编号:主分区1-4 ,逻辑分区5.。。。。。

LINUX规定:逻辑分区必须建立在扩展分区之上,而不是建立在主分区上

分区作用:

主分区:主要是用来启动操作系统的,它主要放的是操作系统的启动或引导程序,/boot分区最好放在主分区上
扩展分区不能使用的,它只是做为逻辑分区的容器存在的;我们真正存放数据的是主分区和逻辑分区,大量数据都放在逻辑分区中
如果你用的是GPT的分区方式,那么它没有限制主分区个数
注意:从MBR转到GPT分区或者说从GPT转到MBR会导致数据全部丢失
因此我们在对硬盘分区时最好划分主分区连续,比如说:主分区一、主分区二、扩展分区。

分区命令parted的用法

parted的适用场景

创建操作大于2T的分区
一般情况下,我们都是选择使用fdisk工具来进行分区,但是目前在实际生产环境中使用的磁盘空间越来越大,呈TiB级别增长;而常用的fdisk这个工具对分区是有大小限制的,它只能划分小于2T的磁盘,所以在划大于2T磁盘分区的时候fdisk就无法满足要求了;这个时候有2个方法,其一是通过卷管理来实现,其二就是通过parted工具来实现对GPT磁盘进行分区操作;这里我们采用parted的方法来实现管理。

parted的2种使用方式

交互式

手动按序交互式的创建;

非交互式

可将命令行写在脚本中,运行脚本实现一键创建;适用于远程批量管理多台主机的场景。

两种方式比较

两种方法的使用和原理其实是一样的;要想实现非交互式创建,无非是在每一个具体的交互式命令前加上parted DEVICES_NAME即可。

交互式方式实现分区步骤

  1. 选择操作磁盘

parted命令后跟上欲操作磁盘的名字即可选择此设备进行操作。

1
2
3
4
[root@kvm ~]# parted /dev/sdb
GNU Parted 3.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
  1. 新建磁盘标签类型为GPT

因为parted命令只能针对gpt格式的磁盘进行操作,所以这里必须将新建的磁盘标签格式设为gpt。

1
(parted) mklabel gpt
  1. 分区
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mkpart PART-TYPE [FS-TYPE] START END

PART-TYPE(分区类型)

primary :主分区
logical :逻辑分区
extended :扩展分区

FS-TYPE(文件系统类型)
ext4、ext3、ext2、xfs

START: 设定磁盘分区起始点;可以为0,numberMiB/GiB/TiB;

0:设定当前分区的起始点为磁盘的第一个扇区;
1G:设定当前分区的起始点为磁盘的1G处开始;

END:设定磁盘分区结束点;

-1:设定当前分区的结束点为磁盘的最后一个扇区;
10G:设定当前分区的结束点为磁盘的10G处;

将/dev/sdb整个空间分给同一个分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(parted) mkpart primary 0 -1                                              
Warning: The resulting partition is not properly aligned for best performance.
Ignore/Cancel? I
(parted) p
Model: AVAGO AVAGO (scsi)
Disk /dev/sdb: 18.0TB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 17.4kB 18.0TB 18.0TB primary
(parted) q
Information: You may need to update /etc/fstab.

格式化分区

因为整个/dev/sdb只分了一个区,则这个分区名默认会分配为/dev/sdb1;使用mkfs命令将/dev/sdb1分区格式化为ext4。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@kvm ~]# mkfs -t ext4 /dev/sdb1                 
mke2fs 1.42.9 (28-Dec-2013)
/dev/sdb1 alignment is offset by 244736 bytes.
This may result in very poor performance, (re)-partitioning suggested.
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=64 blocks, Stripe width=64 blocks
274659328 inodes, 4394530311 blocks
219726515 blocks (5.00%) reserved for the super user
First data block=0
134111 block groups
32768 blocks per group, 32768 fragments per group
2048 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000, 214990848, 512000000, 550731776, 644972544, 1934917632,
2560000000, 3855122432

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

设定分区label(非必要)

1
[root@kvm ~]# e2label /dev/sdb1 /gfsdata01

创建挂载目录

1
[root@kvm ~]# mkdir /gfsdata01

临时挂载分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@kvm ~]# mount /dev/sdb1 /gfsdata01
[root@kvm ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/root_vg-lv_root 89G 2.6G 82G 4% /
devtmpfs 126G 0 126G 0% /dev
tmpfs 126G 0 126G 0% /dev/shm
tmpfs 126G 2.0M 126G 1% /run
tmpfs 126G 0 126G 0% /sys/fs/cgroup
/dev/sda1 976M 216M 694M 24% /boot
/dev/sda7 99G 61M 94G 1% /home
/dev/sda8 62G 53M 59G 1% /tmp
/dev/sda6 99G 61M 94G 1% /app
tmpfs 26G 0 26G 0% /run/user/1014
tmpfs 26G 0 26G 0% /run/user/0
/dev/sdb1 17T 20K 16T 1% /gfsdata01

开机自动挂载(永久挂载)

即修改/etc/fstab文件。

1
echo '/dev/sdb1 /gfsdata01    ext4    defaults    0 0' >>/etc/fstab

非交互式方式实现脚本

适用于需要在多台主机上进行同样的分区操作,可以通过ansible工具调用脚本实现批量分区配置挂载等操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@kvm ~]# cat ./auto_partition.sh 
#!/bin/bash
# 新建/dev/sdb的磁盘标签类型为GPT
parted /dev/sdb mklabel gpt
# 将/dev/sdb整个空间分给同一个分区
parted /dev/sdb mkpart primary 0 100%
# 忽略警告
ignore
# 格式化分区
mkfs -t ext4 /dev/sdb1
# 设定分区label(非必要)
e2label /dev/sdb1 /gfsdata01
# 创建挂载目录
mkdir /gfsdata01
# 临时挂载
mount /dev/sdb1 /gfsdata01
# 开机自动挂载(永久挂载)
echo '/dev/sdb1 /gfsdata01 ext4 defaults 0 0'>>/etc/fstab
[root@kvm ~]#

删除分区(rm子命令)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(parted) p                                                                
Model: AVAGO AVAGO (scsi)
Disk /dev/sdb: 18.0TB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 17.4kB 4096GB 4096GB primary

(parted) rm 1
(parted) p
Model: AVAGO AVAGO (scsi)
Disk /dev/sdb: 18.0TB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags

(parted)

实验文件系统

有时候仅仅为了实验而插入新磁盘、扫描SCSI设备、再分区、格式化,整个过程挺麻烦的。

好在,有更为便捷的方式:

1
2
dd if=/dev/zero of=sdx bs=1M count=32
mke2fs sdx

现在sdx文件就是一个ext家族的文件系统了,相当于已经格式化的/dev/sdxN,它可以直接拿来挂载使用。

1
mount sdx /mnt/sdx

还可以使用mkisofs命令工具快速将目录创建成一个可挂载的镜像文件:

1
2
mkdir -p foo/bar/baz
mkisofs -o test.iso foo # 将foo打包成iso镜像

现在,test.iso镜像文件也可以直接挂载使用:

1
mount test.iso /mnt/test

查看文件系统状态信息

lsblk
lsblk(list block devices)用于列出设备及其状态,主要列出非空的存储设备。其实它只会列出/sys/dev/block中的主次设备号文件,且默认只列出非空设备。

1
2
3
4
5
6
7
8
9
[root@server2 ~]# lsblk /dev/sdb
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 20G 0 disk
├─sdb1 8:17 0 9.5G 0 part /mydata/data
└─sdb2 8:18 0 3G 0 part

[root@server2 ~]# lsblk /dev/sdb1
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb1 8:17 0 9.5G 0 part /mydata/data

其中上面的几列意义如下:

NAME:设备名称;

MAJ:MIN:主设备号和此设备号;

RM:是否为可卸载设备,1表示可卸载设备。可卸载设备如光盘、USB等。并非能够umount的就是可卸载的;

SIZE:设备总空间大小;

RO:是否为只读;

TYPE:是磁盘disk,还是分区part,亦或是rom,还有loop设备;

mountpoint:挂载点。

blkid
虽然它有不少比较强大的功能,但一般只用它一个功能,就是查看器文件系统类型和uuid。

1
2
3
4
5
6
7
8
9
[root@xuexi ~]# blkid
/dev/sda1: UUID="77b5f0da-b0f9-4054-9902-c6cdacf29f5e" TYPE="ext4"
/dev/sda2: UUID="f199fcb4-fb06-4bf5-a1b7-a15af0f7cb47" TYPE="ext4"
/dev/sda3: UUID="6ae3975c-1a2a-46e3-87f3-d5bd3f1eff48" TYPE="swap"
/dev/sdb1: UUID="95e5b9d5-be78-43ed-a06a-97fd1de9a3fe" TYPE="ext4"
/dev/sdb2: UUID="45da2d94-190a-4548-85bb-b3c46ae6d9a7" TYPE="ext2"

[root@xuexi ~]# blkid /dev/sdb1
/dev/sdb1: UUID="95e5b9d5-be78-43ed-a06a-97fd1de9a3fe" TYPE="ext4"

parted /dev/sda print和fdisk -l
虽然fdisk和gdisk分别是mbr和gpt格式的专用工具,但是仅用于查看信息还是可以的。parted能兼容两者,所以也可以。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
shell> parted /dev/sdb p
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 1049kB 10.2GB 10.2GB ext4
2 10.2GB 13.5GB 3221MB ext2 Linux filesystem

shell> fdisk -l /dev/sda
Disk /dev/sda: 21.5 GB, 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
Disk label type: dos
Disk identifier: 0x000cb657

Device Boot Start End Blocks Id System
/dev/sda1 * 2048 514047 256000 83 Linux
/dev/sda2 514048 37847039 18666496 83 Linux
/dev/sda3 37847040 41943039 2048000 82 Linux swap / Solaris

du
u命令用于评估文件的空间占用情况,它会统计每个文件的大小,统计时会递归统计目录中的文件,也就是说,它会遍历整个待统计目录,所以统计速度上可能并不理想。

1
2
3
4
5
6
7
8
9
10
11
12
13
du [OPTION]... [FILE]...
选项说明:
-a, --all:列出目录中所有文件的统计信息,默认只会列出目录中子目录的统计信息,而不列出文件的统计信息
-h, --human-readable:人性化显示大小
-0, --null:以空字符结尾,即"\0"而非换行的"\n"
-S, --separate-dirs:不包含子目录的大小
-s, --summarize:对目录做总的统计,不列出目录内文件的大小信息
-c,--total:对给出的文件或目录做总计。在统计非同一个目录文件大小时非常有用。见下文例子。
-d,--max-depth:指定显示时的目录深度,默认会递归显示所有层次
--max-depth=N:只列出给定层次的目录统计,如果N=0,则等价于"-s"
-x, --one-file-system:忽略不同文件系统上的文件,不对它们进行统计
-X, --exclude-from=FILE:从文件中读取要排除的文件
--exclude=PATTERN:指定要忽略不统计的文件

df

df用于报告磁盘空间使用率,默认显示的大小是1K大小block数量,也就是以k为单位。

和du不同的是,df是读取每个文件系统的superblock信息,所以评估速度非常快。由于是读取superblock,所以如果目录下挂载了另一个文件系统,是不会将此挂载的文件系统计入目录大小的。注意,du和df统计的结果是不一样的,如果对它们的结果不同有兴趣,可参考我的另一篇文章:详细分析du和df的统计结果为什么不一样。

如果用df统计某个文件的空间使用情况,将会转而统计该文件所在文件系统的空间使用情况。

1
2
3
4
5
6
7
8
df [OPTION]... [FILE]...
选项说明:
-h:人性化转换大小的显示单位
-i:统计inode使用情况而非空间使用情况
-l, --local:只列出本地文件系统的使用情况,不列出网络文件系统信息
-T, --print-type:同时输出文件系统类型
-t, --type=TYPE:只列出给定文件系统的统计信息
-x, --exclude-type=TYPE:指定不显示的文件系统类型的统计信息

mount

mount用来显示挂载信息或者进行文件系统挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
mount # 将显示当前已挂载信息
mount [-t 欲挂载文件系统类型 ] [-o 特殊选项] 设备名 挂载目录

选项说明:
-a 将/etc/fstab文件里指定的挂载选项重新挂载一遍。
-t 支持ext2/ext3/ext4/vfat/fat/iso9660(光盘默认格式)。 不用-t时默认会调用blkid来获取文件系统类型。
-n 不把挂载记录写在/etc/mtab文件中,一般挂载会在/proc/mounts中记录下挂载信息,然后同步到/etc/mtab,指定-n表示不同步该挂载信息。
-o 指定挂载特殊选项。下面是两个比较常用的:
loop 挂载镜像文件,如iso文件
ro 只读挂载
rw 读写挂载
auto 相当于mount -a
dev 如果挂载的文件系统中有设备访问入口则启用它,使其可以作为设备访问入口
default rw,suid,dev,exec,auto,nouser,async,and relatime
async 异步挂载,只写到内存
sync 同步挂载,通过挂载位置写入对方硬盘
atime 修改访问时间,每次访问都修改atime会导致性能降低,所以默认是noatime
noatime 不修改访问时间,高并发时使用这个选项可以减少磁盘IO
nodiratime 不修改文件夹访问时间,高并发时使用这个选项可以减少磁盘IO
exec/noexec 挂载后的文件系统里的可执行程序是否可执行,默认是可以执行exec, 优先级高于权限的限定
remount 重新挂载,此时可以不用指定挂载点。
suid/nosuid 对挂载的文件系统启用或禁用suid,对于外来设备最好禁用suid
_netdev 需要网络挂载时默认将停留在挂载界面直到加载网络了。使用_netdev可以忽略网络正常挂载。如NFS开机挂载。
user 允许普通用户进行挂载该目录,但只允许挂载者进行卸载该目录
users 允许所有用户挂载和卸载该目录
nouser 禁止普通用户挂载和卸载该目录,这是默认的,默认情况下一个目录不指定user/users时,将只有root能挂载

umount

1
2
umount 设备名或挂载目录
umount -lf 强制卸载

LVM相关概念和机制

PV(Physical Volume)即物理卷

硬盘分区后(还未格式化为文件系统)使用pvcreate命令可以将分区创建为pv,要求分区的system ID为8e,即为LVM格式的系统标识符。

VG(Volume Group)即卷组

将多个PV组合起来,使用vgcreate命令创建成卷组,这样卷组包含了多个PV就比较大了,相当于重新整合了多个分区后得到的磁盘。虽然VG是整合多个PV的,但是创建VG时会将VG所有的空间根据指定的PE大小划分为多个PE,在LVM模式下的存储都以PE为单元,类似于文件系统的Block。

PE(Physical Extend)

PE是VG中的存储单元。实际存储的数据都是存储在这里面的。

LV(Logical Volume)

VG相当于整合过的硬盘,那么LV就相当于分区,只不过该分区是通过VG来划分的。VG中有很多PE单元,可以指定将多少个PE划分给一个LV,也可以直接指定大小(如多少兆)来划分。划分为LV之后就相当于划分了分区,只需再对LV进行格式化即可变成普通的文件系统。

通俗地讲,非LVM管理的分区步骤是将硬盘分区,然后将分区格式化为文件系统。而使用LVM,则是在硬盘分区为特定的LVM标识符的分区后将其转变为LVM可管理的PV,其实PV仍然类似于分区,然后将几个PV整合为类似于磁盘的VG,最后划分VG为LV,此时LV就成了LVM可管理的分区,只需再对其格式化即可成为文件系统。

LE(logical extent)
PE是物理存储单元,而LE则是逻辑存储单元,也即为lv中的逻辑存储单元,和pe的大小是一样的。从vg中划分lv,实际上是从vg中划分vg中的pe,只不过划分lv后它不再称为pe,而是成为le。

将2块磁盘总空间“合二为一”并挂载到同一目录

创建物理卷

1
2
3
4
[root@MYSQL-SERVER ~]#  pvcreate /dev/sdb1
Physical volume "/dev/sdb1" successfully created.
[root@MYSQL-SERVER ~]# pvcreate /dev/sdc1
Physical volume "/dev/sdc1" successfully created.

创建卷组

1
2
[root@MYSQL-SERVER ~]#  vgcreate vgmysql /dev/sdb1
Volume group "vgmysql" successfully created

添加新的物理卷到卷组中
此步即为将2块磁盘空间合二为一的关键步骤;当系统中新增了磁盘或新建了物理卷,而要将其添加到已有卷组时,就可使用vgextend命令;

1
2
[root@MYSQL-SERVER ~]#  vgextend vgmysql /dev/sdc1
Volume group "vgmysql" successfully extended

查看卷组

1
2
3
4
[root@MYSQL-SERVER ~]#  vgs
VG #PV #LV #SN Attr VSize VFree
vgmysql 2 0 0 wz--n- 32.74t 32.74t
vgroot 1 4 0 wz--n- 264.00g 4.00m

创建逻辑卷

1
2
3
[root@MYSQL-SERVER ~]#  lvcreate -L 32.7T -n lvmysql vgmysql 
Rounding up size to full physical extent 32.70 TiB
Logical volume "lvmysql" created.

格式化逻辑卷

1
2
3
4
5
6
7
8
9
10
[root@MYSQL-SERVER ~]#  mkfs -t xfs /dev/vgmysql/lvmysql
meta-data=/dev/vgmysql/lvmysql isize=512 agcount=33, agsize=268435328 blks
= sectsz=4096 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=0, rmapbt=0, reflink=0
data = bsize=4096 blocks=8777839616, imaxpct=5
= sunit=64 swidth=64 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=521728, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0

创建挂载目录并挂载

1
2
3
4
5
挂载
mount /dev/vgmysql/lvmysql /mysql_data/

做开机自动挂载
echo '/dev/mapper/vgmysql-lvmysql /mysql_data xfs defaults 0 0' >/etc/fstab

参考文章

  1. https://www.cnblogs.com/daduryi/p/6619028.html
  2. https://www.cnblogs.com/wholj/p/10924129.html
  3. https://www.cnblogs.com/f-ck-need-u/p/7048971.html
  4. https://blog.csdn.net/s361260777/article/details/82631170
  5. https://www.cnblogs.com/f-ck-need-u/p/7049233.html