收缩EXT4文件系统¶
警告
磁盘分区收缩是高风险操作,非必要不要执行
虽然我的实践是成功的,但是对于 Raspbery Pi OS(Raspbian) 我还是采用 disable_auto_resize ,然后采用手工 在线扩展 EXT4 根文件系统 实现指定容量扩展。这样扩展分区指定大小后无需计算文件系统扩展的大小,并且EXT4文件系统扩展比收缩难度和风险要低,更安全一些。
我在 树莓派(Raspberry Pi)快速起步 实践中发现,当 Raspbery Pi OS(Raspbian) 首次启动时,会自动将原本 dd
创建的启动盘的小分区自动扩展到占用整个磁盘。这在使用SD/TF卡的时候没有什么影响,因为原本SD/TF卡空间就很小,扩展占用整个SD/TF卡正好也满足需求。
但是,我在构建 树莓派4 USB存储启动Ubuntu Server 20.04 方案时,是希望将磁盘的大部分空间用于独立的存储服务,例如构建 ZFS 或者分布式存储 Ceph Atlas ,此时我需要收缩默认占用整个磁盘空间的EXT4文件系统。
备注
EXT4文件系统只支持 在线扩展 EXT4 根文件系统 ,但是不能在线收缩。所以本文采用的是离线方式,也就是 umount
状态下收缩EXT4文件系统。
原理¶
在离线状态(umount)时,使用
resize2fs
命令可以收缩EXT4文件系统收缩完EXT4文件系统后,再使用
fdisk
将分区改小(分区结束位置前移)
实践操作¶
树莓派(Raspberry Pi)快速起步 之后,磁盘分区如下(根分区
/dev/sda2
已经扩展到整个磁盘):
Disk /dev/sda: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: ssport
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x527a830f
Device Boot Start End Sectors Size Id Type
/dev/sda1 8192 1056767 1048576 512M c W95 FAT32 (LBA)
/dev/sda2 1056768 1953525167 1952468400 931G 83 Linux
执行
fsck
:
# 执行 resize2fs 会提示 e2fsck 需要使用 -f 参数
e2fsck -f /dev/sda2
e2fsck 1.47.0 (5-Feb-2023)
Pass 1: Checking inodes, blocks, and sizes
Inode 1403 extent tree (at level 2) could be narrower. Optimize<y>? yes
Inode 58312 extent tree (at level 2) could be narrower. Optimize<y>? yes
Inode 58316 extent tree (at level 1) could be narrower. Optimize<y>? yes
Inode 58383 extent tree (at level 1) could be narrower. Optimize<y>? yes
Inode 58385 extent tree (at level 1) could be narrower. Optimize<y>? yes
Inode 58387 extent tree (at level 2) could be narrower. Optimize<y>? yes
Inode 58389 extent tree (at level 2) could be narrower. Optimize<y>? yes
Inode 58392 extent tree (at level 2) could be narrower. Optimize<y>? yes
Inode 58927 extent tree (at level 1) could be narrower. Optimize<y>? yes
Pass 1E: Optimizing extent trees
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
rootfs: ***** FILE SYSTEM WAS MODIFIED *****
rootfs: 60775/59592000 files (0.2% non-contiguous), 4195072/244058550 blocks
收缩分区到128G空间:
resize2fs /dev/sda2 128G
resize2fs 1.47.0 (5-Feb-2023)
Resizing the filesystem on /dev/sda2 to 33554432 (4k) blocks.
The filesystem on /dev/sda2 is now 33554432 (4k) blocks long.
按照上述文件系统收缩以后,就可以使用fdisk调整分区大小来匹配已经收缩的文件系统:
# fdisk /dev/sda
Welcome to fdisk (util-linux 2.39.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p
Disk /dev/sda: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: ssport
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x527a830f
Device Boot Start End Sectors Size Id Type
/dev/sda1 8192 1056767 1048576 512M c W95 FAT32 (LBA)
/dev/sda2 1056768 1953525167 1952468400 931G 83 Linux
Command (m for help):
执行以下操作交互命令(高亮),注意实际输入只有交互中的单个操作命令字符,例如 n
表示添加分区, p
表示打印分区:
Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.
Command (m for help): p
Disk /dev/sda: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: ssport
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x527a830f
Device Boot Start End Sectors Size Id Type
/dev/sda1 8192 1056767 1048576 512M c W95 FAT32 (LBA)
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (2048-1953525167, default 2048): 1056768
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1056768-1953525167, default 1953525167): +268435456
Created a new partition 2 of type 'Linux' and of size 128 GiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: y
The signature will be removed by a write command.
Command (m for help): p
Disk /dev/sda: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: ssport
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x527a830f
Device Boot Start End Sectors Size Id Type
/dev/sda1 8192 1056767 1048576 512M c W95 FAT32 (LBA)
/dev/sda2 1056768 269492224 268435457 128G 83 Linux
Filesystem/RAID signature on partition 2 will be wiped.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
备注
这里输入分区的起始扇区是 1056768
,这个值和调整扇区之前的 /dev/sda2
分区起始位置一致(这样可以避免错位)
输入分区的终止扇区值是 +268435456
,这个值实际上是之前 resize2fs
结果值 33554432
乘以 8
: 因为 resize2fs
输出结果的值是以 4k
为单位,而 fdisk
操作命令的扇区 sector
是 512字节
。
如果一切没有出错的话,将调整(shrink)分区挂载进行检查
mount /dev/sda2 /mnt
此时我遇到一个报错:
这里的错误显示是文件系统supperblock错误,或者是其他错误,待补充
怎么办?
执行一次
e2fsck
对/dev/sda2
进行修复:
# 执行 resize2fs 会提示 e2fsck 需要使用 -f 参数
e2fsck -f /dev/sda2
此时会提示大量的 块位图不一致
( Block bitmap differences
),则按照提示进行 fix
修复
e2fsck 1.47.0 (5-Feb-2023)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Block bitmap differences: -3731424 -3731426 -(3731428--3731429) -3731431 -3731435 -(3731437--3731442)...
...
Fix<y>? yes
...
Padding at end of inode bitmap is not set. Fix<y>? yes
rootfs: ***** FILE SYSTEM WAS MODIFIED *****
rootfs: 60775/8192000 files (0.2% non-contiguous), 969186/33554432 blocks
修复完成后,再次执行磁盘挂载就能够成功。