这一节主要介绍 Liunx 是怎么用磁盘的。

磁盘分区

在 Liunx 中一切皆文件,磁盘在 Liunx 中也是文件,包括 /dev/hd[a-d](以 IDE 为接口) 和 /dev/sd[a-p](以 SCSI/SATA/U盘) 等类型的磁盘设备文件名。
[root@test1 test]# ll /dev/ | grep sda
brw-rw----. 1 root disk 8, 0 Mar 12 22:45 sda
brw-rw----. 1 root disk 8, 0 Mar 12 22:45 sda1
brw-rw----. 1 root disk 8, 0 Mar 12 22:45 sda2
brw-rw----. 1 root disk 8, 0 Mar 12 22:45 sdb
(测试机1的磁盘设备文件名是 sda)
 
 
Liunx 开机启动的时候 BIOS 会读 CMOS 芯片里的参数,然后到 MBR(主引导分区)中执行引导加载程序,引导加载程序再读取内核文件从而启动操作系统。
这其中至关重要的 MBR 就放在磁盘的第一扇区。
第一扇区有 512 bytes,MBR 的大小是 446 bytes,还有 64 bytes 用来记录整块磁盘的分区表。由于每个分区需要 16 bytes 来记录,所以原则上只能记录 4 个分区。Liunx 引入扩展分区和逻辑分区的概念来解决这个问题。
如下图所示:
 
P1 是主分区,P2 是扩展分区,L1/L2/L7 是逻辑分区。其中,扩展分区的分区表是记录在非第一扇区中的。
它们对应的设备文件名是:
P1: /dev/sda1
P2: /dev/sda2
L1: /dev/sda5
L2: /dev/sda6
L3: /dev/sda7
 
sda1-sda4 是留给主分区和扩展分区用的,所以逻辑分区从 sda5 开始分配。
 
 
再看测试机1磁盘设备文件名为 /dev/sda,它有两个主分区 /dev/sda1 和 /dev/sda2,没有逻辑分区。
[root@test1 test]# ll /dev/ | grep sda
brw-rw----. 1 root disk 8, 0 Mar 12 22:45 sda
brw-rw----. 1 root disk 8, 1 Mar 12 22:45 sda1
brw-rw----. 1 root disk 8, 2 Mar 12 22:45 sda2
brw-rw----. 1 root disk 8, 0 Mar 12 22:45 sdb
磁盘设备 sdb 没有用到,通过 fdisk 命令在 sdb 上新增磁盘分区:
[root@test1 ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2). 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
Building a new DOS disklabel with disk identifier 0xd2793837. The device presents a logical sector size that is smaller than
the physical sector size. Aligning to a physical sector (or optimal
I/O) size boundary is recommended, or performance may be impacted. Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p):
Using default response p
Partition number (1-4, default 1):
First sector (2048-1875385007, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-1875385007, default 1875385007):
Using default value 1875385007
Partition 1 of type Linux and of size 894.3 GiB is set Command (m for help): w
The partition table has been altered! Calling ioctl() to re-read partition table.
Syncing disks.
[root@controller-0 sqg04]# partprobe
[root@controller-0 sqg04]# cd /dev/sd
sda sda1 sda2 sdb sdb1
 
现在 sdb 的主分区 sdb1 分出来了,记得分完区之后要用 partprobe 命令更新分区表,不然只能重启系统来更新分区表了。
 

文件系统

分完区的磁盘需要制成文件系统,才能成为 Liunx 可以使用的文件系统格式。
常见的文件系统类型有 ext2/ext3/ext4 和 nfs/gfs 等等。
通过 df 命令查看文件系统的信息:
# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 40G 4.7G 33G 13% /
tmpfs tmpfs 16G 20M 16G 1% /tmp
/dev/mapper/vol1-provider_ccs ext4 4.6G 22M 4.3G 1% /mnt/bricks/ccs
tmpfs tmpfs 294M 267M 28M 91% /mnt/rcpha/image
/dev/loop0 ext4 277M 125M 134M 49% /mnt/rcpha/etcd
example-5gbts-04-OAM-000.local:/mstate nfs4 477M 77M 371M 18% /mnt/mstate
sct-20a-12345678-oam-000.local:/services fuse.glusterfs 1.8G 234M 1.4G 15% /mnt/services
(测试机 2 有四种类型的文件系统:ext4/tmpfs/nfs4/fuse.glusterfs)
 
 
每种文件系统都有自己的“特色”。以 ext 系列文件系统举例,其示意图如下:
 
