1. 磁盘基本概述

机械hdd与固态ssd:
image.png

SSD采⽤电⼦存储介质进⾏数据存储和读取的⼀种技术,突破了传统机械硬盘的性能瓶颈,拥有 极⾼的存储性能SSD⽆查找延迟, 存储与读取速度快同时防震抗摔, ⽆噪⾳, 易携带

磁盘⼤⼩:
image.png

硬盘命名:

在设备名称的定义规则如下, 其他的分区可以以此类推
系统的第⼀块SCSI接⼝的硬盘名称为/dev/sda
系统的第⼆块SCSI接⼝的硬盘名称为/dev/sdb
系统中分区由数字编号表示, 1~4留给主分区使⽤和扩展分区, 逻辑分区从5开始

有些存放数据的设备并不是直接硬件对应的设备⽂件,⽽是通过软件⽣成的块设备⽂件,例 如lvm和软raid设备⽂件。

  1. 物理硬盘 /dev/sd[a-z]
  2. KVM虚拟化 /dev/vd[a-z] online
  3. //第⼀块磁盘 /dev/sda
  4. //第⼀块磁盘, 第⼀个分区 /dev/sda1
  5. //第⼆块磁盘第⼀个分区 /dev/sdb1

注意:
MBR⽅式只能分4个主分区,GPT可分128个主分区
MBRGPT之间互相转换会导致数据丢失

2. 磁盘容量检查

1.使用df命令查看已经分区并挂载好的磁盘容量,不加参数以k为单位

  1. df -i #查看inode使⽤情况
  2. df -h #以G或者T或者M⼈性化⽅式显示
  3. df -T #查看⽂件类型
  4. //使⽤df命令查看磁盘,下⾯分别介绍每列什么含义
  5. [root@xmh ~]# df -h
  6. //设备名称 #磁盘大小 已用大小 可用大小 使用百分比 挂载点
  7. Filesystem Size Used Avail Use% Mounted on
  8. /dev/vda1 40G 5.9G 32G 16% /

2.使用lsblk查看整个系统物理磁盘个数、分区和容量

  1. [root@xmh ~]# lsblk
  2. NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
  3. sr0 11:0 1 4.2G 0 rom /mnt
  4. vda 253:0 0 40G 0 disk
  5. └─vda1 253:1 0 40G 0 part /

3.使⽤du命令查看⽬录或者⽂件的容量,不加参数以k为单位

du -sh opt  #⼈性化输出显示⼤⼩
-s:列出总和
-h:⼈性化显示容量信息

3. 磁盘分区Fdisk

分区之前, 需要先给虚拟机添加⼀块磁盘,以便于我们做后续的实验 vmware 虚拟机,请按如下进⾏操作:

  1. 找到对应虚拟主机点击右键, 选择设置
  2. 在硬件向导⾥⾯点击添加按钮, 在硬件类型中选中“硬盘”, 点击下⼀步
  3. 磁盘类型选择默认, 然后创建新虚拟磁盘, 调整⼤⼩(不要勾选⽴即分配空间)
  4. 最后点击下⼀步, 完成即可

⼩于2TB存储磁盘, 可选分区⼯具fdisk

// ⽣产分区建议: 如⽆特殊需求, 直接使⽤整个磁盘即可, ⽆需分区 
// 学习分区建议:1P+1E(3L) 2P+1E(2L) 3P+1E(1L) (仅适⽤于练习)

[root@xmh ~]# fdisk -l 
[root@xmh ~]# fdisk /dev/sdb 
Command (m for help): m #输⼊m列出常⽤的命令 
Command action
    a toggle a bootable flag #切换分区启动标记 
    b edit bsd disklabel #编辑sdb磁盘标签 
    c toggle the dos compatibility flag #切换dos兼容模式 
    d delete a partition #删除分区 
    l list known partition types #显示分区类型 
    m print this menu #显示帮助菜单 
    n add a new partition #新建分区 
    o create a new empty DOS partition table #创建新的空⽩分区表 
    p print the partition table #显示分区表的信息 
    q quit without saving changes #不保存退出 
    s create a new empty Sun disklabel #创建新的Sun磁盘标签 
    t change a partition's system id #修改分区ID,可以通过l查看
    id u change display/entry units #修改容量单位,磁柱或扇区 
    v verify the partition table #检验分区表 
    w write table to disk and exit #保存退出 
    x extra functionality (experts only) #拓展功能

//创建分区
Command (m for help): n  #新建分区
Partition type:
   p   primary (0 primary, 0 extended, 4 free)  #主分区
   e   extended  #扩展分区
Select (default p): p   #选择主分区
Partition number (1-4, default 1):  #默认回车
First sector (2048-41943039, default 2048):   #默认扇区回⻋车
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +1G  #分配1G

//创建扩展分区
Command (m for help): n  #新建分区
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): e  #创建扩展分区
Partition number (2-4, default 2):
First sector (2099200-41943039, default 2099200):
Using default value 2099200
Last sector, +sectors or +size{K,M,G} (2099200-41943039, default    41943039): #默认划分所有空间给扩展分区

