麒麟系统根目录扩容:LVM、物理分区与应急清理实战
磁盘空间告警在麒麟系统上比在普通Linux发行版上更让人头疼。原因不复杂银河麒麟V10的安装方式五花八门有人装了LVM自动分区有人手动给根目录单独划了一块还有人图省事直接用了使用整个磁盘的默认选项。等根目录真的满了你面对的分区方案可能跟网上教程完全对不上抄来的命令大概率水土不服。这篇文章我不急着讲命令先把麒麟系统上根目录扩容的几条典型路线全过一遍——从查看现状、临时挤空间到LVM动态扩容、物理分区重建再到虚拟机加盘和目录迁移。你按自己机器的实际情况选一条路走就行过程里我会把我踩过的坑也一并交代清楚。适合正在被根目录100%告警折磨的运维以及给客户部署过麒麟系统的开发同学。1. 动手扩容前先把这四件事查清楚扩容这件事十个人有九个失败在第一步没搞清自己的文件系统类型就开始敲命令。麒麟系统涉及的底层方案太多盲目套用网上命令非常危险下面这几条命令能帮你把现状摸清楚花不了两分钟。1.1 空间满了inode也可能满了先用一条命令定位“满”的本质df -hT / df -i /-hT一起看的话输出里会有Filesystem、Type、Size、Used、Avail、Use%、Mounted on几列Type列是关键它直接告诉你根文件系统是ext4还是xfs。这两类文件系统的扩容命令完全不同后面会细说。df -i /看的是inode使用率很多人会忽略这个。我遇到过一台机器df -h显示还有十几G但应用就是写不进文件报No space left on device最后发现是inode被上百万个小文件耗尽了。判断规则很简单空间满了看df -hT写不进文件但空间有富余就看df -i。两个都看了才不会在扩容时白折腾。1.2 有没有LVM扩容路线完全是两码事接下来看磁盘和分区的整体拓扑lsblklsblk输出会直接展示磁盘、分区和挂载点之间的层级关系。如果根目录所在分区下面还挂着一层比如sda2下面有klvg-root这类名字说明系统用了LVM——这是银河麒麟V10服务器版很常见的默认方案。如果没有这层结构根目录直接对应sda2、nvme0n1p3这类物理分区那就是普通分区方案。这两个方案在扩容上有本质区别LVM方案逻辑卷可以动态扩大只要卷组里有空闲空间文件系统扩容不需要碰分区表风险低很多。普通分区方案分区边界是写在分区表里的扩根分区就得改分区表操作难度和风险都上一个台阶。一句话总结看到LVM恭喜你看不到LVM请直接跳到第4章按物理分区的路子走。1.3 确认文件系统类型这决定扩容用什么命令blkid /dev/sda2 cat /etc/fstab | grep -v ^#blkid能查看到分区的UUID和TYPE字段/etc/fstab则能确认根目录的挂载配置。麒麟V10常见默认文件系统是ext4和xfs两种。这两者的差异非常大ext4可以扩大也可以缩小缩小一般要离线操作不推荐扩大用resize2fs命令命令参数要写设备路径比如resize2fs /dev/sda2。xfs只能扩大不能缩小扩大用xfs_growfs命令参数要写挂载点比如xfs_growfs /。xfs即便在文件系统内部还有空闲空间也不能通过缩小分出一部分给别的分区用。我看到过太多人在xfs上执行resize2fs或者在ext4上执行xfs_growfs结果都是报错后一脸懵。先把Type记清楚后面才不会出错。1.4 备份永远别跳过的一步改分区表属于高危操作一旦断电、误操作或者分区表写坏数据可能全部丢失。动手之前务必做一次备份。虚拟机环境最优先用虚拟化平台做整机快照这是最省事的方案。物理机环境重要数据先复制一份到外部存储至少要把分区表备份了sfdisk -d /dev/sda partition_table_backup.txt这个备份文件很小但关键时候能救命。我之后会在第6章讲一个因为分区表搞坏差点翻车的实例靠的就是这份备份恢复的。2. 不扩容也能救急先把空间挤出来有时候你不一定马上需要扩容。根目录爆满往往不是安装时分区规划有问题而是运行过程中日志、缓存、旧内核把空间慢慢吃光了。先把这些假性占用清理掉再看是否真的需要扩容这是成本最低的方案。2.1 日志是头号元凶journald必须设置上限先看日志占了多少journalctl --disk-usage du -sh /var/log/*麒麟系统默认用systemd-journald收集系统日志这个服务如果没设上限日积月累能把/var/log/journal撑到很大。当场回收空间可以这样journalctl --vacuum-size200M这条命令会立刻把journal日志裁剪到200M以内不需要重启服务对正在运行的应用没有影响。但只清理一次治标不治本。我建议顺手改一下journald的配置防止它再次爆掉vim /etc/systemd/journald.conf找到SystemMaxUse这一行改成SystemMaxUse500M保存后重启journald服务systemctl restart systemd-journald/var/log下还有各种应用日志先定位再处理du -sh /var/log/*.log /var/log/*/ | sort -rh | head -20对纯文本日志不能轻易删除文件本身有些进程会一直持有文件句柄删了可能不会立即释放空间反而要重启进程才生效更安全的做法是清空内容 /var/log/bigfile.log2.2 旧内核残留占满/boot升级还总失败麒麟系统每次升级内核后旧内核不会自动删除。桌面版默认给/boot分配的空间往往只有1G左右升级几次就满了然后yum update就会报磁盘空间不足。查看当前运行的内核版本和已安装的内核包uname -r rpm -qa | grep kernel保留当前运行的内核把其他版本卸载掉yum remove kernel-xxxxxx/boot空间释放后不仅启动恢复正常后续内核升级也不会再卡死。如果你不确定哪个能删就只保留uname -r显示的这个版本其他全删问题不大。2.3 软件包缓存和临时文件一次清干净软件包缓存也可能占掉好几个Gyum clean all再看根目录下哪些目录最大du -x -h --max-depth1 / 2/dev/null | sort -rh | head -20-x参数让du只在根文件系统内统计不进入其他挂载点这样能避免误判。/tmp、/var/tmp下的临时文件也可以清理但/var/tmp要小心——有些程序会把运行中的临时状态写在这里最好等没有关键任务运行时再清。清完这一轮用df -hT /再看一次。如果根分区使用率已经降到80%以下而且没有持续增长的迹象其实可以暂时不扩容。如果清理完仍然很紧张或者根目录本来的容量就偏小那就走下面的正经扩容路线。3. 有LVM的扩容路径动态扩大根逻辑卷如果麒麟V10服务器版在安装时用了默认的LVM自动分区扩容会顺滑很多。LVM把物理分区PV聚合到卷组VG再从卷组里分逻辑卷LV给文件系统用。扩容根目录的本质就是物理空间到位卷组里有空闲空间把逻辑卷扩大再把文件系统扩大。每一步都有明确的命令。3.1 先确认LVM结构pvs/vgs/lvs一把梭pvs vgs lvs这三条命令分别查看物理卷、卷组、逻辑卷的信息。重点看卷组的VFree列这是卷组里还没分配出去的空闲空间。如果VFree已经大于0那你不需要加磁盘直接跳到3.3节把剩余空间分给根逻辑卷就行。如果VFree是0那就先得有新的物理空间进到卷组里——要么物理磁盘加了容量要么磁盘上还有未分配的空闲区。3.2 把物理卷扩展到新增空间pvresize场景一你在虚拟化平台把虚拟磁盘从80G扩到了120G。虚拟机里的sda磁盘会多出40G未分配空间。如果根PV对应的分区恰好是sda2并且sda2后面就是空闲区直接扩展物理卷pvresize /dev/sda2执行后再看pvsPV的大小会从80G变成120G卷组的VFree也会增加40G。场景二磁盘上有一个尚未使用的空闲分区你需要先把它加入卷组pvcreate /dev/sda3 vgextend 卷组名 /dev/sda3这里有个关键点LVM要求PV必须是一整个分区或一整块磁盘它不能识别磁盘上的一块未分区空间。如果磁盘末尾还有空闲空间也得先通过fdisk或growpart把分区边界扩过去再执行pvresize。这一步看着简单实际操作中经常有人漏掉分区表环节结果pvresize报找不到空间。3.3 逻辑卷与文件系统同步扩大一步都不能少物理空间就位后扩容分两步先扩逻辑卷再扩文件系统。很多人lvextend执行完就以为结束了结果df -h一看毫无变化原因就是漏了第二步。把卷组所有剩余空间全部分给根逻辑卷lvextend -l 100%FREE /dev/klvg/root-l 100%FREE表示把卷组里所有空闲PE全部给这个逻辑卷。如果你只想分一部分比如只加50G可以写成lvextend -L 50G /dev/klvg/root逻辑卷扩大之后文件系统不会自动跟着变大必须手动执行resize命令。这一步最忌讳搞混文件系统类型# ext4文件系统参数写设备路径 resize2fs /dev/klvg/root # xfs文件系统参数写挂载点 xfs_growfs /执行完用df -hT /验证根目录可用空间应该已经变大了。3.4 LVM扩容的物理空间来源小结为了让这一章更直观我把LVM扩容常见的几种物理空间来源整理成了表格物理空间来源操作备注卷组已有空闲空间直接lvextend最简单什么都不用做虚拟磁盘扩容后有未分配区fdisk/growpart扩大PV分区再pvresize分区表操作参考第4章磁盘上有未用分区pvcreate vgextend不影响到原分区LVM的真正优势在于分区表基本不用动逻辑卷边界是软边界操作风险远低于物理分区方案。如果装系统时能自己选我强烈建议用LVM。4. 没有LVM的物理分区扩容改分区表是唯一出路没有LVM的麒麟系统比如桌面版或者手动分区的场景根目录通常直接落在一个物理分区上。这种方案下要扩容就只能通过修改分区表把根分区所属的边界向外扩展。这就是风险相对较高的操作但按部就班做并没有想象中那么可怕。4.1 判断根分区是不是最后一个分区先看lsblk的分区排列lsblk最简单的场景是sda1是/bootsda2是根目录而sda2后面就是空闲空间。这种情况可以直接把sda2扩展到磁盘末尾。如果根分区后面还跟着swap、/home或者其他数据分区就不能直接扩需要先处理后面的分区这部分我放到第5章讲。在可以扩展的前提下强烈建议用growpart代替手动fdisk。growpart会自动计算安全的起始扇区比手工删除重建分区更不容易出错。麒麟V10服务器版基于CentOS生态用yum安装yum install -y cloud-utils-growpart growpart /dev/sda 2这条命令的意思是把/dev/sda的第2个分区扩展到该磁盘的最大可用空间。执行完用lsblk确认分区大小已经变化。如果系统装不了growpart也可以用fdisk手动操作但需要格外小心。进入交互界面fdisk /dev/sda然后按顺序执行按d删除根分区例如分区2按n新建分区分区号仍然选2关键First sector必须保持和原分区完全一致不能改动Last sector直接回车使用默认值即磁盘末尾最后按w保存退出。这里很多人会害怕删除分区这个词。实际上只要First sector没变文件系统上保存的超级块、inode表位置都没动数据并不会丢。但风险在于操作过程中如果断电、误触或者把起始扇区写错分区表就会损坏。所以再次强调操作前先做分区表备份生产环境先做整机快照。growpart相比fdisk的另一个优势是它会自动判断分区表类型对MBR和GPT都能正确处理而且能避免在MBR扩展分区上因为逻辑分区嵌套复杂而出错。能用它就别手动算扇区。4.2 让内核读取新分区表再resize文件系统分区边界改完后内核还保留着旧的分区表信息需要让它重新读取partprobe /dev/sda如果partprobe没生效可以补一条partx -u /dev/sda然后根据文件系统类型执行对应的resize命令# ext4文件系统 resize2fs /dev/sda2 # xfs文件系统 xfs_growfs /这跟LVM那章的第二步是一样的。执行完df -hT /验证空间应该已经扩大。4.3 什么情况千万别直接改分区表不是所有物理分区都适合用删除重建这套流程。下面这几种情况直接改分区表会出大问题根分区本身是LVM的PV这种情况下系统显示根目录挂载在/dev/mapper/xxx-root上而不是sda2这种路径。直接把sda2当成普通分区resize会让LVM元数据错乱系统可能直接起不来。根分区后面有不可删除的数据分区比如/home、数据库数据目录后面分区里有业务数据不是说删就删的。MBR分区表下根分区是逻辑分区MBR的扩展分区逻辑比较绕删除重建逻辑分区容易牵扯到整个扩展分区链在线操作风险极高。没有任何备份和快照分区表操作属于高危操作裸奔上生产环境属于拿业务开玩笑。如果命中上面任意一条就不建议走这条路了直接看第5章的迂回方案。5. 虚拟机场景和空间在中间的迂回方案前面几章假设的都是根分区后面正好有空闲空间的理想情况。实际生产环境往往没这么友好要么根分区后面被swap挡住了要么中间隔着/home要么虚拟磁盘本身还没扩容。这一章专治各种不凑巧。5.1 虚拟机加盘后要先让系统识别新容量虚拟机里装了麒麟系统物理磁盘大小由虚拟化平台控制。要在KVM、VMware、OpenStack这些平台先把虚拟磁盘从80G扩到120G然后进虚拟机执行echo 1 /sys/class/scsi_disk/0:0:0:0/rescan或者用partprobe /dev/sda这样系统才能识别到磁盘容量变化。有时候SCSI设备的rescan不一定生效最稳妥的办法是找维护窗口重启一次虚拟机。重启是笨办法但确实有效。识别到新的磁盘容量后再回到第3章或第4章按对应的方案扩容。这条经验很多人不知道虚拟机里加完磁盘进系统发现fdisk -l还是原来的容量以为要重装系统其实只是没触发SCSI设备的重新扫描。5.2 根分区被swap挡住Swap分区换swapfile一个很常见的分区布局是sda1/boot、sda2/、sda3swap根分区后面跟着swap分区。这时候想要扩大根分区就得先把swap挪走。思路把swap分区去掉根分区扩展到磁盘末尾然后用一个swapfile文件替代swap分区。第一步关闭swap并删除swap分区swapoff /dev/sda3 fdisk /dev/sda在fdisk交互界面里删除sda3然后把sda2扩展方法和第4章一致。保存后用resize2fs或xfs_growfs扩大根文件系统。第二步创建swapfiledd if/dev/zero of/swapfile bs1M count8192 chmod 600 /swapfile mkswap /swapfile swapon /swapfile上面的命令创建一个8G的swapfile大小按需调整。第三步修改/etc/fstab删掉原来swap分区的那一行加上/swapfile none swap sw 0 0服务器上完全不配置swap会有内存耗尽被OOM killer误杀进程的风险所以用swapfile替代是更稳妥的做法。整个操作维护窗口内完成根分区扩容完成的同时swap功能也保住了。5.3 根分区后面夹着/home等数据分区如果根分区后面还跟着/home或者其他数据分区又没有LVM想扩大根分区就得走备份—删除—重建—恢复的流程把/home的数据全部备份到外部存储删掉/home分区扩大根分区然后用腾出来的空间重建/home分区恢复数据。这条路极其依赖备份完整性和维护窗口的长度。数据量一大备份和恢复的时间成本就非常可怕。所以绝大多数情况下我不推荐在数据分区紧挨着根分区的物理机上强行扩容——性价比太低出问题的概率太高。更合适的方案见下一节。5.4 挂新盘迁移大目录最稳妥的曲线扩容如果系统盘动不了或者扩容难度太大还有一个通用的好办法加一块新磁盘把根目录下占用最大的目录迁移过去挂载回去。路径级别的迁移不碰系统分区风险小很多。假设根目录下/var/lib/docker占了几十个G新磁盘是/dev/sdb1mkdir /data mount /dev/sdb1 /data rsync -avxP /var/lib/docker/ /data/docker/rsync同步完用bind mount把新位置绑定回原路径mount --bind /data/docker /var/lib/docker如果想让重启后仍然生效写入/etc/fstab/dev/sdb1 /data xfs defaults 0 0 /data/docker /var/lib/docker none bind 0 0整个过程最好在相关服务停止状态下进行避免迁移过程中有新数据写入导致目录不一致。服务端有双机或集群的话可以逐台操作。这个方法几乎适用于所有系统盘容量不足但磁盘有富余的场景不需要碰分区表是最安全的扩容方式之一。6. 我在麒麟系统扩容中踩过的坑最后一章分享几个实际踩过的坑。有些坑差点引发事故写出来帮大家绕开。6.1 把文件系统类型搞错了命令直接报错一次在一台银河麒麟V10上执行扩容根文件系统是xfs我习惯性地执行了resize2fs /dev/sda2结果终端直接提示Bad magic number in super-block。当时第一反应是分区表坏了头皮发麻后来冷静下来发现其实是文件系统类型搞错了换成xfs_growfs /立即成功。教训任何一个扩容操作前先看df -hT /输出里的Type列。这一步耗时两秒钟能避免后面摔一个大跟头。6.2 lvextend成功了df -h却没变化还有一次给客户的LVM逻辑卷扩容lvextend -L 20G执行成功后lvs看到的逻辑卷大小已经变了但df -h始终没有变化。客户在旁边催我当时也是一愣后来想起来文件系统还没resize。这就是LVM扩容三步走的典型疏漏先扩PV再扩LV最后resize文件系统。lvextend不负责resize文件系统这是教科书不会强调但实际必然踩的坑。执行完lvextend一定要追问一句文件系统是什么类型对应的resize命令执行了没有。6.3 虚拟机加盘后新空间怎么都看不到在VMware里把虚拟机磁盘从100G扩到200G进系统执行fdisk -l还是显示100G。折腾了半天最后发现只是SCSI设备没有重新扫描。执行echo 1 /sys/class/scsi_disk/0:0:0:0/rescan后新空间马上出现了。这里的设备号和路径可能因环境不同而有差异可以用ls /sys/class/scsi_disk/查看实际有哪些设备。如果rescan没用直接安排重启启动后系统会重新枚举所有SCSI设备容量自然就更新了。6.4 分区表误操作靠备份救了回来一次测试环境里用fdisk手动扩展分区删除分区后新建结果我设置的起始扇区比原来小了2048个扇区保存退出后系统直接无法挂载根分区。那个时候真的慌了片刻后来用之前备份的分区表恢复机器才重新启动起来。从那次之后我给自己立了一条规矩任何涉及分区表修改的操作第一件事永远是sfdisk -d /dev/sda partition_table_backup.txt。文件虽小关键时刻就是一个救生圈。6.5 不同麒麟版本底层可能完全不同银河麒麟V10的服务器版和桌面版分区方案可能存在差异。同一个V10版本有人装的是LVM有人装的是普通分区甚至文件系统类型都有ext4和xfs两种可能。这意味着你在网上抄到的命令很可能只适用于某一种特定安装方式。所以务必基于当前机器执行lsblk和df -hT /的实际输出做判断不要凭经验想当然。我这篇文章里的每一条路线都对应一种实际存在的麒麟部署情况先定位清楚自己属于哪一类再动手。最后说点掏心窝的体会。我在麒麟系统上做扩容最大的感悟是判断比操作重要先判断文件系统类型、判断有没有LVM、判断根分区在不在磁盘末尾再决定走哪条路。另外装新系统的时候多用点心——根目录空间给足/var单独分区能用LVM就用LVM这些都能让后续扩容少很多麻烦。扩容的终点不是df -h的数字变大了而是日常的日志轮转、空间监控、告警阈值都跟上否则下次还会在同一个坑里再摔一次。