1. 磁盘管理,Linux运维迈不过去的坎
搞Linux系统,不管你是刚入门没多久的新手,还是混迹多年的老运维,磁盘管理永远是个绕不开的活。装系统要分区,磁盘满了要清理,新加了一块硬盘要让系统认识它,服务器跑着跑着IO性能不行了要定位瓶颈——这些全是磁盘管理的范畴。可以这么说,一个搞Linux的人基本功扎不扎实,看磁盘管理这块就知道个七八成。
平时工作中,我最常看到两类人:一类是只会用df -h看个使用率,满了就瞎找文件删,也不知道怎么看哪块盘在读写,更不清楚系统盘和数据盘的区别;另一类是命令背得滚瓜烂熟,fdisk、mkfs、mount用得比吃饭还熟练,但让他说说为什么分区要对齐、以及内核分区表为什么默认选fdisk而不是parted,就支支吾吾了。说白了,知道怎么敲命令的人很多,真正理解磁盘管理背后逻辑的人很少。
这篇文章我就把自己这些年折腾Linux磁盘管理的经验梳理一遍。从最基础的分区、格式化、挂载,到系统环境下的监控排查思路,每个环节都会结合我实际操作中遇到的场景来讲,尽量把命令背后的原理说清楚,把那些文档里不写、但实操中非常关键的避坑点列出来。不管你手头是只有一块硬盘的个人电脑,还是几十块盘的生产环境,这套思路都能用得上。看完这篇文章,你至少能把磁盘管理的整个流程串起来,知道问题出现的时候该往哪个方向排查。
2. 动手之前,先把磁盘的底细摸清楚
拿到一台新机器,或者手动加了一块硬盘之后,第一件事绝不是急着分区,而是先把机器上现有的磁盘情况和系统状态摸清楚。不夸张地说,一半的误操作事故都是因为没搞清楚设备对应关系,结果在错误的硬盘上执行了mkfs,数据全没了,连后悔药都没得吃。
2.1 三条命令快速看清磁盘拓扑
在Linux里,磁盘设备的命名有一套自己的规矩。传统的机械硬盘和绝大多数虚拟机磁盘走的是SD协议,设备名一般叫sda、sdb、sdc这样排下去;NVMe固态硬盘则是nvme0n1、nvme1n1的形式,后面的n1代表第一个命名空间,下面的p1、p2代表分区。搞清楚这个命名规律之后,再看命令输出就比较直观了。
我排查磁盘问题的第一步永远是lsblk,这条命令以树状结构展示块设备,整个系统的磁盘拓扑一眼就能看明白。
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 120G 0 disk ├─sda1 8:1 0 512M 0 part /boot/efi ├─sda2 8:2 0 1G 0 part /boot └─sda3 8:3 0 118.5G 0 part └─centos-root 253:0 0 50G 0 lvm /看这个输出,sda3下面挂了一个centos-root的逻辑卷,分区的层级关系、每块盘的大小、挂载点在哪,一秒定位。我习惯在lsblk后面加个-p参数,把/dev/sda这种完整路径也打出来,因为脚本里处理的时候直接用完整路径更稳妥,少一层转换。
如果说lsblk负责展示结构,那blkid就是负责暴露信息。它会显示分区的UUID、文件系统类型、PARTUUID这些属性。这里我可以特别提醒一句:UUID这个字段极其重要,后面配置自动挂载的时候,我们依赖的就是它,而不是设备名。设备名在内核枚举顺序变化之后可能不固定,但UUID是分区格式化时生成的一个唯一标识,只要不重新格式化,基本不会变。
$ blkid /dev/sda2 /dev/sda2: UUID="a3f9d1c2-8e47-4d2b-b1e2-8f0a9c3d6e71" TYPE="xfs"第三件要干的事,是看当前文件系统的实际使用情况,用的就是最常见的df -h。这里有一个很多新人容易忽略的细节:df -h默认显示的是挂载点的使用率,但如果你直接df -h /dev/sda3,输出的还是这个设备对应挂载点的数据。真到排查根因的时候,df显示的使用率并不等于磁盘占用快照的全部,还有一些预留块和元数据空间不会直接列出来,这个后面我展开讲。
2.2 别拿使用率当唯一指标
不少朋友对磁盘的状况判断完全依赖df -h,看到使用率没过80%就觉得一切正常。这种想法在个人电脑上问题不大,但在服务器上可能要吃大亏。生产环境下,文件系统的使用率只是液体温度计上的刻度,磁盘的整理压力远不止于此——平均负载、IO队列长度、每秒读写次数,这些都是衡量磁盘状态的重要参数。
我自己遇到过一件印象挺深的事。有台数据库服务器,df -h看着使用率只有60%多,但业务方持续报慢查询。排查了很久,后来用iostat -x 1才定位到那块盘的%util长期保持在95%以上,等待IO的进程队列堆了一长串。问题根本不在空间上,而是磁盘故障导致的读写性能劣化。
所以磁盘管理,空间维度只是其中一个方面,还要同时关注状态维度。前者靠df、du这类工具,后者靠iostat、sar -d这类性能工具。一条iostat -x 1,每秒刷新一次,在持续观察几轮之后,%util、await、svctm这几个指标能告诉你磁盘到底是在正常服务还是已经快累垮了。
说到du还得提一嘴,排查“磁盘满了但不知道什么占的”这种问题,最佳工具是du而不是find或者ls。我通常的命令组合是:
$ du -h --max-depth=1 /var 2>/dev/null | sort -h $ du -sh /* 2>/dev/null | sort -h第一行先看某个大目录下面各子目录的体积,第二行直接把根目录下每个一级目录的体积排序。找到最大的目录,再往下继续du --max-depth=1,逐步缩小范围。排查的效率和准确度要比乱猜高得多。
2.3 工具选型之前,先操作系统底牌
现在的发行版里,分区工具包括fdisk,来自util-linux工具集,老牌且支持MBR和GPT分区表,兼容性极好,但交互式操作在设计上稍显老旧,脚本化能力偏弱。parted适合处理超大磁盘和更精细的对齐需求,命令行模式能力很强,但容错率也相对低,一个参数写错就可能造成不可逆的修改。gdisk则是专门为GPT分区表设计的,当你需要处理2TB以上磁盘时它是个好选项。
我的建议是,日常操作先用fdisk,搭配lsblk确认设备结构。处理2TB以上的盘时,建议选择parted或者gdisk。MINI个人电脑装机或虚拟化环境里跑几块小盘,fdisk完全够用。生产环境推荐优先使用parted,尤其是脚本自动化的时候,非交互模式配合参数能省去无数人肉确认的麻烦。
注意:
fdisk对GPT分区表是支持的,但老版本的fdisk存在一些细节差异,例如分区对齐的处理。CentOS 7之后自带的util-linux版本对GPT已经很友好,Ubuntu 18.04之后也没问题。遇到太老的系统,建议先用parted -l看一眼分区表类型再做决定。
3. 分区与格式化,动刀之前先想清楚三件事
分区和格式化是磁盘管理里风险最高的两个环节,动的是真格。这步一旦出错,轻则分区表损坏系统起不来,重则数据直接蒸发。所以我在这一章把规划思路放在操作步骤前面,先把该想清楚的问题说完,再给具体命令。
3.1 分区方案设计,Plan A和Plan B的区别
第一要决定的是分区表格式:MBR还是GPT。MBR是老的方案,最大只支持2TB容量的磁盘,而且主分区数量限制在4个,扩展分区和逻辑分区这套机制用起来也让人头疼。GPT是UEFI时代的事实标准,支持2TB以上容量,理论上可以建128个分区,而且自带备份分区表,容错性远比MBR强。
现在新装的机器,我几乎无脑推荐GPT。有些朋友担心旧机器兼容性问题,实际上只要机器支持UEFI启动,GPT基本都能用。只有那种老掉牙的BIOS+MBR组合、跑着上古版本系统的机器,才需要为了兼容性继续用MBR。
第二件事,数据盘到底要不要做LVM。关于LVM的争论我见过太多,这里不预设立场,说一下我的实操结论:系统盘装在服务器上,空间规划没把握,就准备上LVM;个人电脑或简单业务,分区挂载足够清晰的话,LVM的灵活性收益有限,还会给你多加一层逻辑抽象,排查问题的时候多一环。但如果磁盘要动态扩容、要做快照,LVM几乎是刚需,这是纯粹的物理分区无法方便做到的事情。没有特殊需求,就别给自己找麻烦,一步到位用LVM也完全可以——我服务过的不少企业,数据盘也全是LVM,出了问题照样能解决。
第三件事,分区对齐。很多新手在这里踩坑——SSD硬盘分区没对齐,性能直线下降,本来能跑满的IO写速度直接砍半。分区对齐指的是分区起始位置是物理扇区大小(常见为4096字节)的整数倍。绝大多数现代分区工具默认就是对齐的,但用老版本工具或手动指定参数时就需要留意了。对齐检查可以用parted查看:
$ parted /dev/sda align-check optimal 1 1 aligned看到aligned就说明没问题。
3.2 fdisk与parted的实操脚本
确定方案之后,操作就按部就班了。最传统的方式,用fdisk来做。下面是一次完整的分区创建过程:
$ fdisk /dev/sdb Welcome to fdisk (util-linux 2.23.2). 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): 1 First sector (2048-209715199, default 2048): Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-209715199, default 209715199): +100G ... Command (m for help): w里面值得注意的就是First sector这一行,直接回车用默认值2048,这不只是一个数字,背后对应的是1MB对齐的标准做法。分区起始于1MiB的位置,保证后续所有对齐计算都不出问题。以前老教程会教人手算柱面起始位置,现在完全没必要了。
parted则是另一种思路,适合脚本化和处理大容量磁盘。看看如何用一行命令把整块盘分成一个大分区:
$ parted /dev/sdc --script mklabel gpt mkpart primary xfs 2048s 100%这里做了两件事:mklabel gpt把分区表设为GPT,mkpart创建了一个分区。2048s和100%分别指定起始和结束位置,起始位置留出2048个扇区,保证对齐。执行完用parted /dev/sdc print验证一下,比用fdisk的交互式菜单要省事得多。
3.3 mkfs格式化选择,xfs与ext4的取舍
分区建好之后是格式化。选择文件系统成了一个关键决策,各家策略也不完全一样。xfs在性能扩展性上表现优秀,特别适合大文件、大容量场景,CentOS/RHEL 7之后也顺势成了默认文件系统,但它有个短板——不支持缩减,分区只能扩大不能缩小。ext4是Linux老牌文件系统,向下兼容性非常好,支持缩容(虽然过程很麻烦),小文件场景下表现稳健。实际使用中,系统盘数据量小的用ext4完全没压力,数据盘增速快、以后可能要扩容的,直接用xfs更符合长期演进策略。
格式化的命令都很简单,只是方向上不能选错:
$ mkfs.xfs /dev/sdb1 $ mkfs.ext4 /dev/sdb1如果分区之前已经被使用过,mkfs会给出确认提示,这是它保护数据的方式。但这里我要着重强调:mkfs执行之后,原有数据基本没有恢复的可能,所以执行之前至少用blkid和lsblk再确认一遍目标设备,确认没有拼写错误。我在生产环境里,格式化前还会在fdisk -l里重新看一遍对应盘的容量和型号,和现场标签做交叉验证,多一个确认环节就多一道保险。
格式化完成后还有个容易被忽略的小步骤:文件系统检查。xfs系用xfs_check或xfs_repair -n(只读检查),ext4系用e2fsck -f。新格式化的盘一般不会出问题,但如果你格式化的是一块重新利用的旧盘,跑一遍检查可以提前把坏块风险暴露出来,免得挂上去之后才出幺蛾子。
4. 挂载与自动挂载,让系统认识并使用新磁盘
分区格式化之后,磁盘还只是一个存放文件系统数据的地方,系统并不会自动把这块区域变成你可以访问的目录。挂载——把这个文件系统关联到某个目录上——才是真正让它服务于业务的最后一步。这一步看起来简单,里面却有不少需要注意的细节。
4.1 mount命令背后的机制
挂载的本质可以用一句话说清:让某个文件系统出现在系统目录树的某个位置。执行
$ mount /dev/sdb1 /data之后,/data目录就成了访问/dev/sdb1上所有文件的入口。这里有个关键问题——/data目录本身必须是一个已经存在的目录。如果/data不存在,mount会直接报错;如果/data是空目录,挂载后原目录里看不到内容也正常;但如果/data目录下本来有文件,挂载之后这些文件会被暂时隐藏,直到卸载才重新出现。这个特性经常把新手绕晕,误以为数据丢了,其实并没有,只是被挂载点给覆盖了视角而已。
挂载时还可以指定很多参数,这些参数往往比想象中更关键。比如:
$ mount -o noatime,nodiratime /dev/sdb1 /datanoatime的意思是,文件被读取时不更新访问时间戳。这个参数对于高IO场景效果立竿见影,因为默认的atime更新会带来大量额外的写IO。日志系统、数据库数据文件这类以读为主或读写频繁的场景,加上noatime能显著降低不必要的写放大。网上经常有人问为什么数据库性能差,查了一圈发现是atime更新的锅,这个参数就是为这种场景准备的。
4.2 写入/etc/fstab的几个陷阱
mount命令挂载的盘,重启后就没了。要想开机自动挂载,得写入/etc/fstab。这个文件是系统启动时自动读取的挂载配置,格式看起来简单,写错一个字段就可能造成系统启动异常,所以这里尤为需要耐心。
来看一个标准条目:
UUID=a3f9d1c2-8e47-4d2b-b1e2-8f0a9c3d6e71 /data xfs defaults,noatime 0 2六个字段从左到右分别是:设备标识、挂载点、文件系统类型、挂载参数、是否dump备份、是否开机检查。第一个字段我用的不是/dev/sdb1而是UUID,这是我在前面强调过的原因——设备名可能因为内核枚举顺序变化而改变,UUID却稳定得多。这也是为什么前面要说blkid这个命令,它就是为了拿到这个UUID。
参数里有一个非常容易踩坑的情况:文件系统类型写错。如果你用过xfs格式化,但/etc/fstab里类型写着ext4,系统启动时挂载会失败。有些人不确定具体类型,就写auto让系统自动探测,这种写法能用,但我不太推荐,因为自动探测增加了启动阶段的不确定性,明确写清类型反而更稳妥。
第六个字段也有讲究。0表示开机不做fsck检查,1表示根文件系统要检查,2表示其他文件系统要检查。个人电脑小规模环境,写0和2都可以;但生产环境建议按规范写,给数据盘一个合理的检查级别,在系统异常断电之后,开机阶段自动跑一次文件系统检查有时候能挽救很多麻烦。
/etc/fstab写完,强烈建议执行一次验证:
$ mount -a这条命令会根据/etc/fstab尝试挂载所有尚未挂载的条目。如果输出没有报错,基本说明配置没问题;如果报错,马上改还来得及,别等到重启才发现起不来系统。这条命令被我视为操作fstab后必经的检查步骤,几乎每次都做。
4.3 swap分区和设备绑定
磁盘管理除了常规数据盘,还有一类特殊分区——swap。swap是Linux的虚拟内存扩展,物理内存不够时,内核会把部分不常用的内存页换到swap上,相当于给内存加了一块“备胎”。swap分区的创建和管理方式跟普通分区不太一样。
用分区做swap的流程大致是这样:
$ mkswap /dev/sdb2 $ swapon /dev/sdb2mkswap把分区格式化成swap格式,swapon让系统启用它。临时关闭某个swap分区用swapoff /dev/sdb2。如果要用文件而不是分区来做swap,流程也类似,先dd创建文件,再mkswap,再swapon,但性能上一般不如分区方案,生产环境优先考虑分区或LVM逻辑卷。
关于swap大小,网上流传着“内存的两倍”这种旧公式,实际上现在内存动不动就几十GB,再按两倍设纯属浪费磁盘。我一般建议:物理内存小于4GB时设置等于内存大小的swap,内存8GB~16GB时设4GB~8GB swap,内存再大就按业务需求灵活调整,甚至设到2GB~4GB也够用。判断swap是否够用,看free -h里的swap used,以及vmstat里si、so两个列是否持续非零,如果持续有大量换入换出,说明内存压力已经传到swap上了,优先加物理内存,而不是继续堆swap。
5. 磁盘日常监控与隐患排查,别等出事了才想起来
磁盘管理的最高境界不是出问题时能快速恢复,而是问题还在萌芽阶段就把它摁掉。这需要一套日常监控手段和一个清晰的问题排查思路。这一章的内容全部来自我处理过的真实故障场景,每一个都对应着某种常见隐患。
5.1 空间耗尽的慢排查与快定位
“磁盘满了”——这是运维接到最多的告警之一。满,其实分两种:一种是真的被文件占满了,df -h看得清清楚楚;另一种是df -h显示没满,但应用写不进数据了。第二种情况比第一种隐蔽得多,排查起来也更容易走弯路。
最经典的隐藏占用是文件被删除但进程还持有句柄。某个日志文件被rm了,但写这个文件的进程没有重启,文件句柄还开着。从文件系统角度看,这个空间已经被释放了,但进程仍然在往这个“幽灵文件”里写数据,空间一直不会归还。表象就是df -h显示使用率一直在涨,但你用du找遍所有目录都找不到大文件。这种时候用lsof | grep deleted一查,立刻现原形:
$ lsof | grep deleted java 12345 app 2w REG 253,0 10737418240 1048577 /var/log/bigapp.log (deleted)找到对应进程,确认日志文件确实可以删除,重启进程或者让应用重新打开文件句柄,空间就会回来。这类问题在日志量很大的Java应用上最常出现,我处理过不止一次。
另一种空间耗尽来自inode耗尽。inode是文件系统存储元数据的结构,每个文件或目录都要占用一个inode。如果一个分区里堆积了大量极小的文件(比如缓存目录、邮件队列、Docker容器产生的临时文件),文件个数达到上限,即使磁盘还有剩余空间,也创建不了任何新文件。判断方法很简单:
$ df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda3 1310720 1310720 0 100% /看到IUse%超过90%就该警惕,到了100%就会报“No space left on device”,而df -h可能才用了不到一半。解决办法通常是找出海量小文件所在目录,批量清理,比如find /var -xdev -type f -size +1M配合清理策略,或者直接把这类应用的数据目录挪到inode配额更充裕的分区上。
5.2 IO性能问题,从数据中定位瓶颈
磁盘性能问题的排查比空间问题复杂,因为它不是非黑即白的,往往伴随多种症状:业务响应慢、CPU iowait升高、应用卡顿。我的排查入口永远是iostat,而且后台常开几个采集窗口。
$ iostat -x 1 5这条命令的意思是每秒采样一次,共采样5次。输出里面的%util是磁盘忙碌百分比,await是IO请求平均处理时间(毫秒),svctm是设备IO服务时间。几个指标要结合起来看:
%util接近100%说明磁盘的IO请求已经饱和,基本可以断定瓶颈就在磁盘本身。await数值异常大但svctm正常,说明IO请求在排队,通常是并发请求太多导致。r_await和w_await分别表示读写延迟,如果写延迟是读延迟的好几倍,那可能要考虑文件系统配置、日志落盘机制或者磁盘本身写性能的问题。
有一次排查一个数据库备份卡住的案例,iostat显示%util只有30%多,但await高达400多毫秒。一开始我以为是磁盘阵列有问题,后来检查发现两块数据盘做了软RAID1,其中一块磁盘已经处于降级状态,所有读写都要靠另一块盘支撑,性能自然骤降。换掉故障盘,重建RAID,延迟立刻回到正常水平。所以IO性能排查,一定要把硬件状态也纳入视野,别只盯着软件指标。
5.3 日常巡检该盯的几个数据点
说实话,与其天天靠告警救命,不如建立一套简单的日常巡检习惯,很多隐患在告警发生之前就暴露了。我自己的巡检清单通常包含四个维度。
磁盘空间使用率是一个基础维度。设置阈值告警的做法比较通用,比如数据盘使用率超过85%就告警,超过92%就必须处理。留出足够余量不是因为强制要求,而是给清理和扩容争取时间窗口。主线业务在不需要停服的情况下完成扩容,本身就是运维水平的一部分。
inode使用率是一个需要同步关注的维度。空间使用率和inode耗尽,触发条件不同,但解决办法类似。把df -i纳入日常巡检清单,能避免那种“明明有空间却写不进文件”的诡异故障。
磁盘健康状态主要依赖S.M.A.R.T.信息。查看磁盘健康度,smartctl是个方便的工具:
$ smartctl -H /dev/sda输出SMART overall-health self-assessment test result: PASSED代表正常。一旦出现FAILED就要尽快备份数据、准备换盘。很多硬盘故障其实是有先兆的,只是没人去看这个状态。不要等到盘真的挂了才开始想办法。
IO性能基线是容易被忽视的一个维度。不要只在出问题时才看iostat,平时就要记录工作负载下的正常性能值。比如某个数据盘正常负载下%util是40%,你平时就知道了,等某天突然升到85%,即使没触发告警,你也会心里有数,提前预警。反过来,不了解基线水平,看到一个60%的%util数据也无法判断正不正常。
6. 实战复盘,一次完整的新盘上线过程
把前面所有知识点串起来,我复盘一次实际工作中给数据库服务器加新数据盘的全过程。这个案例里我用到的每一步都值得你对照自己的环境过一遍。
6.1 场景描述与方案确认
场景是这样的:一台跑着业务的数据库服务器,数据盘快满了。硬件同事新加了一块8TB的SATA盘(设备名识别为sdc),要我把它做成一个数据目录挂上去,把部分历史数据迁过去。系统版本是CentOS 7,内核3.10,数据库文件放在原来的/data目录下,新盘要挂到/data2。
首先要确认新盘是否被系统正确识别:
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 240G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 239G 0 part └─centos-root 253:0 0 239G 0 lvm / sdb 8:16 0 2T 0 disk └─sdb1 8:17 0 2T 0 part /data sdc 8:32 0 8T 0 disksdc容量8T,确认无误。
这里可以直接看到,8T的分区必须用GPT,因为MBR最大只支持2TB。原来那块数据盘sdb是2T,早期规划时用了MBR,好在线性扩容没受影响,但现在如果还用MBR就会碰到容量上限,此时转型GPT就是板上钉钉的选择。
6.2 分区、格式化、挂载的完整记录
分区操作我用parted的非交互模式一步完成:
$ parted /dev/sdc --script mklabel gpt mkpart primary xfs 2048s 100%跑完确认一下分区结果:
$ parted /dev/sdc print Model: ATA ST8000VX004 (scsi) Disk /dev/sdc: 8001GB Sector size (logical/physical): 512B/4096B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 8001GB 8001GB primary1049kB的起始位置正好对应2048扇区,对齐问题不用担心。接着格式化,考虑到将来扩容和数据量增长,文件系统选xfs:
$ mkfs.xfs -f /dev/sdc1-f参数是强制格式化,如果分区上残留有旧文件系统时的确认提示,直接跳过。这里我特意确认过/dev/sdc1对应的就是那台新8T盘,才敢加这个参数,这一点极其重要,必须再次强调。
创建挂载点目录、挂载、写/etc/fstab:
$ mkdir -p /data2 $ mount /dev/sdc1 /data2 $ blkid /dev/sdc1 /dev/sdc1: UUID="e07a30f8-5b42-43c7-98fd-2e0a6bc1d3f4" TYPE="xfs"然后把下面这行追加到/etc/fstab里:
UUID=e07a30f8-5b42-43c7-98fd-2e0a6bc1d3f4 /data2 xfs defaults,noatime 0 2最后验证挂载配置,然后重启前做个复验:
$ mount -a $ df -h /data2 Filesystem Size Used Avail Use% Mounted on /dev/sdc1 8.0T 33M 8.0T 1% /data26.3 回顾与优化点
现在回看这个操作流程,还可以优化一个点:如果预算允许,数据盘建议用LVM而不是直接整个裸分区。在这个案例里,直接分区挂载也能用,但将来如果/data2又满了,想不想扩容就要看当时环境有没有余量磁盘了。LVM的好处在于,扩容时可以随时加PV、扩展LV,不用停机迁移数据。如果你在做这类规划,数据盘建议预留LVM的余地——虽然多一层抽象增加了管理和排查成本,但在动态扩容这个需求面前,收益是实打实的。
另外,这台机器是数据库服务器,挂载参数defaults,noatime基础上还可以考虑加nobarrier(针对老内核)之类的优化,但这类参数对数据安全有一定影响,需要结合具体的存储硬件和应用场景来评估,不能盲从。
7. 踩过的坑和长期经验总结
这些年在磁盘管理上踩过的坑,有一半以上来自初期操作时不够谨慎。教训总结出来,比看十遍文档都有用。
最大的坑永远是误操作。有一次在测试环境本想对sdb做分区,结果fdisk里敲了个/dev/sda,好在发现及时,只是在交互界面里看了一眼就退出了。生产环境里这种事绝对不能发生,我的做法是形成一套强制检查习惯:所有涉及格式化和分区的命令执行前,必须lsblk确认设备对应关系,再对照机器上的磁盘标签做交叉验证,命令里出现/dev/字样的时候,多看一眼再回车。
/etc/fstab写错导致系统无法启动是另一个高频事故。最常见的情况是挂载参数或文件系统类型写错,系统启动时挂载失败,直接卡在emergency mode。我在前面反复强调mount -a先验证,就是防这个。真到了系统起不来那一步也不用慌,在initramfs模式下直接编辑/etc/fstab把错误行注释掉,重启后系统恢复正常,再静下心修正配置。
文件系统类型混淆也是新手重灾区。xfs和ext4的命令、工具集都不同,xfs系列的xfsdump、xfs_repair只能用于xfs文件系统,e2fsck只能用于ext系列。某些管理工具、监控脚本里如果文件系统类型写错,轻则误报,重则数据损坏。我自己就见过一例,运维同学把e2fsck跑在了一个xfs分区上,结果文件系统超级块被改坏,最终只能从备份恢复。这种低级但代价极高的错误,完全可以通过操作规范避免——确认文件系统类型之后,选择匹配的工具集,再动手。
磁盘空间清理也不能只看文件大小,要考虑日志轮转和保留策略。很多人磁盘满了就rm -rf一顿乱删,删完不久又满了。正确做法是建立日志轮转机制:logrotate配置好按大小或日期轮转、压缩、保留份数。数据和应用目录要定期评估增长趋势,提前规划扩容。这属于“治未病”的范畴,一两次紧急清理能救火,但成体系的容量管理和轮转策略才是长治久安的办法。