首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux磁盘管理完全指南:从分区到逻辑卷的实战攻略

Linux磁盘管理完全指南:从分区到逻辑卷的实战攻略

原创
作者头像
用户3597170
发布2025-06-13 16:05:41
发布2025-06-13 16:05:41
53500
代码可运行
举报
运行总次数:0
代码可运行

前言

今天咱们来聊聊Linux磁盘管理这个话题。说起磁盘管理,这可是每个运维工程师都绕不开的基本功。不管是新服务器上线、存储扩容,还是系统迁移,都离不开对磁盘的操作。

见过太多因为磁盘操作不当导致的"血案"了。数据丢失、系统崩溃、业务中断...这些惨痛的教训告诉我们,掌握正确的磁盘管理方法有多重要。

今天我就以Red Hat Enterprise Linux为例,从最基础的分区概念开始,到高级的逻辑卷管理,给大家来个全方位的磁盘管理实战指南。不管你是刚入门的新手,还是想要系统梳理知识的老手,相信都能从中收获满满。

Linux磁盘分区模式详解

MBR分区模式(Master Boot Record)

MBR是传统的分区模式,从DOS时代就开始使用,至今仍然广泛应用。

MBR的特点:

  • 支持最大2TB的磁盘容量
  • 最多支持4个主分区
  • 如果需要更多分区,必须创建扩展分区和逻辑分区
  • 分区表存储在磁盘的第一个扇区(512字节)

分区类型:

  1. 主分区(Primary Partition):可以直接安装操作系统,最多4个
  2. 扩展分区(Extended Partition):不能直接使用,需要在其中创建逻辑分区
  3. 逻辑分区(Logical Partition):在扩展分区中创建,数量不限

我记得刚开始做运维的时候,经常被这个4个主分区的限制搞得头疼。有一次给服务器分区,需要分出系统分区、数据分区、日志分区、备份分区等好几个,结果发现主分区不够用,只能删掉重新规划,折腾了大半天。

GPT分区模式(GUID Partition Table)

GPT是新一代的分区标准,解决了MBR的诸多限制。

GPT的优势:

  • 支持超大容量磁盘(理论上可达18EB)
  • 支持128个主分区(在Linux下)
  • 分区表有备份,可靠性更高
  • 支持分区名称(最长36个字符)
  • 兼容UEFI启动

什么时候选择GPT:

  • 磁盘容量大于2TB
  • 需要超过4个分区
  • 使用UEFI启动的系统
  • 对数据可靠性要求较高的场景

现在新采购的服务器,我基本都推荐使用GPT分区模式。虽然有些老的系统可能不兼容,但从长远来看,GPT是趋势。

常用磁盘分区命令详解

fdisk命令 - MBR分区的老朋友

fdisk是Linux下最经典的分区工具,主要用于MBR分区。

基本语法:

代码语言:javascript
代码运行次数:0
运行
复制
fdisk [选项] 设备名

常用操作:

代码语言:javascript
代码运行次数:0
运行
复制
# 查看磁盘分区信息
fdisk -l
​
# 对指定磁盘进行分区操作
fdisk /dev/sdb

fdisk交互命令:

  • p:显示分区表
  • n:创建新分区
  • d:删除分区
  • t:改变分区类型
  • w:保存并退出
  • q:不保存退出

实际操作示例:

代码语言:javascript
代码运行次数:0
运行
复制
[root@server ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
​
Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical drives)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-20971519, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-20971519, default 20971519): +5G
​
Created a new partition 1 of type 'Linux' and of size 5 GiB.
​
Command (m for help): w
The partition table has been altered!

parted命令 - 现代分区的多面手

parted是更现代的分区工具,支持MBR和GPT两种模式。

基本语法:

代码语言:javascript
代码运行次数:0
运行
复制
parted [选项] [设备名] [命令]

常用操作:

代码语言:javascript
代码运行次数:0
运行
复制
# 查看所有磁盘信息
parted -l
​
# 进入交互模式
parted /dev/sdb
​
# 非交互模式创建分区
parted /dev/sdb mkpart primary 0% 50%

parted交互命令:

  • print:显示分区表
  • mklabel:创建分区表类型
  • mkpart:创建分区
  • rm:删除分区
  • resizepart:调整分区大小

GPT分区实例:

代码语言:javascript
代码运行次数:0
运行
复制
[root@server ~]# parted /dev/sdc
GNU Parted 3.2
Using /dev/sdc
Welcome to GNU Parted! Type 'help' to view a list of commands.
​
(parted) mklabel gpt
Warning: The existing disk label on /dev/sdc will be destroyed and all data on this disk will be lost. Do you want to continue?
Yes/No? yes
​
(parted) mkpart primary 0% 25%
(parted) mkpart primary 25% 50%
(parted) mkpart primary 50% 100%
(parted) print
Model: VMware Virtual disk (scsi)
Disk /dev/sdc: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 
​
Number  Start   End     Size    File system  Name     Flags
 1      1049kB  5369MB  5368MB               primary
 2      5369MB  10.7GB  5368MB               primary
 3      10.7GB  21.5GB  10.7GB               primary
​
(parted) quit

gdisk命令 - GPT分区专家

gdisk专门用于GPT分区,操作方式类似fdisk。

代码语言:javascript
代码运行次数:0
运行
复制
# 对GPT磁盘进行分区
gdisk /dev/sdb

lsblk命令 - 查看块设备信息

这个命令用来查看系统中所有块设备的层次结构。

