凌晨两点半,告警群里弹出一条消息:磁盘使用率 100%。
我当时的状态是:人已经睡着了,手机在床头震个不停。爬起来连上服务器敲 df -h,根分区那行红得刺眼——/dev/vda1 40G 40G 0 100% /。紧接着 MySQL 开始报错,日志写不进去,业务页面开始 500。
摆在面前两条路:一是停机,把机器关了慢慢扩;二是硬着头皮在线扩。业务是给客户跑的,半夜停机也不是不行,但第二天早上大概率要被问一句「为什么半夜断了二十分钟」。于是我选了第二条。
结果是:扩容本身只花了八分钟,剩下三个小时都在给各种细节擦屁股。
这篇就把这三个小时的坑,一条一条摆出来。
先把三个概念分清楚:云盘、分区、文件系统
这是我踩的第一个坑,也是最根本的那个。
很多人(包括当时的我)以为:控制台点了「扩容」,硬盘就变大了,df -h 应该立刻跟着变。
错。
云盘是「盘子」,分区是「盘子上划出来的一块地」,文件系统是「这块地上盖的房子」。控制台扩容只做了第一件事——把盘子换成大号的了。地和房子都还是原来那么大。所以你在服务器里敲 df -h,看到的依然是 40G,然后开始怀疑人生。
正确顺序是这样:
| 层次 | 在哪操作 | 具体动作 |
|---|---|---|
| ① 云盘容量 | 控制台 / API | 控制台点扩容(这一步完全不碰操作系统) |
| ② 分区表 | 服务器内部 | growpart /dev/vda 1 |
| ③ 文件系统 | 服务器内部 | resize2fs(ext 系)/ xfs_growfs(XFS) |
| ④ 验证 | 服务器内部 | lsblk、df -Th |
少做任何一步,容量都不会出现在 df 里。这个认知,比我后面所有敲过的命令都值钱。
顺便说一句,块存储这块的容量空间比我想象中宽得多:单盘支持 1GiB 到 64TiB、容量和性能都能弹性扩展,ESSD 系列云盘最高可提供 300 万随机 IOPS、12GB/s 吞吐,延迟可以压到 30 微秒级别,数据持久性标称做到 12 个 9。规格档位和实际价格建议直接翻 阿里云块存储 EBS 的产品页,以官方页面实时展示为准——我这里的数字只是为了说明「能扩的空间很大,别急着重买机器」。
我实际的七步操作(Linux)
先把完整流程摊开,再说坑。
第一步:先打快照。
这是唯一一步能救命的操作。扩容在云盘层面是不可逆的,出了问题唯一的退路就是回滚快照。我当时为了省那几分钟纠结了一下「要不要先打」,最后打了——谢天谢地,后面用上了。快照不需要装任何 Agent,整盘备份,兼容所有操作系统。
第二步:控制台扩容。
选中云盘,扩容到目标容量。这一步点下去就不回头的。
第三步:盘内确认盘子真的变大了。
sudo lsblk
看 vda 这一行的 SIZE。如果还是 40G,说明扩容没生效或者分区表没刷新(见坑三)。
第四步:扩容分区。
sudo growpart /dev/vda 1
注意 /dev/vda 和 1 之间必须有空格,不是 /dev/vda1。这个细节我一开始写错了,报错信息还相当不友好。
第五步:查文件系统类型。
sudo lsblk -f
记下目标设备名、FSTYPE 和挂载点。不同文件系统扩容命令完全不一样,这一步千万别跳。
第六步:扩容文件系统。
ext2 / ext3 / ext4:
sudo resize2fs /dev/vda1XFS:
sudo xfs_growfs /注意 XFS 后面的参数是挂载点,不是设备名。
Btrfs:
sudo btrfs filesystem resize max /mountpoint
第七步:验证。
df -Th
看 Size 那一列是不是和云盘容量基本对得上。文件系统创建时会占用一部分容量存元数据,所以可能会比控制台显示的容量小一点点,这是正常的,不是扩容失败。
六个坑,一个比一个费时间
坑一:只扩了盘,忘了扩分区
现象:控制台显示 100G,df -h 还是 40G。
我第一反应是「扩容没生效」,差点又去控制台点一次。实际上盘子已经是 100G 了,但分区表里那块地还是 40G。lsblk 一看就明白了——vda 是 100G,vda1 还是 40G。
growpart 补上,问题解决。
坑二:XFS 拿 resize2fs 硬怼
现象:resize2fs: Bad magic number in super-block while trying to open /dev/vda1
我手上这台机器的根分区是 XFS,但我习惯性地敲了 resize2fs。这俩是完全不同的文件系统家族,命令不能混用。XFS 只能用 xfs_growfs,而且参数是挂载点。
判断方法很简单:lsblk -f 看 FSTYPE,或者 df -Th 看 Type 那一列。动命令之前先看一眼文件系统类型,能省半小时。
坑三:分区表刷新了,但内核没跟上
现象:growpart 提示成功,lsblk 也显示分区变大了,但 df -Th 纹丝不动。
这是我停下来查文档查最久的一次。原因是老版本系统不能在线更新分区表,内核里的分区表还是旧的。解决办法:
sudo partprobe /dev/vda
或者
sudo partx -u /dev/vda1
实在不行就重启实例——但这就是我最开始想避免的事,所以能 partprobe 解决就别重启。
坑四:MBR 分区表的 2TiB 天花板
现象:扩容到超过 2TiB 之后,多出来的容量怎么也吃不到。
MBR 分区表的分区上限就是 2TiB,这是分区表格式本身的限制,跟你买多大的盘没关系。超过 2TiB 的要么改用 GPT 分区表,要么在剩余空间上再新建一个分区单独挂载。想原地把 MBR 转 GPT,得先备份再重建分区表,是个体力活——所以规划的时候就把这件事想清楚,比事后补救便宜得多。
顺便说个更冷门的:如果你的 ext 文件系统在创建时没有正确设置 bytes-per-inode,扩容到 64TiB 附近会撞上 inodes (4294967296) must be less than 4294967295 这种报错。这个参数云盘初始化之后改不了,唯一的出路是新建一块盘、创建文件系统时带上 -i 65536、再把数据拷过去。所以从一开始就按目标容量规划,比中途搬家划算。
坑五:以为能缩容
现象:账算下来觉得 100G 用不完,想缩回 40G 省点钱。
不支持。
云盘只能扩不能缩。想"缩容",唯一的办法是新建一块小盘、把数据迁过去、再释放原来的盘。等于重建一遍。所以扩容的时候别一把拉到特别大——按未来 6 到 12 个月的增长量估,留点余量就够,不够再扩。
顺便把计费说清楚:扩容会立即按新容量计费,计费方式和原云盘一致。包年包月的盘,扩容成功后按剩余时长补足新旧容量的差额费用;按量付费的盘就按新规格继续跑。所以「先扩一点看看」的成本,比你想的可控得多,别因为怕花钱而硬扛到半夜告警。
坑六:以为系统盘会自动扩
现象:数据盘扩得好好的,轮到系统盘就翻车。
系统盘和数据盘在扩容这件事上没有区别——一样要打快照、一样要在盘内走 growpart + resize2fs/xfs_growfs。系统盘的麻烦在于它没法卸载,所以如果文件系统本身不一致导致 resize2fs: Permission denied to resize filesystem 这种报错,你没法像数据盘那样 umount 下来修。正确姿势是:先 dmesg -T | grep fs 看有没有 There are errors in the filesystem 这类信息,然后按官方文档把系统盘卸载下来挂到另一台实例上修复。
所以系统盘动手前,快照是硬要求,不是可选项。
性能不是容量:扩容前顺手看一眼规格
这是我从那次事故里学到的第二件事。
云盘的 IOPS 和吞吐上限,跟容量是挂钩的。同一档 ESSD 规格,盘越大,能拿到的 IOPS 越高;反过来,盘小但业务吃 IOPS,你光扩容量能缓解"写不进去",但解决不了"读写慢"。
所以扩容前值得顺手确认两件事:
- 当前规格是不是该换档。ESSD 一般有 PL0 / PL1 / PL2 / PL3 等档位(还有更高的 PL-X),PL 数字越大性能越强,价格也越高。如果业务是数据库这类吃随机 IO 的,从 PL1 升到 PL2 比单纯加容量见效更直接。
- 要不要上 ESSD AutoPL。它的特点是把性能与容量解耦——支持性能预配置和性能突发,业务压力不可预期的时候不用提前把容量堆满,也能瞬时顶到百万级 IOPS。对这种"平时闲、偶尔飙"的负载很友好。
另外一个容易被忘掉的能力是在线变配:部分场景下云盘规格可以在线调整,不用重建盘、不用迁数据。扩容之前先把这两个开关看一眼,比事后发现方向错了要省事。
花十分钟能省三小时的检查清单
那一夜之后我给自己留了一份清单,后来每次扩容都照着走:
| 阶段 | 动作 | 为什么 |
|---|---|---|
| 动手前 | df -h、lsblk、lsblk -f 三个命令存好现场 |
出问题时有对照 |
| 动手前 | 打快照 | 扩容不可逆,这是唯一的退路 |
| 动手前 | 确认分区表是 MBR 还是 GPT、目标容量有没有超 2TiB | 超了就地重建很痛 |
| 动手前 | 算一下新容量按剩余时长补的差额 | 别在半夜做花钱的判断 |
| 扩容中 | 控制台扩容 → growpart → resize2fs/xfs_growfs |
三层要一起走 |
| 扩容中 | 命令用错文件系统会直接报错,别硬试 | 先 lsblk -f 看一眼 |
| 扩容后 | df -Th 对比、业务读写、应用日志三条都过一遍 |
容量对了不等于数据没事 |
| 扩容后 | 快照留几天再删 | 发现问题还能退回去 |
最后
那晚真正让我睡不着的不是扩容,是"我以为我知道怎么扩容"。
控制台那个按钮太友好了,友好到你很容易以为点完就完事——但底下还压着分区表、文件系统、分区表格式、规格档位这一串东西。它们平时不出声,出问题的时候全在凌晨两点半冒出来。
所以我的建议很朴素:平时就把快照开好、把容量告警设在 80% 而不是 95%、扩容按 6 到 12 个月的增长量估。真到了要扩的那天,八分钟是真能搞定的事,不至于像我一样给三个小时擦屁股。