Recently I migrated my home lab from a SuperMicro SYS-E300-8D to something a little beefier. There were ten virtual machines on the SuperMicro server, nine which were allocated 127 GB of thin-provisioned storage, and one VM with 256 GB of thin-provisioned storage.
Thin provisioning — as the name implies — lets the guest operating system think that it has the full amount of storage available, when in fact it’s a deft bit of juggling by me to make sure none of the machines exceeds the 1 TB of physical storage available on the Samsung EVO drive.
I was moving the machines to a brand new host with a brand new hypervisor, so I couldn’t just use a tool like VMware’s vMotion. During the data transfer process the SuperMicro crashed before I could complete migrating the virtual machines. That attempted data transfer was time-consuming, as each virtual machine’s “full” allocated space was 1.4 TB. To speed up the total transfer and increase the chances of getting the data off the SuperMicro before it crashed again, I needed to remove the free space in each VM. This significantly reduced their size, as the VMs were only approximately 40% allocated, and resulted in a successful transfer to my laptop which I used as an impromptu intermediary via a patch cable.
The technical term for removing free space in the VMDK file is “hole punching” (I don’t make the rules). If you understand that files are allocated randomly wherever the operating system finds space, this can result in gaps (or holes) on the virtual drive when a file is deleted or moved. Hole punching removes these gaps conceptually in the same way that defragmenting a spinning disk works, by putting all the files at the beginning of the drive and lopping off the end.
Note: It’s functionally the same way shrinking a database works in SQL Server as well, and as my blog is principally about SQL Server, there you have the lone reference to SQL Server, three times in one sentence.
To hole-punch a virtual drive on ESXi you first need to shut down the VM, and then run a command on the host. ESXi has ssh
functionality, but it must be enabled first.
Once you’ve connected to the host with your favourite ssh client, you then navigate to the storage device where the VMDK file for your virtual machine is located, and run the following command (where sql150 is the name of the VM in this example):
vmkfstools -K sql150.vmdk
Once the process is complete, you can restart the virtual machine.
Note: Depending on which operating system you use on the guest, you may need to zero out unused space first, before running this command. You can find out more from this site.
Convert a thick-provisioned drive to thin-provisioned
Another tip you might find useful is converting a thick-provisioned drive to a thin-provisioned drive. In ESXi, it’s very easy to create a virtual machine with the wrong storage, and only realize this once the VM is up and running and you’re running out of space.
This process is a little more convoluted, because you have to clone the virtual drive as a thin-provisioned drive, rename the old one, name the new file the same as the old one, and then delete the old one once you’re sure the virtual machine restarts successfully.
Also, it’s worth mentioning that the VMDK file itself is not where your data lives. The VMDK file that is named after the VM is a pointer to a second file, following the convention <name_of_vm>-flat.vmdk
, and that’s where the data is stored.
When you clone the drive, you target the main .vmdk
file, but it is the *-flat.vmdk
file which is cloned.
Step 1: Clone the drive. Notice the -d thin
command parameter.
vmkfstools -i sql150.vmdk -d thin sql150-shrunk.vmdk
Step 2: Rename the original file.
vmkfstools -E sql150.vmdk sql150-original.vmdk
Step 3: Rename the new file to replace the original file.
vmkfstools -E sql150-shrunk.vmdk sql150.vmdk
And once you’ve confirmed that the VM starts up correctly, you can remove the old file.
rm sql150-original.vmdk
Share your thoughts in the comments below.
Photo by Gabriel Manlake on Unsplash.