代码语言:javascript
代码运行次数:0
运行
复制
[root@server ~]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   20G  0 disk 
├─sda1            8:1    0    1G  0 part /boot
└─sda2            8:2    0   19G  0 part 
  ├─centos-root 253:0    0   17G  0 lvm  /
  └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
sdb               8:16   0   10G  0 disk 
├─sdb1            8:17   0    5G  0 part 
└─sdb2            8:18   0    5G  0 part 

一块新磁盘的完整处理流程

现在让我通过一个完整的实例,演示如何处理一块新添加的磁盘。

步骤1:识别新磁盘

代码语言:javascript
代码运行次数:0
运行
复制
# 查看所有磁盘
lsblk

# 查看磁盘详细信息
fdisk -l

# 也可以查看/proc/partitions
cat /proc/partitions

假设我们发现了一块新的10GB磁盘 /dev/sdb

步骤2:选择分区模式并创建分区

方案一:使用fdisk创建MBR分区

代码语言:javascript
代码运行次数:0
运行
复制
[root@server ~]# fdisk /dev/sdb

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical drives)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-20971519, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P}: +8G

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical drives)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (16779264-20971519, default 16779264): 
Last sector, +sectors or +size{K,M,G,T,P}: 

Command (m for help): w

方案二:使用parted创建GPT分区

代码语言:javascript
代码运行次数:0
运行
复制
[root@server ~]# parted /dev/sdb
(parted) mklabel gpt
(parted) mkpart data1 0% 80%
(parted) mkpart data2 80% 100%
(parted) quit

步骤3:创建文件系统

代码语言:javascript
代码运行次数:0
运行
复制
# 创建ext4文件系统
mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2

# 或者创建xfs文件系统(RHEL7+推荐)
mkfs.xfs /dev/sdb1
mkfs.xfs /dev/sdb2

步骤4:创建挂载点并挂载

代码语言:javascript
代码运行次数:0
运行
复制
# 创建挂载点
mkdir -p /data1 /data2

# 临时挂载
mount /dev/sdb1 /data1
mount /dev/sdb2 /data2

# 验证挂载
df -h

步骤5:配置开机自动挂载

代码语言:javascript
代码运行次数:0
运行
复制
# 获取UUID
blkid /dev/sdb1
blkid /dev/sdb2

# 编辑/etc/fstab
vim /etc/fstab

# 添加以下内容(UUID替换为实际值)
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data1 ext4 defaults 0 2
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data2 ext4 defaults 0 2

# 测试fstab配置
umount /data1 /data2
mount -a
df -h

重要提醒: 在生产环境中,修改fstab后一定要用mount -a测试,确保配置正确。我见过好几次因为fstab配置错误导致系统无法启动的情况,最后只能进单用户模式修复。

逻辑卷管理(LVM)实战

LVM(Logical Volume Manager)是Linux下的逻辑卷管理器,它提供了比传统分区更灵活的磁盘管理方式。在生产环境中,LVM几乎是标配,因为它可以动态调整容量,这对于业务系统来说太重要了。

LVM核心概念

在开始实操之前,我们先理解几个核心概念:

  • PV(Physical Volume):物理卷,可以是整个磁盘或分区
  • VG(Volume Group):卷组,由一个或多个PV组成的存储池
  • LV(Logical Volume):逻辑卷,从VG中分配空间创建的虚拟分区
  • PE(Physical Extent):物理扩展单元,PV的最小分配单位(默认4MB)
  • LE(Logical Extent):逻辑扩展单元,LV的最小分配单位

简单理解就是:把多个硬盘或分区(PV)组成一个大的存储池(VG),然后从这个池子里分配空间创建虚拟的分区(LV)。

创建LVM的完整流程

让我通过一个实际案例来演示整个流程。假设我们有两块新硬盘/dev/sdb/dev/sdc,需要创建LVM来管理。

步骤1:准备物理卷(PV)

代码语言:javascript
代码运行次数:0
运行
复制
# 首先查看可用磁盘
lsblk

# 创建物理卷(可以是整个磁盘或分区)
pvcreate /dev/sdb /dev/sdc

# 查看物理卷信息
pvdisplay
pvs

输出示例:

代码语言:javascript
代码运行次数:0
运行
复制
[root@server ~]# pvcreate /dev/sdb /dev/sdc
  Physical volume "/dev/sdb" successfully created.
  Physical volume "/dev/sdc" successfully created.

[root@server ~]# pvs
  PV         VG Fmt  Attr PSize  PFree 
  /dev/sdb      lvm2 ---  10.00g 10.00g
  /dev/sdc      lvm2 ---  10.00g 10.00g

步骤2:创建卷组(VG)

代码语言:javascript
代码运行次数:0
运行
复制
# 创建卷组
vgcreate datavg /dev/sdb /dev/sdc

# 查看卷组信息
vgdisplay datavg
vgs

输出示例:

代码语言:javascript
代码运行次数:0
运行
复制
[root@server ~]# vgcreate datavg /dev/sdb /dev/sdc
  Volume group "datavg" successfully created

[root@server ~]# vgs
  VG     #PV #LV #SN Attr   VSize  VFree 
  datavg   2   0   0 wz--n- 19.99g 19.99g

步骤3:创建逻辑卷(LV)

代码语言:javascript
代码运行次数:0
运行
复制
# 创建逻辑卷(指定大小)
lvcreate -L 10G -n datalv datavg

# 创建逻辑卷(使用百分比)
lvcreate -l 50%VG -n applv datavg

# 查看逻辑卷信息
lvdisplay
lvs

输出示例:

代码语言:javascript
代码运行次数:0
运行
复制
[root@server ~]# lvcreate -L 10G -n datalv datavg
  Logical volume "datalv" created.

[root@server ~]# lvcreate -l 50%FREE -n applv datavg
  Logical volume "applv" created.

[root@server ~]# lvs
  LV     VG     Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  applv  datavg -wi-a----- 5.00g                                                    
  datalv datavg -wi-a----- 10.00g

步骤4:创建文件系统并挂载

代码语言:javascript
代码运行次数:0
运行
复制
# 创建文件系统
mkfs.xfs /dev/datavg/datalv
mkfs.xfs /dev/datavg/applv

# 创建挂载点
mkdir -p /data /app

# 挂载
mount /dev/datavg/datalv /data
mount /dev/datavg/applv /app

# 验证
df -h

步骤5:配置自动挂载

代码语言:javascript
代码运行次数:0
运行
复制
# 编辑/etc/fstab
vim /etc/fstab

# 添加以下内容
/dev/datavg/datalv /data xfs defaults 0 2
/dev/datavg/applv /app xfs defaults 0 2

# 测试配置
mount -a

LVM容量调整实战

LVM最大的优势就是可以动态调整容量。在我的运维生涯中,这个功能救过我无数次。

扩展逻辑卷容量

场景: /data分区空间不足,需要扩容

代码语言:javascript
代码运行次数:0
运行
复制
# 1. 检查当前状态
df -h /data
lvs datavg
vgs datavg

# 2. 如果VG有足够空间,直接扩展LV
lvextend -L +5G /dev/datavg/datalv
# 或者扩展到指定大小
lvextend -L 15G /dev/datavg/datalv

# 3. 扩展文件系统
# 对于xfs文件系统
xfs_growfs /data
# 对于ext4文件系统
resize2fs /dev/datavg/datalv

# 4. 验证结果
df -h /data

如果VG空间不足,需要先扩展VG:

代码语言:javascript
代码运行次数:0
运行
复制
# 1. 准备新的物理卷
pvcreate /dev/sdd

# 2. 扩展卷组
vgextend datavg /dev/sdd

# 3. 查看扩展后的VG
vgs datavg

# 4. 然后按上面步骤扩展LV
lvextend -L +10G /dev/datavg/datalv
xfs_growfs /data

我记得有一次凌晨3点,数据库服务器的数据分区突然报警空间不足,业务马上要受影响。好在用的是LVM,我在5分钟内就完成了扩容,业务完全没有感知。如果是传统分区,那就麻烦大了。

缩减逻辑卷容量

⚠️ 重要警告:缩减操作有数据丢失风险,务必先备份数据!

注意:xfs文件系统不支持缩减操作,只有ext系列文件系统支持。

代码语言:javascript
代码运行次数:0
运行
复制
# 1. 卸载文件系统
umount /app

# 2. 检查文件系统
e2fsck -f /dev/datavg/applv

# 3. 缩减文件系统(ext4)
resize2fs /dev/datavg/applv 3G

# 4. 缩减逻辑卷
lvreduce -L 3G /dev/datavg/applv

# 5. 重新挂载
mount /dev/datavg/applv /app

在线扩展示例:

对于某些文件系统,可以实现在线扩展,不需要卸载:

代码语言:javascript
代码运行次数:0
运行
复制
# xfs文件系统在线扩展
lvextend -L +2G /dev/datavg/datalv
xfs_growfs /data

# ext4文件系统在线扩展
lvextend -L +2G /dev/datavg/applv
resize2fs /dev/datavg/applv

LVM快照功能

LVM还提供了快照功能,这在数据备份和测试环境中非常有用。

代码语言:javascript
代码运行次数:0
运行
复制
# 创建快照(快照大小根据变化量估算)
lvcreate -L 2G -s -n datalv_snap /dev/datavg/datalv

# 挂载快照
mkdir /data_snap
mount /dev/datavg/datalv_snap /data_snap

# 查看快照状态
lvs

# 删除快照
umount /data_snap
lvremove /dev/datavg/datalv_snap

我经常在数据库升级前创建快照,如果升级失败可以快速回滚。不过要注意,快照会影响性能,不建议长期保留。

实际生产环境案例分析

案例1:数据库服务器磁盘规划

场景: 新上线一台MySQL数据库服务器,配置4块1TB SAS硬盘。

需求分析:

  • 系统稳定性要求高
  • 数据安全性要求高
  • 需要考虑后期扩容
  • I/O性能要求较高

规划方案:

代码语言:javascript
代码运行次数:0
运行
复制
# 磁盘1-2:系统盘,做RAID1镜像
# /dev/sda 系统盘分区规划
/dev/sda1  /boot     1G     ext4
/dev/sda2  /         30G    xfs
/dev/sda3  /var/log  10G    xfs
/dev/sda4  swap      16G    swap

# 磁盘3-4:数据盘,使用LVM管理
pvcreate /dev/sdc /dev/sdd
vgcreate mysql_vg /dev/sdc /dev/sdd

# 创建逻辑卷
lvcreate -L 1500G -n mysql_data mysql_vg    # 数据目录
lvcreate -L 200G -n mysql_log mysql_vg      # 日志目录
lvcreate -L 100G -n mysql_backup mysql_vg   # 备份目录
lvcreate -L 50G -n mysql_temp mysql_vg      # 临时目录

为什么这样规划:

  • 系统盘使用RAID1保证可靠性
  • 数据盘使用LVM方便后期扩容
  • 分离数据、日志、备份,提高I/O性能
  • 预留部分空间用于快照和临时扩容

案例2:Web服务器存储优化

场景: Web服务器需要存储大量静态文件,访问频繁,需要优化存储结构。

原始状况:

  • 单块2TB磁盘,使用传统分区
  • 网站文件、日志、缓存都在一个分区
  • 经常出现空间不足问题

优化方案:

代码语言:javascript
代码运行次数:0
运行
复制
# 添加新磁盘,使用LVM重新规划
pvcreate /dev/sdb /dev/sdc
vgcreate web_vg /dev/sdb /dev/sdc

# 创建专用逻辑卷
lvcreate -L 1T -n web_files web_vg      # 网站文件
lvcreate -L 500G -n web_logs web_vg     # 访问日志
lvcreate -L 200G -n web_cache web_vg     # 缓存文件
lvcreate -L 100G -n web_backup web_vg    # 备份文件
# 创建文件系统

mkfs.xfs /dev/web_vg/web_files
mkfs.xfs /dev/web_vg/web_logs
mkfs.xfs /dev/web_vg/web_cache
mkfs.xfs /dev/web_vg/web_backup

# 挂载到相应目录

mount /dev/web_vg/web_files /var/www/html
mount /dev/web_vg/web_logs /var/log/httpd
mount /dev/web_vg/web_cache /var/cache/nginx
mount /dev/web_vg/web_backup /backup

优化效果:

  • 不同类型文件分离存储,I/O性能提升
  • 可以针对不同分区设置不同的挂载参数
  • 扩容更加灵活,按需分配空间

案例3:在线扩容实战

场景: 电商网站图片存储空间告急,需要紧急扩容,不能影响业务。

告警信息:

代码语言:javascript
代码运行次数:0
运行
复制
[root@web01 ~]# df -h
Filesystem                    Size  Used Avail Use% Mounted on
/dev/mapper/web_vg-images_lv   50G   47G  1.9G  97% /var/www/images

扩容步骤:

代码语言:javascript
代码运行次数:0
运行
复制
# 1. 检查VG剩余空间
vgs web_vg
  VG     #PV #LV #SN Attr   VSize   VFree
  web_vg   2   4   0 wz--n- 1.82t 200.00g

# 2. 在线扩展逻辑卷
lvextend -L +20G /dev/web_vg/images_lv
  Size of logical volume web_vg/images_lv changed from 50.00 GiB to 70.00 GiB.
  Logical volume web_vg/images_lv successfully resized.

# 3. 在线扩展文件系统
xfs_growfs /var/www/images
meta-data=/dev/mapper/web_vg-images_lv isize=512    agcount=4, agsize=3276800 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=13107200, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=6400, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 13107200 to 18350080

# 4. 验证结果
df -h /var/www/images
Filesystem                    Size  Used Avail Use% Mounted on
/dev/mapper/web_vg-images_lv   70G   47G   24G  67% /var/www/images

整个过程不到2分钟,业务完全无感知。这就是LVM的强大之处!

最佳实践与注意事项

磁盘分区最佳实践

经过多年的生产环境实践,我总结了以下最佳实践:

1. 合理规划分区大小

代码语言:javascript
代码运行次数:0
运行
复制
# 推荐的分区规划
/boot     1GB      # 引导分区,1GB足够
/         30-50GB  # 根分区,不要太大也不要太小
/var      20GB+    # 变量数据,日志文件存放
/var/log  单独分区  # 防止日志填满系统盘
/tmp      单独分区  # 临时文件,可设置noexec参数
swap      内存1-2倍 # 物理内存大于8GB时可以等于内存大小

2. 选择合适的文件系统

代码语言:javascript
代码运行次数:0
运行
复制
# 不同场景的文件系统选择
系统分区:    xfs(RHEL7+默认)
数据分区:    xfs(大文件性能好)
日志分区:    ext4(小文件性能好)
临时分区:    tmpfs(内存文件系统)

3. 使用LVM管理数据盘

代码语言:javascript
代码运行次数:0
运行
复制
# 数据盘强烈推荐使用LVM
# 系统盘可以不用LVM,保持简单
# 为VG预留10-20%的空间用于快照和扩容
vgcreate -s 32M datavg /dev/sdb /dev/sdc  # 大容量使用大PE

安全操作建议

1. 操作前必须备份

代码语言:javascript
代码运行次数:0
运行
复制
# 备份分区表
sfdisk -d /dev/sda > /root/sda_partition_backup.txt
dd if=/dev/sda of=/root/mbr_backup.img bs=512 count=1

# 备份重要数据
tar -czf /backup/data_backup_$(date +%Y%m%d).tar.gz /important/data

# 备份LVM配置
vgcfgbackup

2. 使用UUID而不是设备名

代码语言:javascript
代码运行次数:0
运行
复制
# /etc/fstab中推荐使用UUID
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data xfs defaults 0 2

# 而不是使用设备名(可能会变化)
/dev/sdb1 /data xfs defaults 0 2

3. 测试配置

代码语言:javascript
代码运行次数:0
运行
复制
# 修改/etc/fstab后必须测试
mount -a
echo $?  # 返回0表示成功

# 检查挂载状态
df -h
findmnt

4. 设置合适的挂载参数

代码语言:javascript
代码运行次数:0
运行
复制
# 针对不同用途设置不同参数
/dev/datavg/web_lv /var/www xfs defaults,noatime 0 2          # Web文件,禁用访问时间更新
/dev/datavg/log_lv /var/log xfs defaults,nodev,nosuid 0 2     # 日志分区,安全参数
/dev/datavg/tmp_lv /tmp     xfs defaults,nodev,nosuid,noexec 0 2  # 临时分区,禁止执行

性能优化建议

1. 分区对齐

代码语言:javascript
代码运行次数:0
运行
复制
# 使用parted创建分区时确保对齐
parted /dev/sdb mkpart primary 2048s 100%

# 检查分区对齐
parted /dev/sdb align-check optimal 1

2. 选择合适的PE大小

代码语言:javascript
代码运行次数:0
运行
复制
# 根据VG大小选择PE大小
小于16GB:    4MB(默认)
16GB-256GB:  8MB
256GB-1TB:   16MB
大于1TB:     32MB

vgcreate -s 32M large_vg /dev/sdb

3. I/O调度器优化

代码语言:javascript
代码运行次数:0
运行
复制
# 查看当前调度器
cat /sys/block/sda/queue/scheduler

# SSD使用noop或deadline
echo noop > /sys/block/sda/queue/scheduler

# 机械硬盘使用cfq
echo cfq > /sys/block/sdb/queue/scheduler

# 永久设置(添加到/etc/rc.local)
echo 'echo noop > /sys/block/sda/queue/scheduler' >> /etc/rc.local

故障排除与恢复

常见问题及解决方案

在运维工作中,磁盘相关的故障是最常见的,下面分享一些实用的排查和恢复方法。

问题1:分区表损坏

症状:系统无法识别分区,fdisk -l显示异常

代码语言:javascript
代码运行次数:0
运行
复制
# 使用testdisk恢复分区表
yum install testdisk
testdisk /dev/sda

# 或者使用备份恢复
sfdisk /dev/sda < /root/sda_partition_backup.txt

# GPT分区表修复
gdisk /dev/sda
# 在gdisk中使用 'r' 进入恢复模式,然后使用 'c' 修复

问题2:LVM元数据损坏

症状:vgs、lvs命令报错,无法激活卷组

代码语言:javascript
代码运行次数:0
运行
复制
# 扫描并修复
pvscan --cache
vgscan --mknodes
lvscan

# 强制激活(谨慎使用)
vgchange -ay --partial datavg

# 从备份恢复LVM配置
vgcfgrestore datavg

问题3:文件系统损坏

症状:无法挂载,提示文件系统错误

代码语言:javascript
代码运行次数:0
运行
复制
# ext4文件系统检查修复
umount /dev/sda1
e2fsck -f /dev/sda1
e2fsck -y /dev/sda1  # 自动回答yes

# xfs文件系统检查修复
umount /dev/sda1
xfs_repair /dev/sda1
xfs_repair -L /dev/sda1  # 强制修复,可能丢失数据

问题4:/etc/fstab配置错误导致启动失败敲黑板,这个非常常见

这是我遇到过最多的问题之一,解决方法:

代码语言:javascript
代码运行次数:0
运行
复制
# 1. 进入单用户模式或救援模式
# 2. 重新挂载根分区为可写
mount -o remount,rw /

# 3. 修复/etc/fstab
vim /etc/fstab
# 注释掉有问题的行或修正配置

# 4. 测试配置
mount -a

# 5. 重启系统
reboot

数据恢复技巧

当发生严重的数据丢失时,可以尝试以下恢复方法:

1. 使用ddrescue恢复数据

代码语言:javascript
代码运行次数:0
运行
复制
# 安装ddrescue
yum install ddrescue

# 创建磁盘镜像(先救数据,后分析)
ddrescue -d -r3 /dev/sda /backup/sda_image.img /backup/sda_recovery.log

# 在镜像上进行恢复操作

losetup /dev/loop0 /backup/sda_image.img

2. 使用photorec恢复文件

代码语言:javascript
代码运行次数:0
运行
复制
# photorec是testdisk套件的一部分
photorec /dev/sda

# 或者在镜像上恢复
photorec /backup/sda_image.img

3. 恢复ext4删除的文件

代码语言:javascript
代码运行次数:0
运行
复制
# 使用extundelete恢复
yum install extundelete

# 恢复所有删除的文件
extundelete /dev/sda1 --restore-all

# 恢复特定文件
extundelete /dev/sda1 --restore-file /path/to/file

监控与预警系统

建立完善的监控系统可以提前发现问题:

1. 磁盘空间监控脚本

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# disk_monitor.sh
THRESHOLD=85
EMAIL="admin@company.com"

df -h | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $5 " " $1}' | while read output;
do
    usage=$(echo $output | awk '{print $1}' | sed 's/%//g')
    partition=$(echo $output | awk '{print $2}')
    
    if [ $usage -ge $THRESHOLD ]; then
        message="Warning: Disk usage on $partition is ${usage}%"
        echo $message
        # 发送邮件告警
        echo $message | mail -s "Disk Space Alert" $EMAIL
        
        # 记录日志
        logger "DISK_ALERT: $message"
    fi
done

2. LVM状态监控

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# lvm_monitor.sh

# 检查VG状态
vgs --noheadings -o vg_name,vg_attr | while read vg_name vg_attr; do
    if [[ $vg_attr != *"w"* ]]; then
        echo "Warning: VG $vg_name is not writable"
        logger "LVM_ALERT: VG $vg_name status abnormal: $vg_attr"
    fi