//创建逻辑分区
Command (m for help): n #新建分区
Partition type:
   p   primary (1 primary, 1 extended, 2 free)
   l   logical (numbered from 5)  
Select (default p): l   #创建逻辑分区
Adding logical partition 5
First sector (2101248-41943039, default 2101248):
Using default value 2101248
Last sector, +sectors or +size{K,M,G} (2101248-41943039, default 41943039): +5G  #分配5G空间

//查看分区创建
Command (m for help): p  
Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048     2099199     1048576   83  Linux
/dev/sdb2         2099200    41943039    19921920    5  Extended
/dev/sdb5         2101248    12587007     5242880   83  Linux

//保存分区(默认情况下分区的操作在内存中进行)
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

//检查磁盘是否是MBR分区方式
[root@xmh ~]# fdisk /dev/sdb -l|grep type
Disk label type: dos   #dos表示MBR分区

//安装parted,刷新内核立即生效,无须重启系统
[root@xmh ~]# yum -y install parted
[root@xmh ~]# partprobe /dev/sdb

4. 磁盘分区Gdisk

⼤于2TB使⽤分区⼯具gdisk
注意:从MBR转到GPT,或从GPT转到MBR会导致数据全部丢失

//安装gdisk⼯具
[root@xmh /]# yum install gdisk

[root@xmh /]# gdisk /dev/sdb
Command (? for help): n  #创建新分区
Partition number (1-128, default 1):
First sector (34-41943006, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-41943006, default = 41943006) or {+-}size{KMGTP}: +1G  #分配1G空间

Command (? for help): p #打印查看
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         2099199   1024.0 MiB  8300  Linux filesystem


Command (? for help): w  #保存分区
Do you want to proceed? (Y/N): y #确认
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

//检查磁盘是否为gpt格式
[root@xmh /]# fdisk -l /dev/sdb |grep type
Disk label type: gpt

//安装parted,刷新内核立即生效,无需重启
[root@xmh /]# yum -y install parted
[root@xmh /]# partprobe /dev/sdb

5. 磁盘格式化Mkfs

mkfs格式化磁盘,实质创建⽂件系统

mkfs常⽤的选项有
-b #设定数据区块占⽤空间⼤⼩,⽬前⽀持1024、2048、4096 bytes每个块。
-t #⽤来指定什么类型的⽂件系统,可以是ext4, xfs
-i #设定inode的⼤⼩
-N #设定inode数量,防⽌Inode数量不够导致磁盘不⾜
-L #预设该分区的标签label
-f #强制格式化

//格式化整个sdb磁盘为ext4⽂件系统 
[root@xmh ~]# mkfs.ext4 /dev/sdb

//也可以格式化sdb1分区为xfs⽂件系统 
[root@xmh ~]# mkfs.xfs /dev/sdb1

6. 磁盘挂载Mount

在上⾯的内容中讲到了磁盘的分区和格式化, 那么格式化完了后, 如何使⽤, 这就涉及到了挂载这块磁盘。

挂载分区前需要创建挂载点,
挂载点以⽬录形式出现如何往挂载点⽬录写⼊数据,
实际上会写⼊到该分区 挂载点建议是空⽬录, 不是也不影响挂载分区的使⽤

6.1. 临时挂载磁盘

命令:mount挂载磁盘,实质为⽂件系统指定访问⼊⼝ 
mount -t  #指定⽂件系统挂载分区,如ext4, xfs 
mount -a  #读取/etc/fstab配置⽂件的所有分区 
mount -o  #指定挂载参数

//fstab被损坏情况下,让只读⽂件系统可写(正常情况下不使⽤) 
[root@xmh ~]# mount -o rw,remount /

//挂载/dev/sdb1⾄db1⽬录,/dev/sdb5 至db05目录
[root@xmh ~]# mkdir /db1
[root@xmh ~]# mkdir /db5
[root@xmh ~]# mount /dev/sdb1 /db1
[root@xmh ~]# mount /dev/sdb5 /db5

//查看挂载的情况
[root@xmh ~]# df -h |grep "sdb[1,5]"
/dev/sdb1                      976M  2.6M  907M   1% /db1
/dev/sdb5                      4.8G   20M  4.6G   1% /db5

//也可以指定分区类型(不指定默认自动识别)
[root@xmh ~]# mount -t xfs /dev/sdb1 /db1/

6.2. 永久挂载磁盘

//使⽤blkid命令获取各分区的UUID
[root@xmh ~]# blkid |grep "sdb" | awk  '{print $2}'
UUID="aaa7cc8f-a116-4655-a54d-8e0c2e8a581b"
UUID="e214c60e-9595-4fd1-be46-7094c0b72351"

//使⽤UUID挂载磁盘sdb1分区⾄于db1, 临时挂载
[root@xmh ~]# mount UUID="aaa7cc8f-a116-4655-a54d-8e0c2e8a581b" /db1
[root@xmh ~]# mount UUID="e214c60e-9595-4fd1-be46-7094c0b72351" /db2

//也可以把下⾯这⾏写到/etc/fstab中,永久挂载, 开机⾃动挂载
[root@xmh ~]# blkid |grep "sdb" | awk  '{print $2}' >>/etc/fstab
[root@xmh ~]# tail -2 /etc/fstab
UUID="aaa7cc8f-a116-4655-a54d-8e0c2e8a581b"  /db1     ext4    defaults        0 0
UUID="e214c60e-9595-4fd1-be46-7094c0b72351"  /db5     ext4    defaults        0 0

//加载fstab配置⽂件, 同时检测语法是否有错误
[root@xmh ~]# mount -a

fstab配置⽂件介绍

[root@xmh ~]# vim /etc/fstab
//分区标识(UUID或设备名)                         挂载点   文件类型 挂载参数        不检查 不备份
UUID="aaa7cc8f-a116-4655-a54d-8e0c2e8a581b"  /db1     ext4    defaults        0      0

//挂载参数, 可写fstab配置⽂件, 也可以mount时使⽤-o参数指定

参数                   参数意义                           系统默认值
async           系统每隔⼀段时间把内存数据写⼊磁盘中
sync            实时同步内存和磁盘中数据
suid,nosuid    允许/不允许分区有suid属性                     suid
rw,ro          可以指定⽂件系统是只读(ro)或可写(rw)            rw
exec,noexec    允许/不允许可执⾏⽂件执⾏,不要挂载根分区         exec
user,nouser    允许/不允许root外的其他⽤户挂载分区             nouser
auto,noauto    开机⾃动挂载/不⾃动挂载                        auto
default         默认⽂件系统挂载设置 rw, suid, dev, exec, auto, nouser, async

#加载所有挂载配置
[root@xmh ~]# mount -a

6.3. 卸载挂载磁盘

umount -lf #强制卸载挂载

//使⽤站点⽬录卸载 
[root@xmh ~]# umount /db1 

//使⽤设备名卸载/dev/sdb1
[root@xmh ~]# umount /dev/sdb1

//umount不能卸载的情况 
[root@xmh ~]# umount /db1 
umount: /db1: device is busy.

(In some cases useful info about processes that use the device is found by lsof(8) or fuser(1)

//如上情况解决办法有两种, 切换⾄其他⽬录或使⽤'-l'选项强制卸载 
[root@xmh ~]# umount -l /db1

7. ⽣产磁盘故障案例

Inode被沾满,导致磁盘有可⽤的剩余空间也⽆法继续使⽤

//1.创建大量的小文件
[root@xmh /]# mkdir /test
[root@xmh /]# cd /test/
[root@xmh test]# touch {1..19000000}.txt
-bash: /bin/touch: Argument list too long #直接用touch创建大量小文件会报错
[root@xmh test]# echo {1..19000000}.txt |xargs touch #使用该命令创建大量小文件

//2.当进入编辑cronta时,直接报错
[root@xmh ~]# crontab  -e
/tmp/crontab.2LrP8u: No space left on device

//先查看磁盘容量
[root@xmh ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        20G  6.3G   14G  33% /   #可以发现磁盘容量是空闲的

//查看inode容量
root@xmh ~]# df -i
Filesystem       Inodes    IUsed  IFree IUse% Mounted on
/dev/sda3      10171904 10171904      0  100% / #发现inode容量已满

提示:当磁盘容量或inode容量任意一个不足时就都会提示No space left on device


//3.查找大于1M的目录
[root@xmh ~]# find / -type d -size +1M  |xargs ls -lhd #find定位查找
drwxr-xr-x. 2 root root 235M Jan 31 15:46 /test

//4.定位好后删除拥有大量小文件的目录
[root@xmh ~]# rm -rf /test/

Block空间即将被占满, 但删除⼤⽂件也没有释放空间

假设现在线上正在运⾏Nginx服务, Nginx产⽣的⽇志已经达到了20个G, 磁盘眼看就看沾满 了, 请问不重启Nginx的⽅式如何处理

是会删除⽂件, 但Nginx持续占⽤着⽂件, 所以空间并不会被释放
rm -f access.log

正确做法如下, 清空该⽂件即可释放⽂件内容 
> access.log

磁盘故障处理总结:

  1. 当出现No space left on device这个报错提示,首先需要看磁盘空间(df -h)和inode空间(df -i),这两个哪个的容量不够
  2. 假设是磁盘容量不够,那么就针对大文件进行du -su一步一步排查,然后确认是否要删除。
  3. 假设是题目中的inode容量不够,需要对容量不够的挂载点,例如文中的 / ,进行find查找大小大于1M的目录,然后进入到该目录统计该目录的小文件的数量(ls -l |wc -l),然后在使用文中的 ls |xargs rm -f 删除小文件,最后在确认删除小文件所属的目录

注意:如果是删除了小文件,但是inode空间还没有释放,需要通过lsof |grep delete过滤出对应的服务,然后重启服务即可