shrink root volumes in AWS
01 Mar 2024
Volumes
- /dev/nvme1n1 → Old volume → /old
- /dev/nvme2n1 → New volume → /new
- /dev/nvme3n1 → Backup Old volume (only applicable for XFS root volumes) → /old-backup
General instructions
- Create a snapshot of the root volume
- Stop the target instance
- Create a new volume with the desired size, ensure iops and speed are equal to the old volume
- Create a tmp ec2 instance, this is what would be used to copy data between the old / new volumes
- Detach the root volume from the old instance and attach it to the tmp one
- Attach the new volume to the tmp instance and ssh into it
mkdir -p /old /new
dd bs=16M if=/dev/nvme1n1 of=/dev/nvme2n1 count=100
#copy bootloader from old to the new volumefdisk /dev/nvme2n1
#format new volumepress 'p' take note on the start section, eg: 2048 delete the current partition with 'd' create a new partition 'n' and use the previous start section press 'a' to make the partition bootable press 'w' to save changes
fdisk -l
#review than old and new volumes looks similar
########## ext2/3/4 ##########
e2fsck -f /dev/nvme1n1p1
#check for errors in old volumeresize2fs -M -p /dev/nvme1n1p1
#move the data to the beginning of the partition
In the previous command’s output, the last line tells you the number of blocks. Each block is sized 4K but when we clone the partition, we are going to do it in 16 MB blocks. So, in order to compute the number of 16 MB, blocks, multiply the number in the last line by 4 / (16 * 1024).
Round this number UP (not down) to the nearest integer. Example: 1252939 (number in last line) * 4 / (16 * 1024) = 305.893310546875 … But round this UP to 306 or even 310 (it doesn’t matter as long as you don’t go below).
dd bs=16M if=/dev/nvme1n1p1 of=/dev/nvme2n1p1 count=310
#copy data from old to new volume
resize2fs -p /dev/nvme2n1p1
#new volume, expand fse2fsck -f /dev/nvme2n1p1
#fix possible errors in the new volume
########## xfs ##########
- Create an additional volume same size as old volume and attached to the tmp instance. Will be use it to host a backup of the original fs, this is a workaround to xfs lack of shrinking capacity
mkfs.xfs /dev/nvme2n1 /dev/nvme3n1
#format the new and the additional volumemount /dev/nvme1n1 /old; mount /dev/nvme2n1 /new
mkdir /old-backup; mount /dev/nvme3n1 /old-backup
xfsdump -L data -f /old-backup/old.xfsdump /old
xfsrestore -f /old-backup/old.xfsdump /new/
blkid /dev/nvme1n1p1
#get old uuidxfs_admin -U <UUID from step above> /dev/nvme2n1p1
#apply old uuid to new volumexfs_admin -L / /dev/nvme2n1p1
Final step
Dettach the new volume, attach it to the target instance as /dev/sda1 and start the instance
References: