前言
今天咱们来聊聊Linux磁盘管理这个话题。说起磁盘管理,这可是每个运维工程师都绕不开的基本功。不管是新服务器上线、存储扩容,还是系统迁移,都离不开对磁盘的操作。
见过太多因为磁盘操作不当导致的"血案"了。数据丢失、系统崩溃、业务中断...这些惨痛的教训告诉我们,掌握正确的磁盘管理方法有多重要。
今天我就以Red Hat Enterprise Linux为例,从最基础的分区概念开始,到高级的逻辑卷管理,给大家来个全方位的磁盘管理实战指南。不管你是刚入门的新手,还是想要系统梳理知识的老手,相信都能从中收获满满。
MBR是传统的分区模式,从DOS时代就开始使用,至今仍然广泛应用。
MBR的特点:
分区类型:
我记得刚开始做运维的时候,经常被这个4个主分区的限制搞得头疼。有一次给服务器分区,需要分出系统分区、数据分区、日志分区、备份分区等好几个,结果发现主分区不够用,只能删掉重新规划,折腾了大半天。
GPT是新一代的分区标准,解决了MBR的诸多限制。
GPT的优势:
什么时候选择GPT:
现在新采购的服务器,我基本都推荐使用GPT分区模式。虽然有些老的系统可能不兼容,但从长远来看,GPT是趋势。
fdisk是Linux下最经典的分区工具,主要用于MBR分区。
基本语法:
fdisk [选项] 设备名
常用操作:
# 查看磁盘分区信息
fdisk -l
# 对指定磁盘进行分区操作
fdisk /dev/sdb
fdisk交互命令:
p
:显示分区表n
:创建新分区d
:删除分区t
:改变分区类型w
:保存并退出q
:不保存退出实际操作示例:
[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是更现代的分区工具,支持MBR和GPT两种模式。
基本语法:
parted [选项] [设备名] [命令]
常用操作:
# 查看所有磁盘信息
parted -l
# 进入交互模式
parted /dev/sdb
# 非交互模式创建分区
parted /dev/sdb mkpart primary 0% 50%
parted交互命令:
print
:显示分区表mklabel
:创建分区表类型mkpart
:创建分区rm
:删除分区resizepart
:调整分区大小GPT分区实例:
[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分区,操作方式类似fdisk。
# 对GPT磁盘进行分区
gdisk /dev/sdb
这个命令用来查看系统中所有块设备的层次结构。
[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
现在让我通过一个完整的实例,演示如何处理一块新添加的磁盘。
# 查看所有磁盘
lsblk
# 查看磁盘详细信息
fdisk -l
# 也可以查看/proc/partitions
cat /proc/partitions
假设我们发现了一块新的10GB磁盘 /dev/sdb
。
方案一:使用fdisk创建MBR分区
[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分区
[root@server ~]# parted /dev/sdb
(parted) mklabel gpt
(parted) mkpart data1 0% 80%
(parted) mkpart data2 80% 100%
(parted) quit
# 创建ext4文件系统
mkfs.ext4 /dev/sdb1
mkfs.ext4 /dev/sdb2
# 或者创建xfs文件系统(RHEL7+推荐)
mkfs.xfs /dev/sdb1
mkfs.xfs /dev/sdb2
# 创建挂载点
mkdir -p /data1 /data2
# 临时挂载
mount /dev/sdb1 /data1
mount /dev/sdb2 /data2
# 验证挂载
df -h
# 获取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(Logical Volume Manager)是Linux下的逻辑卷管理器,它提供了比传统分区更灵活的磁盘管理方式。在生产环境中,LVM几乎是标配,因为它可以动态调整容量,这对于业务系统来说太重要了。
在开始实操之前,我们先理解几个核心概念:
简单理解就是:把多个硬盘或分区(PV)组成一个大的存储池(VG),然后从这个池子里分配空间创建虚拟的分区(LV)。
让我通过一个实际案例来演示整个流程。假设我们有两块新硬盘/dev/sdb
和/dev/sdc
,需要创建LVM来管理。
步骤1:准备物理卷(PV)
# 首先查看可用磁盘
lsblk
# 创建物理卷(可以是整个磁盘或分区)
pvcreate /dev/sdb /dev/sdc
# 查看物理卷信息
pvdisplay
pvs
输出示例:
[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)
# 创建卷组
vgcreate datavg /dev/sdb /dev/sdc
# 查看卷组信息
vgdisplay datavg
vgs
输出示例:
[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)
# 创建逻辑卷(指定大小)
lvcreate -L 10G -n datalv datavg
# 创建逻辑卷(使用百分比)
lvcreate -l 50%VG -n applv datavg
# 查看逻辑卷信息
lvdisplay
lvs
输出示例:
[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:创建文件系统并挂载
# 创建文件系统
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:配置自动挂载
# 编辑/etc/fstab
vim /etc/fstab
# 添加以下内容
/dev/datavg/datalv /data xfs defaults 0 2
/dev/datavg/applv /app xfs defaults 0 2
# 测试配置
mount -a
LVM最大的优势就是可以动态调整容量。在我的运维生涯中,这个功能救过我无数次。
场景: /data
分区空间不足,需要扩容
# 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:
# 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系列文件系统支持。
# 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
在线扩展示例:
对于某些文件系统,可以实现在线扩展,不需要卸载:
# xfs文件系统在线扩展
lvextend -L +2G /dev/datavg/datalv
xfs_growfs /data
# ext4文件系统在线扩展
lvextend -L +2G /dev/datavg/applv
resize2fs /dev/datavg/applv
LVM还提供了快照功能,这在数据备份和测试环境中非常有用。
# 创建快照(快照大小根据变化量估算)
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
我经常在数据库升级前创建快照,如果升级失败可以快速回滚。不过要注意,快照会影响性能,不建议长期保留。
场景: 新上线一台MySQL数据库服务器,配置4块1TB SAS硬盘。
需求分析:
规划方案:
# 磁盘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 # 临时目录
为什么这样规划:
场景: Web服务器需要存储大量静态文件,访问频繁,需要优化存储结构。
原始状况:
优化方案:
# 添加新磁盘,使用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
优化效果:
场景: 电商网站图片存储空间告急,需要紧急扩容,不能影响业务。
告警信息:
[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
扩容步骤:
# 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. 合理规划分区大小
# 推荐的分区规划
/boot 1GB # 引导分区,1GB足够
/ 30-50GB # 根分区,不要太大也不要太小
/var 20GB+ # 变量数据,日志文件存放
/var/log 单独分区 # 防止日志填满系统盘
/tmp 单独分区 # 临时文件,可设置noexec参数
swap 内存1-2倍 # 物理内存大于8GB时可以等于内存大小
2. 选择合适的文件系统
# 不同场景的文件系统选择
系统分区: xfs(RHEL7+默认)
数据分区: xfs(大文件性能好)
日志分区: ext4(小文件性能好)
临时分区: tmpfs(内存文件系统)
3. 使用LVM管理数据盘
# 数据盘强烈推荐使用LVM
# 系统盘可以不用LVM,保持简单
# 为VG预留10-20%的空间用于快照和扩容
vgcreate -s 32M datavg /dev/sdb /dev/sdc # 大容量使用大PE
1. 操作前必须备份
# 备份分区表
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而不是设备名
# /etc/fstab中推荐使用UUID
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data xfs defaults 0 2
# 而不是使用设备名(可能会变化)
/dev/sdb1 /data xfs defaults 0 2
3. 测试配置
# 修改/etc/fstab后必须测试
mount -a
echo $? # 返回0表示成功
# 检查挂载状态
df -h
findmnt
4. 设置合适的挂载参数
# 针对不同用途设置不同参数
/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. 分区对齐
# 使用parted创建分区时确保对齐
parted /dev/sdb mkpart primary 2048s 100%
# 检查分区对齐
parted /dev/sdb align-check optimal 1
2. 选择合适的PE大小
# 根据VG大小选择PE大小
小于16GB: 4MB(默认)
16GB-256GB: 8MB
256GB-1TB: 16MB
大于1TB: 32MB
vgcreate -s 32M large_vg /dev/sdb
3. I/O调度器优化
# 查看当前调度器
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显示异常
# 使用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命令报错,无法激活卷组
# 扫描并修复
pvscan --cache
vgscan --mknodes
lvscan
# 强制激活(谨慎使用)
vgchange -ay --partial datavg
# 从备份恢复LVM配置
vgcfgrestore datavg
问题3:文件系统损坏
症状:无法挂载,提示文件系统错误
# 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配置错误导致启动失败(敲黑板,这个非常常见)
这是我遇到过最多的问题之一,解决方法:
# 1. 进入单用户模式或救援模式
# 2. 重新挂载根分区为可写
mount -o remount,rw /
# 3. 修复/etc/fstab
vim /etc/fstab
# 注释掉有问题的行或修正配置
# 4. 测试配置
mount -a
# 5. 重启系统
reboot
当发生严重的数据丢失时,可以尝试以下恢复方法:
1. 使用ddrescue恢复数据
# 安装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恢复文件
# photorec是testdisk套件的一部分
photorec /dev/sda
# 或者在镜像上恢复
photorec /backup/sda_image.img
3. 恢复ext4删除的文件
# 使用extundelete恢复
yum install extundelete
# 恢复所有删除的文件
extundelete /dev/sda1 --restore-all
# 恢复特定文件
extundelete /dev/sda1 --restore-file /path/to/file
建立完善的监控系统可以提前发现问题:
1. 磁盘空间监控脚本
#!/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状态监控
#!/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. 设置定时任务
# 添加到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
为了提高工作效率,我编写了一些实用的自动化脚本:
#!/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"
#!/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
#!/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. 容器存储
# 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. 软件定义存储
# 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. 云存储集成
# 挂载阿里云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调度器优化
# 查看和设置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. 文件系统参数调优
# 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性能优化
# 使用适当的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. 多路径存储
# 安装multipath
yum install device-mapper-multipath
# 配置multipath
mpathconf --enable --with_multipathd y
# 查看多路径设备
multipath -ll
2. 存储复制和同步
# 使用rsync同步数据
rsync -avz --progress /data/ backup-server:/backup/data/
# 使用DRBD实现块级复制
drbdadm create-md r0
drbdadm up r0
drbdadm primary --force r0
3. 快照策略
#!/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. 预防性维护
#!/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. 应急响应预案
#!/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监控
# 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. 自定义监控指标
#!/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不熟悉,在扩容时操作失误导致了数据丢失,那一夜的通宵达旦和焦虑至今记忆犹新。从那以后,我就告诉自己:任何存储操作都要三思而后行,备份永远是第一位的。
现在的存储技术发展很快,从传统的本地存储到分布式存储,从物理机到虚拟化再到容器化,技术在变,但基础的原理和思维方式是不变的。希望大家能够:
运维这条路不容易,但很有意思。每解决一个问题,每优化一个性能瓶颈,每成功恢复一次故障,都会让我们成长。希望这篇文章能够帮助到正在这条路上奋斗的朋友们。
技术的路很长,我们一起走。如果你在工作中遇到存储相关的问题,或者有什么好的经验想要分享,都欢迎留言讨论。让我们在交流中共同进步,在实践中不断成长!
觉得这篇文章有用的话,别忘了点赞、转发、收藏三连击!你的支持是我持续分享的动力。关注@运维躬行录,我会持续分享更多实用的运维技术和经验,让我们一起在运维的道路上精进技艺,共同成长!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。