Shrinking an Ext4 File System on LVM in Linux
Posted on In Hardware, Linux, TutorialIn Extending a Mounted Ext4 File System on LVM in Linux, we introduced how to extend a mounted ext4 filesystem on LVM Logical volume by adding a new physical volume. It is also common to shrink an ext4 file system as to spare some disk space. In this post, I will discuss how to shrink an ext file system on a LVM logical volume (LV).
After the file system and LV is shrunk, the disk space is returned to the volume group (VG) and you can allocate the disk space in the VG to other LVs. On the other hand, you may also delete a PV to remove a hard drive from the Linux box or shrink the underlining partition to spare some raw disk space. We will also introduce these 2 following actions.
The example we used for introduction here is that /dev/sdb is a hard drive with a partition /dev/sdb1 as a PV of VG vg, vg contains a LV named lv_data, and an ext4 file system on lv_data is created and mounted to /mnt/data.
Table of Contents
First step: backup your data
Backup your data in /mnt/data first! Shrinking file systems and partitions are danger operations. Backup your data before any following operations.
Unmount the ext4 file system
Different from extending the file system, it is better to umount the file system first before shrinking it:
# umount /mnt/data
Extending a file system will give it more spare space where there is no data stored since the space is new. However, for shrinking a file system, the to be deleted space from the file system may have data stored there and it is more complex. To avoid possible data loss, please unmount the file system first.
Shrink the ext4 file system and the LVM LV
The suggested way to shrink the ext4 file system and the LVM LV is to use the lvresize
command:
# lvresize --resizefs --size SIZE /dev/vg/vg_data
Here, SIZE is your intended new size for the LV and file system, such as 200G. --resizefs
lets lvresize
also resize underlying filesystem together with the logical volume. It is better than resize2fs
+ lvresize
since it is not unlikely for an admin to accidently use inconsistent parameter for resize2fs
and lvresize
.
It will prints information like (may be different according to the versions of the tools on you system):
fsck from util-linux 2.21.2
/dev/mapper/vg_linux-lv_home: 15741/54419456 files (0.1% non-contiguous), 4781794/217677824 blocks
resize2fs 1.42.3 (14-May-2012)
Resizing the filesystem on /dev/mapper/vg_linux-lv_home to 26214400 (4k) blocks.
Reducing logical volume lv_home to 100.00 GiB
Logical volume lv_home successfully resized
Please note that this command may take much time for moving data to spare disk space. Only do this when you have sufficient time allowing the file system being kept unmounted.
After this command executes successfully, you can remount the file system again and check the file system size by df -hT
.
Next steps
After the file system and LV is shrunk, the disk space is returned to the VG vg and you can allocate the space to other LVs. Here, we introduce 2 other possible following steps depending on your purpose of shrinking the file system and LV. You may check them only if you need them.
1. Removing the hard drive
You may want to remove the /dev/sdb from the box. Make sure you shrink the file system to small enough in the above lvresize
command so that the spare space in the vg is larger than /dev/sdb1’s capacity.
To remove the hard drive, detailed tutorial can be found in How to delete a disk from a LVM group while keeping the data. Here, we only list the commands:
# pvmove /dev/sdb1
# vgreduce vg /dev/sdb1
# pvremove /dev/sdb1
Then, if there is no other partitions on /dev/sdb, you are free to remove the hard drive for /dev/sdb. Finding the physical hard drive for a device like /dev/sdb in Linux may be tricky (/dev/sdb is not always the 2nd disk on your box!), my suggested method is introduced in
2. Shrinking the partitions
You may not want to remove /dev/sdb but to shrink /dev/sdb1 and spare some raw disk space for creating other partitions on /dev/sdb.
To achieve this, you need 2 steps: shrink the PV /dev/sdb1 and shrink the disk partition /dev/sdb1.
Shrink the PV
Now, you need pvresize
:
# pvresize --setphysicalvolumesize SIZE /dev/sdb1
Here, ensure that the PV size SIZE is appropriate for your intended new partition size of /dev/sdb1.
Shrink the partition
Here, I suggest parted
for resizing partition instead of the old method of shrinking partition using fdisk
.
The resizepart
subcommand in parted
can move the END position of a partition:
2.4.10 resizepart
-----------------
-- Command: resizepart NUMBER END
Moves the END position of partition NUMBER. Note that this does
not modify any filesystem present in the partition. If you wish to
do this, you will need to use external tools, such as 'resize2fs'.
When growing a partition you will want to grow the filesystem
afterwards, but when shrinking, you need to shrink the filesystem
before the partition.
An example of using the resizepart
command in parted
is as follows:
# parted /dev/sdb
GNU Parted 3.2
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: ATA ST31000528AS (scsi)
Disk /dev/sdb: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 32.3kB 700GB 700GB primary
(parted) resizepart
Partition number? 1
End? [700GB]? 650GB
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? No
(parted) resizepart
Partition number? 1
End? [650GB]? 680GB
(parted) quit
Information: You may need to update /etc/fstab.
Note that in this example, we select “No” for the warning parted printed out for safety and use a larger size instead.
Besides of parted
, if you prefer a GUI program, the GPartd is a very handy tool for shrinking partitions.
Instead of
“lvresize –resizefs –resize ”
it should be
“lvresize –resizefs –size “
That’s a bug. Thanks lot Dieter for reporting this!
There’s an error in the resize command. –resize should be –size:
# lvresize –resizefs –size SIZE /dev/vg/vg_data
Otherwise lvresize throws an error.
Thanks Mike for the reporting. It was fixed.
Thanks Eric. The combined shrink and resize operation as described worked perfectly for me.
Good to know that. Cheers!
lvresize saved me a lot of pain , and is WAY MORE safer than lvreduce , esp on a prod server.
Thanks, much appreciated.
I am very glad to know it helped!
It’s awesome.. fixed for me too.. thanks
Very clear and useful !
thanks
Thanks for your write up, definitely a lot less messier than manually shrinking fs then lv. And the backup bit up there before all the work is abolutely spot on.
Cheers