Resize a Vagrant VMDK Drive

Using Vagrant as a development environment is great. But you have to watch the available disk space when doing some funky database benchmarking. Last Friday i wrote a script to populate a test database with over 60 million records. And left it running over the weekend. With the idea it would be finished when i returned to the office on Monday. Well it actually was still running. But the Vagrant instance was out of disk space when i logged in. Damn. Should have made sure i had a big disk attached to this instance.

O well. My first idea was to just drop the database that i wanted to use for testing. But due to no space available on the system. I could not drop it. I really couldn’t do anything on the system. Even writing config files failed. So where did all the disk space go?

$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/debian-605-root 10G 9.8G 0.2G 99% /

That’s really not that much space left. And /var/mysql/ibdata1 for the InnoDB tables was taking up 7 GB. And since i have a couple of InnoDB tables i can’t just delete this file. So need to come up with something else. And after a bit of Googling. I came across this post. Which seemed promising. But the most important part is left out. And instead linked to some horrible garbled page. That is completely unreadable. So i had to do some digging to figure this out on my own. For cloning the disks i followed the steps in the article however. The Virtual Box files are located in the user folder in the following path

$ cd ~/VirtualBox VMs/development_*

The first thing i did was convert the VMDK image to a VDI image so we can actually do some partition resizing.

$ VBoxManage clonehd box-disk1.vmdk box-disk1.vdi –format VDI

So now we have a new VDI image. And we need to resize it so it has sufficient space for what we are trying to do. In my case 20 GB is sufficient.

$ VBoxManage modifyhd box-disk1.vdi –resize 20000

Now that the new disk is created it needs to be attached to the vagrant virtual machine. This is easily achieved by doing right click on the VM in VirtualBox and select Settings

Storage > SATA Controller > Add hard disk (select existing and point to the new VDI image)

Now boot the Vagrant image in VirtualBox so we have a screen to work with. When it has booted up. Login.

First create a new Primary partition in the unused space of type Linux LVM (8e) with cfdisk.

$ cfdisk /dev/sda

When the partition table has been written. It’s time to create a new physical volume on the new partition with the help of pvcreate

$ pvcreate /dev/sda3
successfully created

For the next steps we will be needing the Volume Group name. We will get this by running pvdisplay

$ pvdisplay | grep “VG Name”
VG Name debian-605

So now we have all the bits ready. And its time to extend the root partition with the newly created partition.

$ vgextend debian-605 /dev/sda3
Volume group “debian-605” successfully extended

Awesome! next step extending the logical partition

$ lvextend /dev/debian-605/root /dev/sda3
Extending logical volume root to 18.84 GiB
Logical volume root successfully resized

Almost there. The last thing left to do is resize the filesystem to make all space available.

$ resize2fs /dev/debian-605/root
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/debian-605/root is mounted on /; on-line resizing required old desc_blocks = 1, new_desc_blocks = 2
Performing an on-line resize of /dev/debian-605/root to 4937728 (4k) blocks.
The filesystem on /dev/debian-605/root is now 4937728 blocks long.

It’s that simple really. So let’s check.

$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/debian-605-root 19G 8.6G 9.1G 49% /

After this i did not bother to convert the VDI image back to a VDMK image. But if you have to for some reason. You could do that with the commands below. And some manual editing of the VirtualBox xml config.

$ VBoxManage internalcommands sethduuid box-disk1.vdi
$ VBoxManage clonehd box-disk1.vdi box-disk1.vmdk –format VMDK

So that’s it really for resizing the Vagrant hard drive. The only thing left for me was to cleanup the large ibdata1 file. And setup Mysql to use separate ibdata files for InnoDB table.

$ vi /etc/mysql/my.cnf
[mysqld]
innodb_file_per_table

Restart Mysql and dump all needed databases except the system tables like (mysql, information_schema).

$ /etc/init.d/mysql restart
$ echo ‘show databases;’ | mysql -uroot -p | grep -v ^Database$ | grep -v ^information_schema$ | grep -v ^mysql$ | xargs mysqldump -uroot -p –databases > dump.sql

When that’s done. Drop all InnoDB database tables. Remove the ibdata and in_log files from /var/lib/mysql.

$ /etc/init.d/mysql stop
$ rm /var/mysql/ibdata1* /var/mysql/ib_log*

Now we restart Mysql. And reimport the databases.

$ /etc/init.d/mysql start
$ mysql -uroot -p < dump.sql

comments powered by Disqus