下面的命令操作以及示例主要是针对Ubuntu
系统
CPU
常见概念与查询
时钟速度
CPU
时钟速度越高,CPU
运行速度越快- 时钟速度则测量
CPU
每秒执行的周期数,以GHz
(千兆赫)为单位 - 周期是由内部振荡器同步的脉冲,举例,时钟速度为
3.2 GHz
的CPU
每秒执行 32 亿个周期 CPU
规格中会列出最大睿频和处理器基本频率,处理器基本频率是指CPU
的正常运行速度,而最大睿频是指处理器采用睿频加速技术后可以达到的最高速度
下图来源于Intel
时钟速度说明
超线程技术
CPU
架构当中包含两个最主要的模块Processing Unit
(运算处理单元,PU
),负责实际的运算,如加减乘除,是实际干活的Architectual State
(架构状态单元,AS
),执行逻辑和调度方面操作,分配运算任务给PU
- 超线程技术
Hyper-threading
,是硬件架构层的多线程,通过调整AS
模拟出来一个逻辑核,最终实现一个物理核里面有两个AS
,一个PU
开启超线程技术的优缺点
优点
CPU
利用率增高:使用更多资源去执行调度,接收任务,提高PU
的使用效率- 并行能力增强:处理多进程/线程的能力加强,对于支持多线程的程序比较明显
缺点
- 单核性能下降: 对于单线程程序来说,两个
AS
的开销大于一个AS
的(程序在选择AS
上面存在开销)
开启超线程技术后,单个物理核的时钟周期还是一样的,所以对于整个CPU
的运算能力的计算方式还是
整个CPU运算能力 = 物理核心数量 * 每个核心最大睿频频率
或者
= 物理核心1的最大睿频频率 + 物理核心2的最大睿频频率 + ....
目前CPU
的发展主要朝着多核方向,主频和最大睿频提升幅度不大,但是核心越来越多,目前最新的12代core i7,i9
的还有性能核(超线程,最大睿频频率较高)和能效核(单线程)这种架构
CPU
信息查询
使用lscpu
命令查询结果如下
$ lscpu
// --snip--
CPU: 12
在线 CPU 列表: 0-11
厂商 ID: GenuineIntel
型号名称: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
CPU 系列: 6
型号: 158
每个核的线程数: 2
每个座的核数: 6
座: 1
步进: 10
CPU 最大 MHz: 4500.0000
CPU 最小 MHz: 800.0000
// --snip--
从结果输出知道CPU
的型号是Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
,可以知道是属于Core
系列i7
的9代
的针对移动设备进行优化的CPU
,基础频率是2.6GHz
,产品型号每个参数所表示的意思可以参考Intel
处理器编号和名称
该CPU
是6核12线设计,最大频率是4.5GHz
,最低频率是0.8GHz
也可以通过cat /proc/cpuinfo
具体每个系统所识别到的CPU
信息,一般系统会识别到AS
(逻辑核)的数量作为CPU
的总数
服务器一般会使用Xeon
系列的处理器,具体处理计算性能和Core
一样
内存相关
内存信息查询
一般使用内存的时候主要关心内存大小,内存频率就不考虑了
$ free -hw
total used free shared buffers cache available
内存: 31Gi 11Gi 5.4Gi 1.0Gi 867Mi 13Gi 18Gi
交换: 27Gi 0B 27Gi
第一行内存数据参数
total
: 系统总的可以使用的物理内存大小,该值是used + free + buff/cache
的总和used
: 系统已经被使用的物理内存大小free
: 系统还有多少内存可以被使用,系统还未分配出去的内存,真正尚未被使用的物理内存数量shared
: 被多个进程共享使用的内存的大小buffers
:- 被
buff
所使用的物理内存大小,表示linux
内存中的Buffer cache
,缓冲区缓存,主要提高写磁盘的效率 - 设计用来在系统对块设备进行读写的时候,对块进行数据缓存的系统来使用
- 块设备是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或者从设备一次性读到缓冲区
- 在写磁盘的时候,数据会先写入
buffer
,后台会有一个sync
(该命令可以手动执行)程序周期性的去把buffer
中的数据刷新到磁盘,并且释放对应的buffer
- 被
cache
:- 被
cache
所使用的物理内存大小,表示linux
内存中的Page cache
,页面缓存,主要提高读磁盘的效率 - 用来作为文件系统上的文件数据的缓存来用,当进程对文件进行读写的时候把文件映射到内存当中进行操作
- 对于
buffers
和cache
的解释有很多,需要自行去学习
- 被
available
- 可以被应用程序所使用的物理内存大小,应用程序认为可用内存数量
- 对于内核来说,
buff/cache
所占用的资源都是已经被分配出去的,对于应用程序来说,申请内存的时候如果空闲内存不够,内核会回收buff/cache
的内存 - 该参数的计算方式是
free + buff/cache
或者total - used
,实际该值的结果会比计算出来的小一点
第二行交换空间数据参数和第一行的一致,但是这部分空间是磁盘上的
cache
内存的释放
- 在内存够用的时候
cache
内存的使用会加快进程对文件的读写速度,所以在内存压力较大的情况下,有必要清空释放cache
- 内核会在内存将要耗尽的时候,触发
buffer/cache
内存回收的工作,以便释放出内存给急需内存的进程使用 - 内核会对比
cache
中的数据和对应硬盘文件上的数据是否一致,如果不一致需要写回,之后才能回收,在释放cache
内存的时候,系统磁盘IO
会大幅度升高
手动回收内存
# 先把buffer当中的数据同步到磁盘上面
$ sync
# 触发回收内存操作,参数3表示清除pagecache和slab分配器中的缓存对象
$ echo 3 > /proc/sys/vm/drop_caches
上述操作执行完成之后再次执行内存查看命令,可以发现有将近10G
的内存释放
$ free -wh
total used free shared buffers cache available
内存: 31Gi 10Gi 16Gi 1.0Gi 14Mi 3.8Gi 18Gi
交换: 27Gi 0B 27Gi
系统基本信息获取
使用工具inxi
, 项目地址
安装
$ sudo apt install inxi
获取信息,-F
参数指定获取所有检测信息
$ inxi -F
System: Host: gong Kernel: 4.15.0-112-generic x86_64 bits: 64 Console: tty 0 Distro: Ubuntu 18.04.6 LTS
Machine: Device: desktop Mobo: N/A model: NSB5171C v: G769-032 serial: N/A
UEFI: American Megatrends v: 5.12 (G769-032) date: 05/11/2020
CPU: Quad core Intel Core i5-6500 (-MCP-) cache: 6144 KB
clock speeds: max: 3200 MHz 1: 3200 MHz 2: 3200 MHz 3: 3200 MHz 4: 3200 MHz
Graphics: Card: Intel HD Graphics 530
Display Server: N/A driver: i915 tty size: 150x35 Advanced Data: N/A for root out of X
Network: Card-1: Intel I210 Gigabit Network Connection driver: igb
IF: enp5s0 state: up speed: 1000 Mbps duplex: full mac: cc:d3:9d:9f:d5:1d
Card-2: Intel I210 Gigabit Network Connection driver: igb
IF: enp6s0 state: down mac: cc:d3:9d:9f:d5:1e
Card-3: Intel I210 Gigabit Network Connection driver: uio_pci_generic
IF: N/A state: N/A speed: N/A duplex: N/A mac: N/A
Card-4: Intel I210 Gigabit Network Connection driver: uio_pci_generic
IF: N/A state: N/A speed: N/A duplex: N/A mac: N/A
Card-5: Intel I210 Gigabit Network Connection driver: uio_pci_generic
IF: N/A state: N/A speed: N/A duplex: N/A mac: N/A
Card-6: Intel I210 Gigabit Network Connection driver: uio_pci_generic
IF: N/A state: N/A speed: N/A duplex: N/A mac: N/A
Drives: HDD Total Size: 2064.4GB (4.0% used)
ID-1: /dev/sda model: ST2000NM0055 size: 2000.4GB
ID-2: /dev/sdb model: TS64GSSD420K size: 64.0GB
Partition: ID-1: / size: 1.8T used: 69G (4%) fs: ext4 dev: /dev/sda4
ID-2: /boot size: 2.0G used: 84M (5%) fs: ext4 dev: /dev/sda3
ID-3: swap-1 size: 8.59GB used: 0.00GB (0%) fs: swap dev: /dev/sda2
RAID: No RAID devices: /proc/mdstat, md_mod kernel module present
Sensors: System Temperatures: cpu: 36.5C mobo: 29.8C
Fan Speeds (in rpm): cpu: N/A
Info: Processes: 281 Uptime: 69 days Memory: 5668.0/7894.5MB Init: systemd runlevel: 5
Client: Shell (bash) inxi: 2.3.56
系统状态监控
对于大部分web
项目来说,很多性能瓶颈都是出现在数据库上面,数据库的瓶颈是在磁盘IO
上面
下面会使用工具iotop
和iostat
iostat
使用
该工具主要反映系统当前的CPU
和磁盘的整体状态,方便快速定位系统瓶颈
项目地址
安装
$ sudo apt install sysstat
之后执行如下命令,-c
表示只显示CPU
状态信息,3
表示每3s
刷新一下结果
$ sudo iostat -c 3
Linux 5.15.0-56-generic (gong) 2022年12月05日 _x86_64_ (12 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
7.83 0.01 2.69 0.18 0.00 89.30
输出参数
% user
:CPU
处在用户模式下的时间百分比% nice
:CPU
处在带NICE
值的用户模式下的时间百分比% system
:CPU
处在系统模式下的时间百分比% iowait
:等待输入输出完成时间的百分比,值很高,表示硬盘存在 磁盘I/O
瓶颈% steal
:管理程序维护另一个虚拟处理器时,虚拟CPU
的无意识等待时间百分比% idle
:空闲时间百分比,值如果很高,表示CPU
较空闲,同时也可能反映磁盘IO
速度不行
执行如下命令,-d
表示只显示磁盘状态
$ iostat -d 3
Linux 5.15.0-56-generic (gong) 2022年12月05日 _x86_64_ (12 CPU)
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
tps
:该设备每秒的传输次数,一次传输是一次I/O
请求,多个逻辑请求可能会被合并为一次I/O
请求,一次传输请求的大小是未知的kB_read/s
:每秒从设备读取的数据量kB_wrtn/s
:每秒向设备写入的数据量kB_read
:读取的总数据量kB_wrtn
:写入的总数量数据量
iotop
使用
项目地址
安装
$ sudo apt install iotop
执行命令
$ sudo iotop
Total DISK READ: 0.00 B/s | Total DISK WRITE: 0.00 B/s
Current DISK READ: 0.00 B/s | Current DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
1 be/4 root 0.00 B/s 0.00 B/s ?unavailable? init splash
2 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [kthreadd]
3 be/0 root 0.00 B/s 0.00 B/s ?unavailable? [rcu_gp]
4 be/0 root 0.00 B/s 0.00 B/s ?unavailable? [rcu_par_gp]
5 be/0 root 0.00 B/s 0.00 B/s ?unavailable? [netns]
7 be/0 root 0.00 B/s 0.00 B/s ?unavailable? [kworker/0:0H-events_highpri]
9 be/0 root 0.00 B/s 0.00 B/s ?unavailable? [mm_percpu_wq]
10 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [rcu_tasks_rude_]
11 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [rcu_tasks_trace]
12 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [ksoftirqd/0]
13 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [rcu_sched]
14 rt/4 root 0.00 B/s 0.00 B/s ?unavailable? [migration/0]
15 rt/4 root 0.00 B/s 0.00 B/s ?unavailable? [idle_inject/0]
17 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [cpuhp/0]
18 be/4 root 0.00 B/s 0.00 B/s ?unavailable? [cpuhp/1]
19 rt/4 root 0.00 B/s 0.00 B/s ?unavailable? [idle_inject/1]
Total DISK READ
和Total DISK WRITE
表示进程和内核线程之间的,内核块设备子系统的总的读写速度
Current DISK READ
和Current DISK WRITE
表示实际磁盘 I/O
读写速度
可以使用左右按键调整排序,找到最大读写速度的进程,如果磁盘最大的随机读写速度是100MB/S
,数据库某个查询请求占用了80MB/S
的速度读取磁盘,那么其他请求就只剩下一点点磁盘速度了,这个是导致数据库查询经常时间差距非常大的一个原因
磁盘性能测试
使用工具fio
,项目地址
安装
$ sudo apt install fio
fio
中参数解释
-filename=
- 该参数不要使用,超级坑,网络上有很多教程都是说要指定这个参数,所以我们要知道这个参数,并且一定要避开这个雷
- 如果刚好指定了参数是系统盘[根分区或者/boot分区]的话,请直接重装系统吧
- 如果是数据盘的话,就可以准备格式化了
- 本人已经付出惨痛的代价,请使用-directory参数,使得程序读写数据的时候限制在某个文件夹内
- 这个出现问题是随机的,可能这一次执行的时候重启机器后没问题,可能下一次就出问题了
- 这个参数使用的时候会指定测试磁盘名称,指定某个要测试的裸设备,切勿在系统分区做测试,会破坏系统分区,而导致系统崩溃,参数比如
/dev/sda
,/dev/sdb2
- 假设现在已经指定了
/dev/sda
参数,fio
程序执行的时候直接从第一个扇区随机写入数据,但是每块硬盘分区的前面几个扇区是非常重要的,包含了该块硬盘的扩展引导程序,分区标志,该块分区的文件类型等重要的数据
-directory=
: 指定测试文件夹的位置,可以先创建一个文件夹,比如/home/test-files
,然后指定-directory=/home/test-files
,这样fio
的读写就会限制在固定位置了-direct=
:Linux
在读写时,数据会先写到缓存,再在后台写到硬盘,读的时候也是优先从缓存中读,这样访问速度会加快,但是一旦掉电,缓存中数据就会清空,一种模式为DirectIO
,可以跳过缓存,直接读写硬盘,为了绕开这个优化,使得测试结果更加真实,需要设置该参数为1
-ioengine=
:io
引擎选择,可选项有libaio
(Linux
本地异步I/O
),rdb
(通过librbd
直接访问CEPH Rados
),推荐配置为libaio
-iodepth=
: 配置发送命令队列深度,防止测试时候占用太多内存导致系统崩溃,推荐配置为16
-bs=
: 配置单次io
块的大小,测试的时候需要把该参数多次配置为4k
,16k
,256k
等参数,用于测试在不同文件大小下面的读写速度-numjobs=
: 测试使用的线程数量,依据机器性能配置,推荐配置为与机器物理核心相同的数量-size=
: 配置每个线程读写的数量大小,推荐配置为1G
以上,5G
左右比较合适-runtime=
: 配置测试时间,单位是秒,如果不配置该项,size
配置的值全部读完或者写完之后程序才会退出-rw=
: 读写模式配置,可选项randread
(随机读),randwrite
(随机写),randrw
(随机混合读写),read
(顺序读),write
(顺序写),rw
(顺序读写)-rwmixwrite=
: 混合读写模式下面的写的占比,可选值0-100,比如配置为30,那么写占据30,读占据70,该参数和rwmixread
相对,只配置一个就行-thread
和-fork
:两个参数无配置值,声明即可,-thread
表示使用创建线程测试,推荐采用该参数-group_reporting
: 表示汇总每个测试的信息,该参数只声明即可-name
: 定义测试任务名称-lockmem=
:定义测试使用的最大内存,可以配置为1g
安装与获取文档
需要依赖gcc
$ sudo apt install gcc
从源码构建与安装
$ git clone https://github.com/axboe/fio.git
$ cd fio
$ ./configure
$ make
$ sudo make install
创建文档,需要依赖sphinx
$ sudo apt install python3-sphinx
$ make -C doc html
之后在浏览器中访问对应的首页即可,访问地址如下,效果如下
file://${此处替换为项目的绝对路径}/doc/output/html/index.html
使用
检测前需要使用iotop
命令查看是否有其他进程占用较大的磁盘速度,如果有需要把那些程序关闭,以免影响测试结果,执行测试命令需要root
本次测试采用的是一块固态硬盘
测试磁盘/dev/sda
(可以通过fdisk -l
命令查看),测试使用文件夹位置是/home/test-file
的性能,随机读,总测试文件大小为5G
,测试块文件大小为4k
,使用双线程测试
$ fio -directory=/home/test-file -direct=1 -ioengine=libaio \
-bs=4k -size=5G -numjobs=2 -iodepth=16 -thread -rw=randread \
-group_reporting -name="5G_4KB_randread_test" -lockmem=1G
# 由于输出比较多,所以下面逐行分析输出
# rw参数表示运行模式是随机读,测试块文件大小是4k,该行主要是对输入命令的关键信息等打印
5G_4KB_randread_test: (g=0): rw=randread, bs=(R) 4096B-4096B,
(W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=16
...
# fio版本为3.28,尽量使用最新版本,以免下面输出参数缺少
fio-3.28
Starting 2 threads
# 开启两个线程,每个线程会使用-size配置的数据
5G_4KB_randread_test: Laying out IO file (1 file / 5120MiB)
5G_4KB_randread_test: Laying out IO file (1 file / 5120MiB)
# 开启线程的多少和顺序读写,随机读写无关系,对用户而言,线程参数只表示重复执行测试任务几次
# [100%]表示测试100%完成
# r=143MiB/s表示读的次数是143MiB,如果是测试写的话,该参数会是w=???MiB/s
# r=36.6k IOPS,全称Input/Output Operations Per Second,表示每秒的读次数
# 意味着每秒有36.6K次的读操作完成
# 该次执行的测试块大小是4K,所以也可以使用计算方式如下:随机读速度 = 测试块大小 * IOPS大小
Jobs: 2 (f=2): [f(2)][100.0%][r=143MiB/s][r=36.6k IOPS][eta 00m:00s]
# 上面的数据已经足够知道磁盘读写性能了,下面的数据是扩展,了解即可
# 下面参数当中通用的字段含义:
# min-最小,max-最大,avg-平均,stdev-标准差,samples-样本数
# usec表示时间单位/微秒,msec表示时间单位/毫秒
5G_4KB_randread_test: (groupid=0, jobs=2): err= 0: pid=1304003: Fri Dec 9 14:46:54 2022
# 表示对读性能的分组标识,如果是测试写性能,则该参数是write
# 由于我们采用两个线程进行任务,同时配置了测试文件总大小为5G,
# 所以总的读的磁盘文件是10G,每个线程都读了5G的磁盘
# 读取10G磁盘总共耗时71.486秒
read: IOPS=36.7k, BW=143MiB/s (150MB/s)(10.0GiB/71486msec)
# slat:提交延迟,这是提交I/O所花费的时间
slat (usec): min=2, max=996, avg= 4.61, stdev= 4.55
# clat: 完成延迟,提交之后,处理所花的时间
clat (usec): min=40, max=1141.2k, avg=867.03, stdev=5649.13
# 响应时间
lat (usec): min=43, max=1141.2k, avg=871.72, stdev=5649.52
# percentiles: 在性能测试中表示Top Percentile,简写TP,是一个统计学中的术语,与平均数,中位数等是同一类
# 常见的参数是TP50, TP80, TP95
# 举例:TP95:统计该方法每次调用所消耗的时间,并将这些时间按从小到大的顺序进行排序,取第95%的那个值作为TP95的值
# 如下看到TP95的值是2057,则表示完成延迟的所有测试统计数据中,95%的测试消耗时间都是小于2057微秒,TP95=2057微秒
clat percentiles (usec):
| 1.00th=[ 306], 5.00th=[ 334], 10.00th=[ 359], 20.00th=[ 408],
| 30.00th=[ 445], 40.00th=[ 482], 50.00th=[ 515], 60.00th=[ 553],
| 70.00th=[ 594], 80.00th=[ 660], 90.00th=[ 1270], 95.00th=[ 2057],
| 99.00th=[13698], 99.50th=[15139], 99.90th=[18482], 99.95th=[21365],
| 99.99th=[69731]
# bw: 磁盘带宽统计
bw ( KiB/s): min= 2304, max=244152, per=100.00%, avg=149114.40, stdev=43253.75, samples=280
# IOPS: 全称Input/Output Operations Per Second, 表示每秒的读/写次数
# 由于处于read分组下面,所以在这边表示为读的次数
iops : min= 576, max=61038, avg=37278.60, stdev=10813.44, samples=280
# 响应时间的latency分布信息,从最低延迟微秒逐步统计到以毫秒作为基本单位的延迟分布情况
# 目测了一下,下面整块的分布百分比全部加起来是100%
# 举例:下面的750=40.05%表示有40.05%的延迟是小于750微秒,但是大于500微秒
# 举例:下面的4=4.44% 表示有4.44%的延迟小于4毫秒但是大于2毫秒
lat (usec) : 50=0.01%, 100=0.01%, 250=0.27%, 500=45.53%, 750=40.05%
lat (usec) : 1000=2.75%
lat (msec) : 2=5.64%, 4=4.44%, 10=0.09%, 20=1.17%, 50=0.05%
lat (msec) : 100=0.01%, 250=0.01%, 1000=0.01%, 2000=0.01%
# cpu信息统计 usr:用户态CPU占用率,sys:系统CPU占用率,ctx:进程上下文切换次数
# majf:major page faults 主要页面错误数量, minf: minor page faults 次要页面错误数量
cpu : usr=4.72%, sys=10.22%, ctx=2082417, majf=0, minf=34
# IO depths: I/O深度在测试中的分布,控制同一个时刻有多少IO发送给系统
# 该输出和命令执行时候的-iodepth参数有关
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
# submit和complete代表同一时间段内fio发送和已完成的IO数量
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
# issued rwt: 发出的read/write/trim(裁剪)请求的数量,以及其中有多少请求被缩短或删除
# 这个地方和官方文档上对不上,官方文档只有三个参数0,0,0,目前第四个参数位置意思不详
issued rwts: total=2621440,0,0,0 short=0,0,0,0 dropped=0,0,0,0
# 下面一行取决于命令执行配置的参数latency_target,latency_window,latency_percentile
# 下面percentile=100% 表示该最大限度的使用磁盘速度
latency : target=0, window=0, percentile=100.00%, depth=16
Run status group 0 (all jobs):
# bw: 该组中线程的总带宽,后跟该组中所有线程的最小和最大带宽
# io: 该组中所有线程执行的聚合I/O
# run:这组线程中最小和最长的运行时间统计
READ: bw=143MiB/s (150MB/s), 143MiB/s-143MiB/s (150MB/s-150MB/s), io=10.0GiB (10.7GB), run=71486-71486msec
Disk stats (read/write):
# sda(创建的文件夹位于sda,所以获取到该磁盘信息)
# dm-0(dm-0可能是创建的文件夹的磁盘别名)磁盘上面的统计
# ios:所有组队io次数统计,比如下面的数据表示input=2621440, output=0
# merge: I/O调度器执行的总合并数
# ticks: 使磁盘繁忙的滴答数
# in_queue: 在磁盘队列中花费的总时间
# util:磁盘速度利用率,值为99.06%表示在命令执行的99.06%时间内磁盘一直很忙
# aggr开头的表示聚合后的统计,该值会比前面的没聚合的大一些
dm-0: ios=2621375/19, merge=0/0, ticks=180184/0, in_queue=180184, util=99.23%, aggrios=2621441/13, aggrmerge=0/6, aggrticks=174973/3, aggrin_queue=174976, aggrutil=99.06%
sda: ios=2621441/13, merge=0/6, ticks=174973/3, in_queue=174976, util=99.06%
使用fio
如果不幸指定了filename
参数的解决方案
看见别人挨打踩坑的时候一定要睁大眼睛,这样既能够学习到很多东西,又不用付出惨痛的代价
指定了非系统盘的解决方案
之前指定了-filename=/dev/sda
作为参数,机器在重启之后不能正常进入gui
界面,在等待了2分钟之后直接跳转到了系统恢复模式的终端
这个时候需要先去检查/etc/fstab
文件,查看是否配置了/dev/sda
盘的挂载项,发现使用了/dev/sda3
挂载为swap
分区,使用了/dev/sda4
挂载到/home/gong/files
$ cat /etc/fstab
// --snip--
# swap was on /dev/sda3 during installation
UUID=d365f79f-5cd3-43fa-a5cb-82d6eb2e9d55 none swap sw 0 0
# /home/gong/files on /dev/sda4 by user
UUID=5d642ccd-3905-46ec-b3e4-6ec4d30c6248 /home/gong/files ext4 defaults 0 2
# 把上面的挂载项注释,修改为如下,保存之后重启系统,就可以正常进入系统了,磁盘修复后面再说
// --snip--
# swap was on /dev/sda3 during installation
#UUID=d365f79f-5cd3-43fa-a5cb-82d6eb2e9d55 none swap sw 0 0
# /home/gong/files on /dev/sda4 by user
#UUID=5d642ccd-3905-46ec-b3e4-6ec4d30c6248 /home/gong/files ext4 defaults 0 2
进入系统后执行磁盘修复命令,发现程序不能识别该块磁盘的类型,需要指定超级块来运行
$ fsck -y /dev/sda
fsck,来自 util-linux 2.37.2
e2fsck 1.46.5 (30-Dec-2021)
ext2fs_open2:超级块中的幻数有错
fsck.ext2:超级块无效,正在尝试备份块...
fsck.ext2: 超级块中的幻数有错 尝试打开 /dev/sda 时
超级块无法被读取,或它未能正确地描述一个有效的 ext2/ext3/ext4 文件系统。
如果设备有效并确实为 ext2/ext3/ext4 文件系统(而非 swap 或 ufs 等格式),
这说明超级块已经损坏,您可能需要指定备选超级块来运行 e2fsck:
e2fsck -b 8193 <设备>
或
e2fsck -b 32768 <设备>
按照提示执行如下命令
$ e2fsck -b 8193 /dev/sda
以及
$ e2fsck -b 32768 /dev/sda
发现执行的输出都是一样的,输出如下
e2fsck 1.46.5 (30-Dec-2021)
e2fsck: 超级块中的幻数有错 尝试打开 /dev/sda 时
超级块无法被读取,或它未能正确地描述一个有效的 ext2/ext3/ext4 文件系统。
如果设备有效并确实为 ext2/ext3/ext4 文件系统(而非 swap 或 ufs 等格式),
这说明超级块已经损坏,您可能需要指定备选超级块来运行 e2fsck:
e2fsck -b 8193 <设备>
或
e2fsck -b 32768 <设备>
查看超级块的信息
$ mke2fs -n /dev/sda
mke2fs 1.46.5 (30-Dec-2021)
创建含有 117212886 个块(每块 4k)和 29310976 个 inode 的文件系统
文件系统 UUID:018cece1-d340-47e2-a3e3-ea505d6d7699
超级块的备份存储于下列块:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000
可以看到超级块存储的位置列表,是32768, 98304, 163840, 229376...
,所以接下去需要历遍这些块
$ e2fsck -b 32768 /dev/sda
$ e2fsck -b 98304 /dev/sda
$ e2fsck -b 163840 /dev/sda
$ e2fsck -b 229376 /dev/sda
如果上述步骤都没用的话,清空硬盘格式化,重新开始
从零开始方案如下
清空该硬盘
$ sudo dd if=/dev/zero of=/dev/sda
创建为ext4
类型的硬盘
$ sudo mkfs.ext4 /dev/sda
mke2fs 1.46.5 (30-Dec-2021)
丢弃设备块: 完成
创建含有 117212886 个块(每块 4k)和 29310976 个 inode 的文件系统
文件系统 UUID:11072eb4-18af-473e-bb69-6d16cedb0083
超级块的备份存储于下列块:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000
正在分配组表: 完成
正在写入 inode表: 完成
创建日志(262144 个块): 完成
写入超级块和文件系统账户统计信息: 已完成
最后挂载
$ sudo mount /dev/sda /home/gong/files
检查挂载结果
$ df -h
// --snip--
/dev/sda 440G 28K 417G 1% /home/gong/files
配置开机自动挂载
首先要查下设备的UUID
参数
$ blkid |grep /dev/sda
/dev/sda: UUID="11072eb4-18af-473e-bb69-6d16cedb0083" BLOCK_SIZE="4096" TYPE="ext4"
最后编辑/etc/fstab
文件,增加一行,UUID
参数对应上面查询出来的结果
# <file system> <mount point> <type> <options> <dump> <pass>
UUID=11072eb4-18af-473e-bb69-6d16cedb0083 /home/gong/files ext4 defaults 0 2
不同位置的参数解释
<file system>
: 要挂载分区的文件系统,此处建议使用UUID
<mount point>
: 挂载点,自定义创建的一个文件夹的位置<type>
: 要挂载分区的文件系统类型, 使用blkid
命令查询分区的文件系统类型<options>
: 挂载时使用的参数,一般情况下使用defaults
参数就行<dump>
: 是否对这个文件系统进行备份, 0忽略,1备份<pass>
:fsck
检查文件系统的优先级,一般情况下,可以设置为0- 0:表示不检查文件系统
- 1:如果需要检查,根目录(/)对应的文件系统设置为1
- 2:如果需要检查,非根目录对应的其它文件系统设置为2
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。