inode:记录文件的属性,一个文件占用一个 inode,同时记录此文件数据所在的 block 号码。
block:实际记录文件的内容,若文件太大时会占用多个 block。
 
启动扇区: 启动扇区中可以安装引导装载程序。
blockgroup:文件系统中的 inode 和 block 太多,不易管理。因此,将文件系统划分成多个 block group。每个 group 都是一个小“文件系统”,有独立的 inode 和 block,superblock 。
superblock:记录整个文件系统的信息,包括 inode / block 的总量/使用量/剩余量,以及文件系统的格式等信息。superblock 一般只会在第一个 group 有,在其它 group 如果有,则为此 block 的备份。
文件系统描述: 说明每个 block group 的开始和结束 block 号码,以及每个 block 区段分别介于哪个 block 之间。
块对应表: 记录使用与未使用的 block 号码。这样系统就知道哪块 block 没用到,可以把文件存在尚未使用到的 block 。
inode 对应表:和块对应表类似,记录使用与未使用的 inode 号码。
inode table:记录文件的属性和 block 的号码。文件的属性包括该文件的访问模式(r/w/x),文件的所有者与组,文件的大小,文件的创建时间等等。block 号码则是该文件存放在哪块 block 里,可以根据 inode table 的记录访问该文件的内容。
data block:存放文件的数据,一个 block 只能存放一个文件的数据。block 的大小有 1K/2K/4K 三种,如果存放的数据过小于 block 的大小则造成 block 的浪费,如果存放的数据大于 block 的大小即需要多个 block 来存放文件。
 
通过 mkfs 命令将磁盘分区 sdb1 制成文件系统,其中 -t 选项指定文件系统类型:
[root@test1 ~]# mkfs -t ext4 /dev/sdb1
mke2fs 1.42.9 (28-Dec-2013)
Discarding device blocks: done
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
58613760 inodes, 234422870 blocks
11721143 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2382364672
7155 block groups
32768 blocks per group, 32768 fragments per group
8192 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 Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

挂载点

文件系统做好之后,用户还是无法使用。因为 Liunx 中一切皆文件,做好的文件系统并不能用文件的形式呈现给用户,供用户使用。所以需要对文件系统进行挂载,挂载就是提供用户一个目录入口,通过该目录入口来访问文件系统。
 
通过 mount 命令进行挂载。首先创建挂载目录,目录最好是空的,如果不是空的,挂载上的文件系统会把原来目录文件的内容隐藏掉。然后将文件系统 /dev/sdb1 挂载到该目录:
[root@test1 home]# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 xfs 895G 848G 47G 95% /
[root@test1 home]# mount /dev/sdb1 /home/test
[root@test1 home]# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 xfs 895G 848G 47G 95% /
/dev/sdb1 ext4 881G 77M 836G 1% /home/test
 
现在可以通过读写 /home/test 目录来访问文件系统,从而实现在磁盘中存取数据。

文件系统实例