done

# 检查LV状态
lvs --noheadings -o lv_name,vg_name,lv_attr | while read lv_name vg_name lv_attr; do
    if [[ $lv_attr != *"a"* ]]; then
        echo "Warning: LV $vg_name/$lv_name is not active"
        logger "LVM_ALERT: LV $vg_name/$lv_name status abnormal: $lv_attr"
    fi
done

3. 设置定时任务

代码语言:javascript
代码运行次数:0
运行
复制
# 添加到crontab
crontab -e

# 每10分钟检查磁盘空间
*/10 * * * * /root/scripts/disk_monitor.sh

# 每小时检查LVM状态
0 * * * * /root/scripts/lvm_monitor.sh

# 每天备份分区表和LVM配置
0 2 * * * sfdisk -d /dev/sda > /backup/sda_partition_$(date +\%Y\%m\%d).txt
0 2 * * * vgcfgbackup

自动化运维脚本

为了提高工作效率,我编写了一些实用的自动化脚本:

磁盘初始化脚本

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# disk_init.sh - 自动初始化新磁盘为LVM

# 检查参数
if [ $# -lt 2 ]; then
    echo "Usage: $0 <disk_device> <vg_name> [lv_name] [lv_size]"
    echo "Example: $0 /dev/sdb datavg datalv 100G"
    exit 1
fi

DISK=$1
VG_NAME=$2
LV_NAME=${3:-"datalv"}
LV_SIZE=${4:-"100%FREE"}

# 安全检查
if ! lsblk $DISK &>/dev/null; then
    echo "Error: Disk $DISK not found"
    exit 1
fi

echo "Warning: This will destroy all data on $DISK"
echo "VG Name: $VG_NAME"
echo "LV Name: $LV_NAME"
echo "LV Size: $LV_SIZE"
read -p "Continue? (yes/no): " confirm

if [ "$confirm" != "yes" ]; then
    echo "Operation cancelled"
    exit 0
fi

# 创建PV
echo "Creating Physical Volume..."
pvcreate $DISK
if [ $? -ne 0 ]; then
    echo "Error: Failed to create PV"
    exit 1
fi

# 创建或扩展VG
if vgs $VG_NAME &>/dev/null; then
    echo "Extending existing Volume Group..."
    vgextend $VG_NAME $DISK
else
    echo "Creating Volume Group..."
    vgcreate $VG_NAME $DISK
fi

if [ $? -ne 0 ]; then
    echo "Error: Failed to create/extend VG"
    exit 1
fi

# 创建LV
echo "Creating Logical Volume..."
lvcreate -n $LV_NAME -l $LV_SIZE $VG_NAME
if [ $? -ne 0 ]; then
    echo "Error: Failed to create LV"
    exit 1
fi

# 创建文件系统
echo "Creating XFS filesystem..."
mkfs.xfs /dev/$VG_NAME/$LV_NAME
if [ $? -ne 0 ]; then
    echo "Error: Failed to create filesystem"
    exit 1
fi

echo "Disk initialization completed successfully!"
echo "Device: /dev/$VG_NAME/$LV_NAME"
echo "Next steps:"
echo "1. Create mount point: mkdir /your/mount/point"
echo "2. Mount: mount /dev/$VG_NAME/$LV_NAME /your/mount/point"
echo "3. Add to /etc/fstab for persistent mounting"

LVM扩容脚本

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# lvm_extend.sh - 自动扩展LVM逻辑卷

if [ $# -ne 3 ]; then
    echo "Usage: $0 <lv_path> <size> <mount_point>"
    echo "Example: $0 /dev/datavg/datalv +10G /data"
    exit 1
fi

LV_PATH=$1
SIZE=$2
MOUNT_POINT=$3

# 检查LV是否存在
if ! lvs $LV_PATH &>/dev/null; then
    echo "Error: Logical Volume $LV_PATH not found"
    exit 1
fi

# 检查挂载点
if ! mountpoint -q $MOUNT_POINT; then
    echo "Error: $MOUNT_POINT is not a mount point"
    exit 1
fi

# 获取文件系统类型
FS_TYPE=$(findmnt -n -o FSTYPE $MOUNT_POINT)

echo "Extending Logical Volume $LV_PATH by $SIZE"
echo "Mount Point: $MOUNT_POINT"
echo "Filesystem: $FS_TYPE"

# 扩展LV
echo "Extending Logical Volume..."
lvextend -L $SIZE $LV_PATH
if [ $? -ne 0 ]; then
    echo "Error: Failed to extend LV"
    exit 1
fi

# 扩展文件系统
echo "Extending filesystem..."
case $FS_TYPE in
    xfs)
        xfs_growfs $MOUNT_POINT
        ;;
    ext4|ext3|ext2)
        resize2fs $LV_PATH
        ;;
    *)
        echo "Warning: Unsupported filesystem type: $FS_TYPE"
        echo "Please manually extend the filesystem"
        exit 1
        ;;
esac

if [ $? -eq 0 ]; then
    echo "Extension completed successfully!"
    echo "New size:"
    df -h $MOUNT_POINT
else
    echo "Error: Failed to extend filesystem"
    exit 1
fi

系统健康检查脚本

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# system_health_check.sh - 系统存储健康检查

echo "=== System Storage Health Check ==="
echo "Date: $(date)"
echo

# 检查磁盘空间
echo "=== Disk Space Usage ==="
df -h | grep -vE '^Filesystem|tmpfs|udev'
echo

