最近更新时间:2026-10-28 14:46:49
由于部分Linux操作系统版本较旧,云盘无法在操作系统内使用growpart等工具在线(云盘是mount状态)扩容,这种情况需要采用离线(云盘是umount状态)扩容的方式才能使云盘扩容生效。本文主要介绍如何离线扩容Linux数据盘。
数据盘已初始化并在控制台上扩容了云盘容量。参考初始化数据盘(Linux)
已创建快照备份数据。为防止操作失误导致数据丢失,建议您在操作前使用快照备份数据。
业务可以停止对该数据盘的读写。离线扩容期间数据盘处于卸载状态。
扩容操作前,建议为目标云盘创建快照备份,用于应对扩容、分区扩展过程中误操作、文件系统异常等风险,支持通过快照回滚至扩容前时间点,保障数据安全。
以下情况建议使用本文的离线方式,不要使用 growpart 在线扩容:
场景 | 原因 |
CentOS 6 等内核版本低于 3.6 的系统 | 分区处于挂载状态时,内核无法更新分区信息,修改分区表后 |
GPT 分区的起始扇区不是 8 的倍数(例如 34) | 在 CentOS 6/7 上,growpart 会改变分区的起始扇区,导致文件系统无法识别(挂载报 UUID 不存在,resize2fs 报 |
MBR 分区 | 本文使用 fdisk 按原起始扇区重建分区,适用于所有内核版本 |
如果您的系统内核为 3.6 及以上,并且分区起始扇区是 8 的倍数(例如 2048),可以使用在线扩容云盘(Linux)。
只能扩容数据盘上的最后一个分区。 本文以 /dev/vdb 的分区 1 为例,请替换为实际的设备名和分区编号。
ext4 文件系统扩容后超过 16 TiB 时,需要文件系统带有 64bit 特性,执行 dumpe2fs -h /dev/vdb1 | grep features 查看是否包含 64bit。CentOS 6 创建的 ext4 不带 64bit 特性,无论在哪个系统上都无法扩容到 16 TiB 以上(resize2fs 报 New size too large to be expressed in 32 bits);超出部分可以通过选项五新建分区使用。CentOS 7 及以上创建的 ext4 默认带 64bit 特性。xfs 没有此限制。
MBR 分区表最大支持 2 TiB。 扩容后磁盘超过 2 TiB 时,2 TiB 以外的空间无法分配给 MBR 分区,请先参考《转换数据盘MBR分区为GPT分区》。
重建分区时,起始扇区必须与原分区完全一致,请以扇区为单位记录和填写,不要使用 kB、MB 等单位的显示值。
修改分区表后,如果原文件系统无法识别,不要执行 fsck -y、e2fsck -b、xfs_repair、mkfs,这些命令会按错误的位置改写数据。请用备份恢复分区表,或通过快照回滚。
本文命令需要 root 权限,示例以 root 用户执行。
查看分区表类型和分区起始扇区。
parted -s /dev/vdb unit s print示例输出(GPT 分区,起始扇区 34):
Disk /dev/vdb: 2147483648s
Partition Table: gpt
Number Start End Size File system Name Flags
1 34s 2097151966s 2097151933s ext4 primary记录以下信息,后续步骤需要使用:
项目 | 示例 | 说明 |
Partition Table |
|
|
最后一个分区的编号 |
| |
该分区的 Start |
| 起始扇区,重建分区时必须使用这个值 |
查看文件系统类型、UUID 和挂载目录。
lsblk -f /dev/vdb
blkid /dev/vdb1记录文件系统类型(ext4 / ext3 / xfs)、UUID 和挂载目录(示例为 /data)。
步骤一的结果 | 新增容量的用途 | 扩容方式 |
未分区,文件系统直接建在 | 扩大已有文件系统 | 选项三:扩容裸设备文件系统 |
MBR 分区表(msdos) | 扩大已有分区 | 选项一:扩展 MBR 分区 |
MBR 分区表(msdos) | 新建一个分区 | 选项四:新增并格式化 MBR 分区 |
GPT 分区表 | 扩大已有分区 | 选项二:扩展 GPT 分区 |
GPT 分区表 | 新建一个分区 | 选项五:新增并格式化 GPT 分区 |
选项四、选项五不修改已有分区,不需要执行步骤三(卸载)以及"通知内核更新分区""扩容文件系统并挂载",直接跳转到对应选项操作即可。
umount /data
mount | grep /dev/vdb # 无输出表示已卸载如果提示 device is busy,可用 fuser -mv /data 查看占用的进程,停止相关业务后再卸载。
卸载后检查文件系统状态,确认没有错误再继续:
e2fsck -fn /dev/vdb1 # ext3/ext4,只读检查,不修改磁盘
xfs_repair -n /dev/vdb1 # xfs,只读检查,不修改磁盘备份分区表。
sfdisk -d /dev/vdb > /root/vdb-mbr-$(date +%F).txt使用 fdisk 删除原分区,并按原起始扇区重建。
fdisk -u /dev/vdb # CentOS 6;CentOS 7 及以上且原起始扇区 ≥ 2048
fdisk -c=dos -u=sectors /dev/vdb # CentOS 7 及以上,且原起始扇区小于 2048(例如 63)CentOS 7 及以上版本的 fdisk 默认只允许起始扇区 ≥ 2048。原起始扇区为 63 时,如果使用 fdisk -u,输入 63 会提示 Value out of range。此时不要直接回车使用默认值 2048,否则文件系统将无法识别;请输入 q 不保存退出,改用 fdisk -c=dos -u=sectors /dev/vdb 重新操作。
依次输入:
输入 | 说明 |
| 查看分区,确认分区 1 的 Start(例如 2048 或 63) |
| 删除分区。只有一个分区时自动选中分区 1;有多个分区时输入最后一个分区的编号 |
| 新建分区 |
| 主分区 |
| 分区编号,与原分区一致 |
| 起始扇区,必须与原分区的 Start 一致 |
回车 | 结束扇区使用默认值(磁盘末尾) |
| 查看新分区,确认 Start 与原值一致 |
| 写入分区表并退出 |
说明:
提示 DOS-compatible mode is deprecated,不影响操作。
部分新版本 fdisk 在新建分区时会提示 Partition #1 contains a ext4 signature. Do you want to remove the signature?,请输入 N,否则会清除文件系统签名。
原分区类型不是 83(Linux)时,例如 8e(Linux LVM),需在 w 之前输入 t,把类型改回原值;原分区有启动标志时,输入 a 恢复。
继续执行"通知内核更新分区"。
推荐使用方法一(sgdisk),可以保留分区原有的起始扇区、类型、唯一 GUID 和名称。实例上没有 sgdisk 时,可以使用方法二(parted)。
方法一:sgdisk(推荐)
安装 gdisk。
type sgdisk || yum install -y gdisk备份分区表,并读取原分区的信息。
sgdisk --backup=/root/vdb-gpt-$(date +%F).bak /dev/vdb
sgdisk -i 1 /dev/vdb
START=$(sgdisk -i 1 /dev/vdb | awk '/First sector/{print $3}')
TYPE=$(sgdisk -i 1 /dev/vdb | awk '/GUID code/{print $4}')
GUID=$(sgdisk -i 1 /dev/vdb | awk '/unique GUID/{print $4}')
NAME=$(sgdisk -i 1 /dev/vdb | awk -F"'" '/Partition name/{print $2}')
echo "START=$START TYPE=$TYPE GUID=$GUID NAME=$NAME"确认 START 与步骤一记录的起始扇区一致,TYPE、GUID 均不为空。
按原起始扇区重建分区,结束位置为磁盘末尾。
[ -n "$START" ] && [ -n "$TYPE" ] && [ -n "$GUID" ] \
&& sgdisk -e -a 1 -d 1 -n 1:$START:0 -t 1:$TYPE -u 1:$GUID -c 1:"${NAME:-primary}" /dev/vdb \
|| echo "读取分区信息失败,未修改分区表"参数 | 说明 |
| 把备份 GPT 移到扩容后的磁盘末尾 |
| 关闭对齐。不能省略,否则 sgdisk 可能把起始扇区调整为 8 的倍数(例如 34 变为 40) |
| 删除分区 1,并从原起始扇区重建到磁盘末尾 |
| 恢复原分区的类型、唯一 GUID 和名称 |
参数顺序不能改变,-e、-a 1 必须位于 -n 之前。
继续执行"通知内核更新分区"。
方法二:parted
进入 parted,切换为扇区单位并查看分区。
parted /dev/vdb(parted) unit s
(parted) print出现以下提示时,均输入 Fix:
The backup GPT table is not at the end of the disk ... Fix/Ignore/Cancel?
Not all of the space available to /dev/vdb appears to be used ... Fix/Ignore?
记录分区 1 的 Start,例如 34s。
删除原分区,并按原起始扇区重建。
(parted) rm 1
(parted) mkpart primary 34s 100%起始位置必须填写上一步记录的扇区值(带 s)。parted 默认按 kB、MB 显示,精度不足,例如起始扇区 2049 显示为 1049kB,按显示值重建后会变为 2048,导致文件系统无法识别。
出现 Warning: The resulting partition is not properly aligned for best performance. Ignore/Cancel? 时,输入 Ignore。
不要输入 Cancel。 rm 已经生效,取消后分区将不存在。如果误输入了 Cancel,请立即重新执行 mkpart primary 34s 100%。
确认结果后退出。
(parted) print
(parted) quit确认分区 1 的 Start 与原值完全一致。
说明:使用 parted 重建后,分区的类型、名称和唯一 GUID(PARTUUID)会改变。如果 /etc/fstab 使用 PARTUUID= 挂载该分区,请改为文件系统的 UUID=。
继续执行"通知内核更新分区"。
让内核重新读取分区表。
partx -d /dev/vdb; partx -a /dev/vdbCentOS 6 可能输出 error deleting partitions 2-256: BLKPG: No such device or address,可以忽略。
确认内核中的分区已更新。
lsblk /dev/vdb
cat /sys/block/vdb/vdb1/start # 必须与原起始扇区一致分区容量等于磁盘容量,表示内核已更新。如果容量未变化,执行 partprobe /dev/vdb 后再次确认;仍未变化时,请确认该盘所有分区均已卸载,或重启实例。
校验原文件系统可以识别。
blkid /dev/vdb1返回结果中的 TYPE 和 UUID 必须与步骤一记录的一致。
起始扇区或 UUID 不一致时,请立即停止操作,不要扩容或检查文件系统,用备份恢复分区表后联系技术支持:
sgdisk --load-backup=/root/vdb-gpt-<日期>.bak /dev/vdb # GPT
sfdisk /dev/vdb < /root/vdb-mbr-<日期>.txt # MBR,提示 cylinder boundary、bootable 等 Warning 可以忽略说明:CentOS 7 及以上(内核 ≥ 3.6)也可以不卸载数据盘:修改分区表后执行 partx -u /dev/vdb 在线更新分区容量,再在线执行 resize2fs 或 xfs_growfs。CentOS 6 不支持,必须卸载。
ext3 / ext4
e2fsck -f /dev/vdb1 # resize2fs 离线扩容前必须执行
resize2fs /dev/vdb1
mount /dev/vdb1 /dataxfs
xfs 文件系统需要在挂载状态下扩容。
mount /dev/vdb1 /data
xfs_growfs /data数据盘未分区、文件系统直接建在 /dev/vdb 上时,不需要修改分区表。
ext3 / ext4:
umount /data
e2fsck -f /dev/vdb
resize2fs /dev/vdb
mount /dev/vdb /data说明:ext4 也支持在挂载状态下直接执行 resize2fs /dev/vdb 在线扩容。
xfs:
xfs_growfs /data适用于 MBR 分区表,新增的容量用于创建新分区,已有分区保持不变。
注意事项:
MBR 分区表最多 4 个主分区;新分区只能使用磁盘前 2 TiB 范围内的空间。
新建分区不影响已有分区的数据。CentOS 7 及以上,已有分区可以保持挂载;CentOS 6 需要在步骤 3 卸载该盘的所有分区(或重启实例),内核才能识别新分区。
新建分区。
fdisk -cu /dev/vdb # CentOS 6
fdisk -u /dev/vdb # CentOS 7 及以上依次输入:
输入 | 说明 |
| 新建分区 |
| 主分区 |
| 分区编号(示例中已有分区 1) |
回车 | 起始扇区使用默认值(紧接已有分区之后,并按 1 MiB 对齐) |
回车 | 结束扇区使用默认值(磁盘末尾) |
| 查看分区,确认新分区不与已有分区重叠 |
| 写入分区表并退出 |
已有分区处于挂载状态时,写入后会提示 Re-reading the partition table failed with error 16: Device or resource busy,分区表已写入磁盘,继续下一步即可。
让内核识别新分区。
partx -a /dev/vdb
lsblk /dev/vdb可能输出 error adding partition 1(分区 1 已存在),可以忽略。lsblk 中出现 vdb2 表示内核已识别。
未出现 vdb2 时(CentOS 6 已有分区挂载中),卸载该盘的所有分区后重新识别,再把已有分区挂载回去。
umount /data
partx -a /dev/vdb # 可能仍输出 Device or resource busy,以 lsblk 结果为准
lsblk /dev/vdb
mount /dev/vdb1 /data仍未出现 vdb2 时,执行 partprobe /dev/vdb 或重启实例。
创建文件系统并挂载,参见下方"格式化并挂载新分区"。
适用于 GPT 分区表,新增的容量用于创建新分区,已有分区保持不变。CentOS 6 同样需要卸载该盘的所有分区后,内核才能识别新分区(见选项四步骤 3)。
方法一:sgdisk(推荐)
type sgdisk || yum install -y gdisk
sgdisk --backup=/root/vdb-gpt-$(date +%F).bak /dev/vdb
sgdisk -e /dev/vdb # 把备份 GPT 移到扩容后的磁盘末尾
sgdisk -a 2048 -n 2:0:0 -t 2:8300 /dev/vdb # 新建分区 2:起点默认(1 MiB 对齐),终点为磁盘末尾,类型 Linux filesystem
sgdisk -p /dev/vdb # 确认新分区不与已有分区重叠-a 2048:按 1 MiB 对齐新分区的起点。不加时,sgdisk 可能只按 2 或 8 扇区对齐。
已有分区挂载中时提示 The kernel is still using the old partition table,属于正常现象。
然后按选项四的步骤 2、3 让内核识别新分区。
方法二:parted
进入 parted,修复备份 GPT 位置。
parted -a optimal /dev/vdb(parted) print出现 Fix/Ignore 提示时,均输入 Fix。
查看空闲空间,并在空闲空间上新建分区。
(parted) unit MB
(parted) print free示例输出:
Number Start End Size File system Name Flags
1 0.02MB 408022MB 408022MB ext4 primary
408022MB 451036MB 43014MB Free Space以最后一段 Free Space 的 Start 作为新分区的起点:
(parted) mkpart primary 408022MB 100%
(parted) print
(parted) quit使用 -a optimal 启动 parted 时,新分区的起点会自动按 1 MiB 对齐。
按选项四的步骤 2、3 让内核识别新分区。
创建文件系统(任选其一)。
mkfs.ext4 /dev/vdb2
mkfs.xfs -f /dev/vdb2请确认设备名是新分区(示例为 /dev/vdb2),格式化会清除该分区上的全部数据。
挂载新分区。
mkdir -p /data2
mount /dev/vdb2 /data2
df -Th /data2设置开机自动挂载。
blkid /dev/vdb2 # 记录 UUID
echo "UUID=<上一步的UUID> /data2 ext4 defaults,nofail 0 2" >> /etc/fstab # xfs 将 ext4 改为 xfs,末尾两项改为 0 0
mount -a # 无报错表示配置正确建议使用 UUID 挂载,不要使用 /dev/vdb2,设备名在重启后可能变化。
df -Th /data
mount -a # 确认 /etc/fstab 配置正确,无报错文件系统容量与云盘容量基本一致,表示扩容完成。文件系统会占用部分空间存放元数据,因此显示的容量略小于云盘容量。
ext4 扩容到 16 TiB 以上时,resize2fs 报 New size too large to be expressed in 32 bits?
文件系统不带 64bit 特性(CentOS 6 创建的 ext4 均不带),最大只能到 16 TiB。可以把 16 TiB 以外的空间通过选项五新建分区使用,或者把数据迁移到 xfs 或带 64bit 特性的 ext4 文件系统。
resize2fs 报 Bad magic number in super-block,或挂载报 special device UUID=... does not exist?
通常是分区的起始扇区被改变了,文件系统数据仍在原位置,没有损坏。执行 parted -s /dev/vdb unit s print 查看起始扇区,与原值不一致时,按选项二方法一,把 START 设为原起始扇区重建分区即可恢复。恢复前不要执行 fsck、xfs_repair 或格式化。
resize2fs 提示 The filesystem is already xxx blocks long. Nothing to do!?
内核中的分区容量没有更新。请按"通知内核更新分区"重新操作,确认 lsblk 显示的分区容量已等于磁盘容量。
partprobe 提示 Device or resource busy?
该盘上仍有分区处于挂载或使用状态。CentOS 6 不能在分区使用中更新分区信息,请卸载该盘所有分区后重试,或重启实例。
使用 growpart 扩容时提示 failed to repartition,随后提示已回滚(attempting to revert)?
通常是 GPT 分区起始扇区不是 8 的倍数。growpart 已自动回滚,数据没有受影响。请不要卸载后再次执行 growpart(卸载后执行会改变起始扇区,导致文件系统无法识别),请按本文选项二方法一扩容。
新建数据盘时如何分区,以后扩容更方便?
推荐不分区,直接在整块数据盘上创建文件系统,以后扩容只需执行 resize2fs 或 xfs_growfs。
需要分区时,让分区从 2048 扇区开始:parted -s /dev/vdb mklabel gpt mkpart primary 0% 100%。不要写成 mkpart primary 0 100%,此时起始扇区为 34。
2 TiB 以上的数据盘使用 GPT 分区表。
纯净模式