通过 dumpe2fs 命令查看 ext 系列文件系统的内容:
[root@test2:/home/robot]
# dumpe2fs /dev/vda1
dumpe2fs 1.45.5 (07-Jan-2020)
Filesystem volume name: rootfs # 文件系统的名称(Label)
Last mounted on: /sysroot
Filesystem UUID: 18b9201d-3a23-4c98-ab26-7b52c342da23
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean # 文件系统的状态没问题
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 2621440 # 总的 inode 数目
Block count: 10485499 # 总的 block 数目
Reserved block count: 450842
Free blocks: 9018609
Free inodes: 2580673
First block: 0
Block size: 4096
Fragment size: 4096
Group descriptor size: 64
Reserved GDT blocks: 763
Blocks per group: 32768 # 每个 group 有多少个 block
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512 # 每个 group 有多少个 inode
Flex block group size: 16
Filesystem created: Wed Feb 12 16:09:19 2020
Last mount time: Fri Mar 13 14:25:56 2020
Last write time: Fri Mar 13 14:25:56 2020
Mount count: 8
Maximum mount count: -1
Last checked: Thu Feb 13 09:58:45 2020
Check interval: 0 (<none>)
Lifetime writes: 12 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 32
Desired extra isize: 32
Journal inode: 8
First orphan inode: 262571
Default directory hash: half_md4
Directory Hash Seed: 35426ac6-7885-4c68-9f84-f5d639422c77
Journal backup: inode blocks
Journal features: journal_incompat_revoke journal_64bit
Journal size: 64M
Journal length: 16384
Journal sequence: 0x00008261
Journal start: 5725 Group 0: (Blocks 0-32767) csum 0x2580 [ITABLE_ZEROED]
Primary superblock at 0, Group descriptors at 1-5 # superbock
Reserved GDT blocks at 6-768
Block bitmap at 769 (+769)
Inode bitmap at 785 (+785)
Inode table at 801-1312 (+801)
20030 free blocks, 808 free inodes, 878 directories
Free blocks: 9036-9759, 10152-10173, 10766, 10769, 10771-10773, 13489-32767
Free inodes: 264-783, 803, 1270-1289, 1326-1336, 1346-1361, 1381-1390, 1430-1468, 1619-1634, 1650-1662, 2408-2471, 2687-2713, 2741-2791, 2826-2834, 2868-2878
Group 1: (Blocks 32768-65535) csum 0x0061 [ITABLE_ZEROED]
Backup superblock at 32768, Group descriptors at 32769-32773 # backup superblock
Reserved GDT blocks at 32774-33536
Block bitmap at 770 (bg #0 + 770)
Inode bitmap at 786 (bg #0 + 786)
Inode table at 1313-1824 (bg #0 + 1313)
1971 free blocks, 2605 free inodes, 638 directories, 2374 unused inodes
Free blocks: 35584-35647, 35712-35791, 35812-35839, 35968-36031, 36120-36127, 36160-36163, 36234-36236, 36332-36543, 36573-36591, 36611, 36622-36635, 36725-36831, 36863, 36896-37375, 38010, 38020-38021, 38023-38034, 38037-38038, 38040-38046, 38048-38050, 38053-38911
Free inodes: 8380, 8425, 8749-8765, 8862-8864, 8867-8869, 8871-8872, 8874-8875, 8877-8912, 8968, 8971, 8974, 8996-9020, 9024-9047, 9049-9062, 9247, 9277-9294, 9823, 10168-10209, 10809-10811, 11341, 11395-11396, 13426-13428, 13436-13446, 13453, 13455, 13994-14009, 14011-16384
ls 的 -i 选项可以查看文件使用的 inode 号码:
[root@test1:/home/robot]
# touch fileSystem.log
[root@example-5gbts-04-OAM-000:/home/robot]
# ll -hi
total 0
524586 -rw-r--r-- 1 root root 0 Mar 15 11:03 fileSystem.log
(文件 fileSystem.log 的 inode 号码是 524586)
 
 
目录在文件系统中也由 inode 和 block 组成。
目录的 inode 记录着目录下文件的权限/所有者等信息,目录的 block 则记录着目录下文件/目录的 inode 号码。
通过 ls 的 -d 和 -i 选项可以查看目录的 inode 号码:
[root@test1:/home/robot]
# ll -di test/
656226 drwxr-xr-x 2 root root 4096 Mar 15 11:30 test/
(目录 test 的 inode 号码是 656226)
 
 
介绍 Liunx 中软链接和硬链接的概念以加深对 inode 和 block 的理解。
先用 ln 命令造出链接文件, -s 选项指定链接文件为软链接文件:
[root@test1:/home/robot/test]
# ll -di /home/robot/test/
656226 drwxr-xr-x 2 root root 4096 Mar 15 11:36 /home/robot/test/
[root@test1:/home/robot/test]
# ln -s fileSystem.log fileSystem_sln.log
[root@test1:/home/robot/test]
# ln fileSystem.log fileSystem_hln.log
[root@test1:/home/robot/test]
# ll -i
total 0
524586 -rw-r--r-- 2 root root 0 Mar 15 11:03 fileSystem_hln.log
524586 -rw-r--r-- 2 root root 0 Mar 15 11:03 fileSystem.log
656227 lrwxrwxrwx 1 root root 14 Mar 15 11:36 fileSystem_sln.log -> fileSystem.log
 
软链接:
软链接中,链接文件 fileSystem._sln.log 的 block 记录的是被链接文件的 inode,被链接文件的 block 记录的是真实数据的 inode 号码,根据该 inode 号码来指向真实的数据。所以删掉 fileSystem.log 文件,软链接文件会提示找不到文件。
 
硬链接:
硬链接中,链接文件 fileSystem_hln.log 的 block 记录的是真实数据的 inode 号码,被链接文件的 block 记录的也是真实数据的 inode 号码。所以删掉被链接文件 fileSystem.log 依然能够访问链接文件。
 
系统读取 fileSystem.log 文件过程:
[root@test1:/home/robot/test]
# ll -di / /home/ /home/robot/ /home/robot/test/
2 drwxr-sr-x 20 root root 4096 Mar 13 14:27 /
8197 drwxr-xr-x 5 root root 4096 Mar 13 14:27 /home/
524372 drwxr-xr-x 4 robot root 4096 Mar 15 11:36 /home/robot/
656226 drwxr-xr-x 2 root root 4096 Mar 15 11:36 /home/robot/test/
[root@test1:/home/robot/test]
# ll -hi
total 0
524586 -rw-r--r-- 2 root root 0 Mar 15 11:03 fileSystem_hln.log
524586 -rw-r--r-- 2 root root 0 Mar 15 11:03 fileSystem.log
656227 lrwxrwxrwx 1 root root 14 Mar 15 11:36 fileSystem_sln.log -> fileSystem.log
 
系统通过挂载点信息 /dev/vda1 读根目录 / 的 inode 号码 2。 其中,inode 记录着用户/用户组的权限。
系统判断用户具有读文件权限,继续读 / 的 block ,block 中记录的 home 目录的 inode 号码 8197。
读取 home 目录的 block 内容读到 robot 用户的 inode 号码 524372。
继续读取 robot 目录的 block 内容读到 test 目录的 inode 号码 656226。
读取 test 目录的 block,发现 block 中有文件 fileSystem_hln.log 的 inode 号码。
读取 fileSystem_hln.log 的 block 内容,从而获取到文件的内容。
 
 
(完)

每天学五分钟 Liunx 100 | 存储篇:磁盘分区的更多相关文章

  1. 如何从40亿整数中找到不存在的一个 webservice Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库 WPF实战案例-打印 RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange

    如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...

  2. 五分钟学Java:如何才能学好Java Web里这么多的技术

    原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 系列文章介绍 本文是<五分钟学Java>系列文章的一篇 本系列文章主要围绕Java程序员必须掌握的核心技能,结合我个人三年 ...

  3. 零元学Expression Blend 4 - Chapter 42 五分钟快速完成扇形变圆形动画

    原文:零元学Expression Blend 4 - Chapter 42 五分钟快速完成扇形变圆形动画 零元学Expression Blend 4 - Chapter 42 五分钟快速完成扇形变圆形 ...

  4. 《sed的流艺术之一》-linux命令五分钟系列之二十一

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  5. 五分钟搭建一个基于BERT的NER模型

    BERT 简介 BERT是2018年google 提出来的预训练的语言模型,并且它打破很多NLP领域的任务记录,其提出在nlp的领域具有重要意义.预训练的(pre-train)的语言模型通过无监督的学 ...

  6. GC算法精解(五分钟让你彻底明白标记/清除算法)

    GC算法精解(五分钟让你彻底明白标记/清除算法) 相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底 ...

  7. zookeeper-架构设计与角色分工-《每日五分钟搞定大数据》

    本篇文章阅读时间5分钟左右 点击看<每日五分钟搞定大数据>完整思维导图   zookeeper作为一个分布式协调系统,很多组件都会依赖它,那么此时它的可用性就非常重要了,那么保证可用性的同 ...

  8. 「每日五分钟,玩转JVM」:线程共享区

    前言 上一篇中,我们了解了JVM中的线程独占区,这节课我们就来了解一下JVM中的线程共享区,JVM中的线程共享区是跟随JVM启动时一起创建的,包括堆(Heap)和方法区()两部分,而线程独占区的程序计 ...

  9. 五分钟搞定 HTTPS 配置,二哥手把手教

    01.关于 FreeSSL.cn FreeSSL.cn 是一个免费提供 HTTPS 证书申请.HTTPS 证书管理和 HTTPS 证书到期提醒服务的网站,旨在推进 HTTPS 证书的普及与应用,简化证 ...

  10. Python专题——五分钟带你了解map、reduce和filter

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题第6篇文章,给大家介绍的是Python当中三个非常神奇的方法:map.reduce和filter. 不知道大家看到ma ...

随机推荐

  1. MySQL日期时间加|减法

    日期加法 select date_add(curdate(), interval N SECOND); -- 加N秒 select date_add(curdate(), interval N MIN ...

  2. Maven仓库settings.xml配置信息

    找到你的settings.xml配置文件E:\maven3.6.3\apache-maven-3.6.3\conf # 你的本地依赖仓库路径 <localRepository>E:\mav ...

  3. MySQL运维7-Mycat水平分表

    一.水平分表场景 在业务系统中,有一张日志表,业务系统每天都会产生大量的日志数据,单台服务器的数据存储即处理能力是有限的,可以对数据库表进行拆分,这时候就可以使用水平分表的策略 说明1:水平分表,每个 ...

  4. Celery架构和主要模块

    **任务模块 ** 包含异步任务和定时任务.其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列. **消息中间件 Broker * ...

  5. C# 获取另一程序控件,改变值,触发事件

    [DllImport("User32.dll", EntryPoint = "FindWindow")]private static extern IntPtr ...

  6. Python——第二章:字符串操作——索引和切片

    索引: 按照位置提取元素 可以采用索引的方式来提取某一个字符(文字) s = "我叫周杰伦" print(s[3]) #程序员都是从0开始数,这里的3代表第4位,也就是" ...

  7. 文心一言 VS 讯飞星火 VS chatgpt (46)-- 算法导论6.1 4题

    四.假设一个最大堆的所有元素都不相同,那么该堆的最小元素应该位于哪里? 文心一言: 最大堆的最小元素位于堆的根结点.由于最大堆的性质,根结点是堆中所有元素的最大值,因此它也是堆中所有元素的最小值. 讯 ...

  8. 干货分享丨轻松玩转 Huawei LiteOS 传感框架

    摘要:LiteOS传感框架将物联网终端设备上不同类型的传感器统一管理,通过抽象不同类型传感器接口,屏蔽其硬件细节,做到"硬件"无关性,非常方便于物联网设备的开发.维护和功能扩展. ...

  9. EDS从小白到专家丨打造你的专属“数据物流”系统

    "数据快递"如何支撑便捷就医?本期让我们来了解如何使用EDS打造专属的"数据物流"系统...... 本文分享自华为云社区<[EDS从小白到专家]第2期-E ...

  10. 15年了,我们到底怎样才能用好 Serverless?

    摘要:Serverless能够给企业客户和开发者带来非常直观的收益,包括成本节约和效率提升. 作者:冯嘉 一.Serverless发展历程及现状 1.1.Serverless概念 通常意义上来讲,Se ...