# 检查磁盘I/O
echo "=== Disk I/O Statistics ==="
iostat -x 1 1 | tail -n +4
echo

# 检查LVM状态
if command -v vgs &>/dev/null; then
    echo "=== LVM Volume Groups ==="
    vgs
    echo
    
    echo "=== LVM Logical Volumes ==="
    lvs
    echo
    
    echo "=== LVM Physical Volumes ==="
    pvs
    echo
fi

# 检查RAID状态(如果有)
if [ -f /proc/mdstat ]; then
    echo "=== Software RAID Status ==="
    cat /proc/mdstat
    echo
fi

# 检查挂载状态
echo "=== Mount Status ==="
findmnt -D
echo

# 检查文件系统错误
echo "=== Filesystem Errors Check ==="
dmesg | grep -i "error\|fail\|corrupt" | grep -i "ext\|xfs\|filesystem" | tail -10
echo

# 检查SMART状态(如果smartctl可用)
if command -v smartctl &>/dev/null; then
    echo "=== SMART Status ==="
    for disk in $(lsblk -d -n -o NAME | grep -E '^sd[a-z]$'); do
        echo "Disk: /dev/$disk"
        smartctl -H /dev/$disk 2>/dev/null | grep -E "SMART overall-health|result"
    done
    echo
fi

echo "=== Health Check Completed ==="

存储技术发展趋势

随着云计算和容器技术的发展,传统的存储管理方式也在不断演进。作为运维人员,我们需要了解这些新技术:

1. 容器存储

代码语言:javascript
代码运行次数:0
运行
复制
# Docker卷管理
docker volume create mydata
docker run -v mydata:/data nginx

# Kubernetes持久卷
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-data
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data

2. 软件定义存储

代码语言:javascript
代码运行次数:0
运行
复制
# Ceph分布式存储
ceph osd pool create mypool 128
rbd create --size 10240 mypool/mydisk

# GlusterFS分布式文件系统
gluster volume create myvol replica 2 server1:/brick1 server2:/brick1
gluster volume start myvol

3. 云存储集成

代码语言:javascript
代码运行次数:0
运行
复制
# 挂载阿里云OSS
ossfs mybucket /mnt/oss -ourl=http://oss-cn-hangzhou.aliyuncs.com

# 挂载AWS S3
s3fs mybucket /mnt/s3 -o passwd_file=/etc/passwd-s3fs

性能调优深入

对于高并发、大数据量的应用,存储性能调优变得尤为重要:

1. I/O调度器优化

代码语言:javascript
代码运行次数:0
运行
复制
# 查看和设置I/O调度器
cat /sys/block/sda/queue/scheduler
echo mq-deadline > /sys/block/sda/queue/scheduler

# 针对不同存储类型的推荐设置
# SSD: none 或 mq-deadline
# 机械硬盘: mq-deadline 或 bfq
# NVMe: none

2. 文件系统参数调优

代码语言:javascript
代码运行次数:0
运行
复制
# XFS调优参数
mount -o noatime,largeio,inode64,swalloc /dev/datavg/datalv /data

# Ext4调优参数
mount -o noatime,data=writeback,barrier=0,nobh /dev/datavg/datalv /data

3. LVM性能优化

代码语言:javascript
代码运行次数:0
运行
复制
# 使用适当的PE大小
vgcreate -s 32M large_vg /dev/sdb

# 条带化提升性能
lvcreate -L 100G -i 2 -I 64 -n striped_lv datavg

# 使用SSD作为缓存
lvcreate -L 20G -n cache_pool datavg /dev/nvme0n1
lvconvert --type cache-pool datavg/cache_pool
lvconvert --type cache --cachepool datavg/cache_pool datavg/data_lv

企业级存储方案

在大型企业环境中,存储架构通常更加复杂:

1. 多路径存储

代码语言:javascript
代码运行次数:0
运行
复制
# 安装multipath
yum install device-mapper-multipath

# 配置multipath
mpathconf --enable --with_multipathd y

# 查看多路径设备
multipath -ll

2. 存储复制和同步

代码语言:javascript
代码运行次数:0
运行
复制
# 使用rsync同步数据
rsync -avz --progress /data/ backup-server:/backup/data/

# 使用DRBD实现块级复制
drbdadm create-md r0
drbdadm up r0
drbdadm primary --force r0

3. 快照策略

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# snapshot_backup.sh - 自动快照备份脚本

VG_NAME="datavg"
LV_NAME="datalv"
SNAP_NAME="snap_$(date +%Y%m%d_%H%M%S)"
BACKUP_DIR="/backup"

# 创建快照
lvcreate -L 10G -s -n $SNAP_NAME /dev/$VG_NAME/$LV_NAME

# 挂载快照
mkdir -p /mnt/$SNAP_NAME
mount /dev/$VG_NAME/$SNAP_NAME /mnt/$SNAP_NAME

# 备份数据
tar -czf $BACKUP_DIR/backup_$(date +%Y%m%d).tar.gz -C /mnt/$SNAP_NAME .

# 清理快照
umount /mnt/$SNAP_NAME
lvremove -f /dev/$VG_NAME/$SNAP_NAME
rmdir /mnt/$SNAP_NAME

echo "Backup completed: $BACKUP_DIR/backup_$(date +%Y%m%d).tar.gz"

故障预防与应急响应

1. 预防性维护

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# preventive_maintenance.sh

