最近我将 ext4 文件系统大小缩小到 500GB
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 493G 64G 404G 14% /
现在我想缩小分区大小以完全适合文件系统大小。
我尝试使用 parted 和 resizepart 命令。问题是 parted 要求输入新大小。如果我选择 500GB,则生成的分区比 500GB 要小,因此底层文件系统无法容纳此分区。有没有关于如何进行正确大小计算的提示?
答案1
报告的大小df
将不正确,因为它们仅考虑文件系统内部使用的数据块和丢失块以及保留块。
最简单的方法是将文件系统缩小到比您想要的至少 10% 的大小。将分区大小调整为您想要的大小,然后使用 resize2fs 扩大文件系统。
如果您想手动计算,您必须知道文件系统内部有多大。使用检查tune2fs -l /dev/sda2
并将块数乘以块大小。在 parted 中调整分区大小时,使用并将单位切换为扇区,unit s
然后print
使用表格获取起始扇区和逻辑扇区大小。将上面的总大小(以字节为单位)除以扇区大小。四舍五入到最接近的 2048 倍数,并将大小调整为此扇区数(结束扇区 = 扇区大小 + 起始扇区 - 1)。
公式(在 Python 中运行,只需填写前 4 个值):
block_count = N
block_size = N
sector_size = N
start_sector = N
fs_size = block_count * block_size
fs_sectors = fs_size/sector_size
part_sectors = ((fs_sectors-1)/2048+1)*2048
end_sector = start_sector + part_sectors - 1
print "Partition start: %d end: %d size: %d"%(start_sector,end_sector,part_sectors)
print "Resize in parted with: \nresizepart <number> %ds"%(end_sector)
答案2
以下是整个过程的一个例子。
这是硬盘:
root@debian:~# fdisk /dev/loop0
Command (m for help): p
Disk /dev/loop0: 4,9 GiB, 5243928576 bytes, 10242048 sectors
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: 0xc5127fad
Device Boot Start End Sectors Size Id Type
/dev/loop0p1 8192 9765625 9757434 4,7G 83 Linux
注意:“/dev/loop0”是回环设备,是基于文件容器的虚拟硬盘。物理硬盘将被命名为“/dev/sda”。
该磁盘包含一个大小为 4.7GB 的分区(/dev/loop0p1)。
这是分区上的文件系统:
root@debian:~# df -h
/dev/loop0p1 4,7G 2,1G 0 45% /mnt
默认情况下,它的大小与分区相同(4.7GB)。但只使用了 2.1GB(45%)的文件系统。这意味着我们可以将文件系统和分区缩小到 2.1 GB,而不会丢失任何数据。
第一步是在分区上使用带有 -M 开关的 resize2fs。与磁盘碎片整理程序类似,此命令将尝试将所有文件移动到文件系统的开头以形成一个连续的块。然后,这允许将文件系统缩小到其最小可能大小。resize2fs 仅适用于 ext 文件系统,对于其他文件系统,您必须找到具有此功能的等效程序。
root@debian:~# resize2fs -M /dev/loop0p1
文件系统现在如下所示:
root@debian:~# df -h
/dev/loop0p1 2,1G 2,1G 0 100% /mnt
硬盘现在包含一个 4.7GB 的分区,其中有一个 2.1GB 的文件系统,使用率达到 100%。下一步是缩小分区大小以适应较小的文件系统。
为此,我们需要计算新文件系统的大小。 dumpe2fs 工具对此非常有用,它可以显示有关文件系统的详细信息。
root@debian:~# dumpe2fs -h /dev/loop0p1
dumpe2fs 1.43.4 (31-Jan-2017)
Filesystem volume name: <none>
Last mounted on: /
Filesystem UUID: 7d5ec9a4-cc65-4433-95e2-6536e4fd56d6
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options: journal_data_writeback user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 139392
Block count: 565950
Reserved block count: 7825
Free blocks: 8611
Free inodes: 2296
First block: 0
Block size: 4096
这告诉我们有 565950 个块,块大小为 4096 字节。这使我们能够计算文件系统大小:
565950 个块 * 4096 字节 = 2318131200 字节
由此,我们可以计算文件系统的扇区大小。从上面的 fdisk 输出中,我们知道硬盘扇区大小为 512 字节:
2318131200 字节 / 512 字节扇区大小 = 4527600 个扇区
因为分区不是从扇区 0 开始的,所以我们需要从上面的 fdisk 输出中添加起始扇区,然后减一,因为扇区计数从零开始:
4527600 + 8192(起始扇区) - 1 = 4535791
这是我们分区的新结束扇区。
现在我们可以使用 parted 将分区缩小到这个新的结束扇区。“unit s”命令用于将单位切换为扇区。
root@debian:~# parted
GNU Parted 3.2
Using /dev/sda
(parted) select /dev/loop0
Using /dev/loop0
(parted) unit s
(parted) p
Model: Loopback device (loopback)
Disk /dev/loop0: 10242048s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 8192s 9765625s 9757434s primary ext4
(parted) resizepart 1 4535791
Warning: Shrinking a partition can cause data loss, are you sure you want to
continue?
Yes/No? yes
(parted) p
Model: Loopback device (loopback)
Disk /dev/loop0: 10242048s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 8192s 4535791s 4527600s primary ext4
它向我们发出了有关潜在数据丢失的警告,但要切断的扇区中应该没有数据。我们现在有一个 2.1GB 的分区,其中的文件系统已 100% 占用。