先说结论:云主机数据盘扩容,控制台点完那一下,系统里其实一点没变。真正把它补上的,是另一段活。

数据盘快满 → 云控制台点扩容 → 进系统 df -h 一看,还是老大小。这一脸懵,就是下面这个脚本存在的原因。

脚本叫 QingYun.sh,一百来行 bash,五年前写的,到现在还有几台机器在跑。回头看那二十行的核心循环,居然没过时。

它干的事分三层:先把分区表扩到新边界,再把文件系统 resize 到新边界,最后把服务拉回来。难的是中间那层——重建分区的时候,起点必须跟原来分毫不差。差一个扇区,前面所有数据当场读不出来。

整个脚本最关键的就一行:

Startflag=`parted $devpart print | sed -n '/primary/p' | awk '{print $2}'`

先把原来的分区起点读进变量,后面 parted rm 1 把分区登记删掉,再拿这同一个起点 mkpart 建回去。删掉的只是分区表里的登记信息,盘上的数据纹丝没动——像把图书馆的索引卡抽走,书还在架子上,重建时按原位置把卡插回去,书照样找得到。这一行,等于「数据不丢」的全部秘密。

动手之前还得先停下占用盘的东西。数据盘上跑着 mysql、nginx,文件被占着,umount 根本下不来,所以先停宝塔面板整套、wdcp,还有 swap(不少镜像把 swap 文件扔在数据盘上)。停了服务也常漏网,再 fuser -m <挂载点> -k 按挂载点全杀一遍。十个「umount: target is busy」里,九个是忘了这步。

真到重建分区,就这么两行:

parted $devpart rm 1
yes | parted $devpart mkpart primary $Startflag 100%

后面 resize2fs 把 ext4 撑到新边界,mount -a、服务拉起、swap 挂回,自愈收尾。第一次读这段的时候,我还在想那个 yes | 是干嘛的——其实就是 parted 会问一句「确定吗」,喂它一个 y。

诚实说,它也有没防住的。分区表并没有真正备份,旁边那个 parted.txt 只是记录不是备份;它只认「整盘一个分区」的布局,同盘多分区的机器跑它会出事故;也只处理分区号 1。所以我的用法一直是:标准云数据盘放心跑,奇形布局老老实实手动来。

脚本是开源的,署名留着随意改。要批量管一批云主机、顺手把这种运维脚本推下去,七亿批量远程管理工具那套能省点事;盘这档子事之前也栽过一回,fstab 里把盘名写错,开机后挂载直接掉了,回头想想跟这里守的是同一条:动手前先记住原样。

前阵子整理服务器清单,才发现这脚本我五年里改了不到五次,一行注释还停在写它那个下午。