# 检查磁盘健康状态
for disk in $(lsblk -d -n -o NAME | grep -E '^sd[a-z]$'); do
    echo "Checking /dev/$disk..."
    smartctl -t short /dev/$disk
    sleep 60
    smartctl -l selftest /dev/$disk | head -10
done

# 检查文件系统
for fs in $(findmnt -n -o TARGET -t xfs,ext4); do
    echo "Checking filesystem: $fs"
    if [[ $fs == *"xfs"* ]]; then
        xfs_info $fs > /dev/null
    else
        tune2fs -l $(findmnt -n -o SOURCE $fs) > /dev/null
    fi
done

2. 应急响应预案

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# emergency_response.sh

case $1 in
    "disk_full")
        echo "Disk full emergency response..."
        # 清理临时文件
        find /tmp -type f -mtime +7 -delete
        find /var/log -name "*.log" -mtime +30 -delete
        # 压缩日志文件
        find /var/log -name "*.log" -size +100M -exec gzip {} \;
        ;;
    "lvm_failure")
        echo "LVM failure emergency response..."
        # 尝试激活VG
        vgchange -ay
        # 扫描并修复
        pvscan --cache
        vgscan --mknodes
        ;;
    "filesystem_error")
        echo "Filesystem error emergency response..."
        # 只读挂载保护数据
        mount -o remount,ro /problematic/mount
        # 记录错误信息
        dmesg | tail -50 > /var/log/emergency_$(date +%Y%m%d_%H%M%S).log
        ;;
esac

监控与告警进阶

1. 集成Prometheus监控

代码语言:javascript
代码运行次数:0
运行
复制
# prometheus.yml配置片段
- job_name: 'node-exporter'
  static_configs:
    - targets: ['localhost:9100']
  
# 磁盘空间告警规则
groups:
- name: disk
  rules:
  - alert: DiskSpaceHigh
    expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100 < 15
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Disk space usage is above 85%"

2. 自定义监控指标

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
# custom_metrics.sh

# 输出Prometheus格式的指标
echo "# HELP lvm_vg_free_bytes Free bytes in volume group"
echo "# TYPE lvm_vg_free_bytes gauge"

vgs --noheadings --units b -o vg_name,vg_free | while read vg_name vg_free; do
    vg_free_bytes=$(echo $vg_free | sed 's/B//')
    echo "lvm_vg_free_bytes{vg_name=\"$vg_name\"} $vg_free_bytes"
done

写在最后

经过这么多年的运维工作,我深深体会到存储管理的重要性。每一次磁盘故障、每一次数据恢复、每一次性能优化,都是宝贵的经验积累。

记得刚开始做运维的时候,因为对LVM不熟悉,在扩容时操作失误导致了数据丢失,那一夜的通宵达旦和焦虑至今记忆犹新。从那以后,我就告诉自己:任何存储操作都要三思而后行,备份永远是第一位的

现在的存储技术发展很快,从传统的本地存储到分布式存储,从物理机到虚拟化再到容器化,技术在变,但基础的原理和思维方式是不变的。希望大家能够:

  1. 打好基础:扎实掌握分区、文件系统、LVM等基础知识
  2. 注重实践:多在测试环境练习,积累实际操作经验
  3. 保持学习:关注新技术发展,但不要忘记基础
  4. 建立规范:制定标准的操作流程和应急预案
  5. 分享交流:多与同行交流经验,共同提高

运维这条路不容易,但很有意思。每解决一个问题,每优化一个性能瓶颈,每成功恢复一次故障,都会让我们成长。希望这篇文章能够帮助到正在这条路上奋斗的朋友们。

技术的路很长,我们一起走。如果你在工作中遇到存储相关的问题,或者有什么好的经验想要分享,都欢迎留言讨论。让我们在交流中共同进步,在实践中不断成长!

觉得这篇文章有用的话,别忘了点赞、转发、收藏三连击!你的支持是我持续分享的动力。关注@运维躬行录,我会持续分享更多实用的运维技术和经验,让我们一起在运维的道路上精进技艺,共同成长!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Linux磁盘分区模式详解
    • MBR分区模式(Master Boot Record)
    • GPT分区模式(GUID Partition Table)
  • 常用磁盘分区命令详解
    • fdisk命令 - MBR分区的老朋友
    • parted命令 - 现代分区的多面手
    • gdisk命令 - GPT分区专家
    • lsblk命令 - 查看块设备信息
  • 一块新磁盘的完整处理流程
    • 步骤1:识别新磁盘
    • 步骤2:选择分区模式并创建分区
    • 步骤3:创建文件系统
    • 步骤4:创建挂载点并挂载
    • 步骤5:配置开机自动挂载
  • 逻辑卷管理(LVM)实战
    • LVM核心概念
    • 创建LVM的完整流程
    • LVM容量调整实战
    • LVM快照功能
  • 实际生产环境案例分析
    • 案例1:数据库服务器磁盘规划
    • 案例2:Web服务器存储优化
    • 案例3:在线扩容实战
  • 最佳实践与注意事项
    • 磁盘分区最佳实践
    • 安全操作建议
    • 性能优化建议
  • 故障排除与恢复
    • 常见问题及解决方案
    • 数据恢复技巧
    • 监控与预警系统
  • 自动化运维脚本
    • 磁盘初始化脚本
    • LVM扩容脚本
    • 系统健康检查脚本
  • 存储技术发展趋势
    • 性能调优深入
    • 企业级存储方案
    • 故障预防与应急响应
    • 监控与告警进阶
    • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档