缩小或扩大linux ext4文件系统(包含在线扩大根文件系统步骤)
概念
一般而言,我们喜欢把分区和文件系统混为一谈,实际上,它们是有区别的。它们的关系是:文件系统是建立在分区上的,分区大小要大于等于文件系统大小(就像容器和沙子,容器体积要大于等于沙子体积)。
缩小分区的操作步骤是:先缩小文件系统,然后再缩小分区。
扩大分区的操作步骤是:先扩大分区,然后再扩大文件系统。
起因
我的树莓派U盘有128G大小,里面安装了Raspi OS,已经有两个分区,第二个分区是根分区。现在我把第二分区缩小成30GB,然后将多余的容量用于创建一个exfat的分区,用于windows。
后文包含的内容:
- 离线缩小根分区上的文件系统
需要把待缩容的磁盘插到一个已启动的linux系统
- 在线扩大根分区上的文件系统
此时待扩容的磁盘上的linux系统已启动,根分区已挂载至/
后文未包含的内容:
- 在线缩小根分区上的文件系统
操作很麻烦,只介绍原理:因为在挂载状态下,使用resize2fs命令是不允许缩小文件系统的。如果没有另一个Linux系统可用的情况下,想要在线缩小根分区文件系统大小,可以使用initram hook形式来执行e2fsck和resize2fs。因为此时操作系统启动过程还处于initram阶段,根文件系统还没有挂载。
离线缩小根分区上的文件系统操作步骤
步骤简述:
- 查看分区情况
- 缩小第二分区上的文件系统
- 使用fdisk或parted命令缩小第二分区
- 验证结果
1. 查看分区情况
root用户执行:fdisk -l /dev/sdb
# 注意fdisk只能支持MBR分区表,parted支持MBR/GPT分区表,如果你的磁盘是GPT的,可以使用parted命令: parted /dev/sdb unit s p (unit s表示按扇区查看)
回显如下:
Disk /dev/sdb: 115.5 GiB, 124017180672 bytes, 242221056 sectors ### 该磁盘大小115GB多点
Disk model: DataTraveler 3.0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xdf3f5459
Device Boot Start End Sectors Size Id Type
/dev/sdb1 16384 1064959 1048576 512M c W95 FAT32 (LBA)
/dev/sdb2 1064960 242221055 241156096 115G 83 Linux ### 第二分区大小115G, 注意起始扇区 1064960, 后面会用到 ###
root用户执行:dd if=/dev/sdb of=/root/first-16384-sector.dd count=16384
# 备份分区表,此步非必须,只是为了以防万一,可以用dd命令恢复分区表。备份分区表(这里直接备份前16384个扇区,MBR分区表存在于第一个扇区,我这里备份冗余了一点,数字16384可参考前面fdisk命令)。
回显如下:
16384+0 records in
16384+0 records out
8388608 bytes (8.4 MB, 8.0 MiB) copied, 0.456542 s, 18.4 MB/s
2. 缩小第二分区上的文件系统
root用户执行:e2fsck -f /dev/sdb2
# 先强制检查文件系统,注意-f选项
回显如下:
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
rootfs: 61657/3816960 files (0.2% non-contiguous), 786615/15728640 blocks
root用户执行:resize2fs /dev/sdb2 30720M
# 改第二分区的文件系统大小为30G
回显如下:
resize2fs 1.47.0 (5-Feb-2023)
Resizing the filesystem on /dev/sdb2 to 7864320 (4k) blocks.
3. 缩小第二分区
分别用fdisk和parted两种方法演示。fdisk命令步骤比较多,parted命令只需要一条命令。
下面的操作是fdisk的缩小第二分区的操作方法,有点繁琐。
fdisk /dev/sdb
# 注意,这里是sdb不是sdb2,下面进入fdisk操作界面
Welcome to fdisk (util-linux 2.38.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p ### p命令查看当前分区情况 ###
Disk /dev/sdb: 115.5 GiB, 124017180672 bytes, 242221056 sectors
Disk model: DataTraveler 3.0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xdf3f5459
Device Boot Start End Sectors Size Id Type
/dev/sdb1 16384 1064959 1048576 512M c W95 FAT32 (LBA)
/dev/sdb2 1064960 242221055 241156096 115G 83 Linux
Command (m for help): d ### d命令用于删除分区 ###
Partition number (1,2, default 2): 2 ### 删除第二分区 ###
Partition 2 has been deleted.
Command (m for help): n ### n命令新建分区 ###
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): p ### 分区类型是p, 也就是主分区 ###
Partition number (2-4, default 2): 2 ### 分区号是2,第二个分区, 具体是第几个分区,可以看前面的1. 查看分区情况步骤的fdisk -l命令输出###
First sector (2048-242221055, default 2048): 1064960 ### 分区的起始扇区的值,其值参考第一步的值 ###
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1064960-242221055, default 242221055): +32768M ### 分区的末尾值,这里使用32GB,为了安全起见,比前面的30GB大一点 ###
Created a new partition 2 of type 'Linux' and of size 32 GiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: n ### 是否移除签名, !!注意这里选择“否”,不移除ext4签名 !!**
Command (m for help): p ### 查看新分区情况 ###
Disk /dev/sdb: 115.5 GiB, 124017180672 bytes, 242221056 sectors
Disk model: DataTraveler 3.0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xdf3f5459
Device Boot Start End Sectors Size Id Type
/dev/sdb1 16384 1064959 1048576 512M c W95 FAT32 (LBA)
/dev/sdb2 1064960 68173823 67108864 32G 83 Linux
Command (m for help): w ### w命令写入变更 ###
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
下面是parted命令缩小第二分区的操作过程
简洁版就是直接修改分区大小,只有一条命令:parted /dev/sdb resizepart 2 33313M
# 这里的33313MB大致是:32GB加上第二分区之前的空间后的大小
繁琐版本是先删除第二分区,再建立一个新分区,操作如下:
root@raspberrypi:~# parted /dev/sdb
GNU Parted 3.5
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p ### p命令查看当前分区情况 ###
Model: Kingston DataTraveler 3.0 (scsi)
Disk /dev/sdb: 124GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 8389kB 545MB 537MB primary fat32 lba
2 545MB 124GB 123GB primary ext4
(parted) rm 2 ### rm命令删除分区,删除第二分区 ###
(parted) mkpart primary ext4 1064960s 33313M ### 新建第二分区,分区开始于第1064960扇区, 结束于32G+545MB(545M是第1分区末尾所在位置) ###
(parted) p ### p命令查看新分区情况 ###
Model: Kingston DataTraveler 3.0 (scsi)
Disk /dev/sdb: 124GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 8389kB 545MB 537MB primary fat32 lba
2 545MB 33.3GB 32.8GB primary ext4 lba
(parted) quit ### quit命令退出parted ###
Information: You may need to update /etc/fstab.
4. 验证新文件系统
使用e2fsck -f /dev/sdb2
命令检查新的第二分区上的文件系统,结果没有报错。lsblk命令查看,发现分区大小32GB, mount挂载后,发现能正常挂载,使用df -h
命令查看文件系统大小是30GB。这里文件系统比分区
大小小了2GB,那么可以umount卸载分区,使用e2fsck -f /dev/sdb2
强制检查文件系统,执行resize2fs /dev/sdb2
(注意,此处resize2fs后面不带数字),最后就发现文件系统大小就和分区大小一样大了。
在线扩大根分区上的文件系统操作步骤
直接上命令:
root用户执行:lsblk
# lsblk命令查看分区情况
回显如下:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 15.2G 0 disk ### U盘总大小接近15.2GB,注意lsblk命令查看的结果和parted命令查看的空间大小是有一定的差别的,估计是1000和1024进位的差别。
├─sda1 8:1 1 512M 0 part /boot/firmware
└─sda2 8:2 1 9.5G 0 part / ### 可见此时sda2是挂载了/分区,分区大小9.5GB,和前面第一分区加起来才10GB,说明此U盘后面有大概5G左右是自由空间。
root用户执行:parted /dev/sda
### 下面进入parted操作
GNU Parted 3.5
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit MB ### unit命令设置单位为MB
(parted) p ### p命令查看分区情况
Model: Lenovo USB Flash Drive (scsi)
Disk /dev/sda: 16359MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 8.39MB 545MB 537MB primary fat32 lba
2 545MB 10785MB 10240MB primary ext4 ### 根分区大小约10GB
(parted) resizepart 2 16359MB ### resizepart命令变更分区大小,这里将第二分区的末尾设置成U盘大小,16359MB这个数字出现在本段落前面的p命令的回显结果中,当然也可以使用100%来代替这个数字。
Warning: Partition /dev/sda2 is being used. Are you sure you want to continue?
Yes/No? yes ### 警告,我们这里输入yes
(parted) q ### q命令退出parted操作界面
Information: You may need to update /etc/fstab.
至此,第二分区的分区大小已经扩至可用空间的最大值,接下来还需要使用resize2fs命令把文件系统扩至最大可用之空间。
root用户执行:resize2fs /dev/sda2
### resize2fs不带数字参数,则文件系统扩容成最大可用空间
回显如下:
resize2fs 1.47.0 (5-Feb-2023)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/sda2 is now 3860720 (4k) blocks long.
root用户执行:lsblk
# lsblk查看分区大小。
回显如下:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 15.2G 0 disk
├─sda1 8:1 1 512M 0 part /boot/firmware
└─sda2 8:2 1 14.7G 0 part / ### 现在两个分区加起来就是15GB多点了。
root用户执行:df -h |grep '^/'
# df查看文件系统大小, 两个分区加起来也15GB多
/dev/sda2 15G 2.2G 12G 16% /
/dev/sda1 510M 66M 445M 13% /boot/firmware
在线扩大根分区上的文件系统大小的操作至此结束
关于fdisk和parted
- fdisk命令只支持MBR分区表,小于2TB的磁盘,只要不执行w命令,变更就不会生效。parted命令支持GPT和MBR分区表,支持大于2TB的磁盘,操作是实时生效的,每个操作都要谨慎。
- parted指定的大小可能会出入很大,比如我在parted命令下使用mkpart primary ext4 60G, 结果生效后,lsblk查看只有大概55GB。为了避免这个情况,我一般使用MB为单位,或者使用带小数点的值。
本博文是作者“进取有乐”原创,仅发布于博客园,其他网站转载请注明出处。