Amazon VPS instances, by default only have a single disk for the whole filesystem of the server. Unless you chose to add an additional disk when you provision the server, adding disk space to your VPS can be tricky. Here’s a run down on how to add more storage to your server on amazon by mounting a new drive.
In this tutorial, I’ve mounted the new drive to /var/lib/mysql since I need to increase the disk space used by the database. This tutorial is still applicable even if you want to increase a different folder. The process will be the same.
**NOTE: Do the steps here in sequence. Do not proceed to next steps if you get any error. Any errors when messing with hard drives can cause you to lose data. I suggest you make a snapshot of you server first before you make any changes.
1. Perform pre-check on the server
Login to the server via ssh
Check the current disks and partition layout using the below command. Don’t worry if your system has different layout. You just need to make check the disk now so you can identify the new disk that we will add later.
[root@goddard ~]# parted -l && lsblk
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvda: 32.2GB
--> this is the only hard drive on the systemSector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 2097kB 1049kB bios_grub
2 2097kB 32.2GB 32.2GB xfs
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 30G 0 disk
--> the current hard drive has two partitions├─xvda1 202:1 0 1M 0 part
└─xvda2 202:2 0 30G 0 part /
[root@goddard ~]# df –PTh
--> this is the current disk usageFilesystem Type Size Used Avail Use% Mounted on
/dev/xvda2 xfs 30G 5.6G 25G 19% /
devtmpfs devtmpfs 477M 0 477M 0% /dev
tmpfs tmpfs 496M 0 496M 0% /dev/shm
tmpfs tmpfs 496M 13M 484M 3% /run
tmpfs tmpfs 496M 0 496M 0% /sys/fs/cgroup
tmpfs tmpfs 100M 0 100M 0% /run/user/1000
2. Create a disk EC2 web console
Login to AWS EC2 console.
Go to Elastic Block Store > Volumes
Click Create Volume. On the dialog box:
Volume Type: General Purpose SSD
Size: the size of the new disk.
Availability Zone: the same availability zone of the Server you want to attach it
Snapshot ID: (blank/none)
Encryption: Do not check
Click Create and wait for it until its state is “Available”. Take note of the Volume ID of the newly created disk.
3. Attach the New Disk to the Server
Before you attach the disk, go to > Instances on the amazon web console select the server instance and click Actions > Instance State > Stop to shut down the server.
Go to Elastic Block Store > Volumes again
Select the newly created disk and click Actions > Attach Volume.
On the dialog box:
Instance: input the Instance ID of the server in which you’ll attach this volume
Device: Leave this as the default
If the volume is successfully attached, you see the Attachment Information column filled with the Instance ID which uses this volume.
Now go to > Instances and select the server instance
You should see on the Description tab that a new block device is attached to it.
4. Create a Partition on the New Disk
We need to partition and format the disk before we can use it.
Login to the server via ssh.
Re-check the drives to identify the newly added disk
[root@goddard ~]# parted -l; lsblk
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvda: 32.2GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 2097kB 1049kB bios_grub
2 2097kB 32.2GB 32.2GB xfs
Error: /dev/xvdf: unrecognised disk label
Model: Xen Virtual Block Device (xvd)
Disk /dev/xvdf: 10.7GB --> this is the new disk
Sector size (logical/physical): 512B/512B
Partition Table: unknown
Disk Flags:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 30G 0 disk
├─xvda1 202:1 0 1M 0 part
└─xvda2 202:2 0 30G 0 part /
xvdf 202:80 0 10G 0 disk --> the new disk has no existing partition
Now we’ll need to create a partition on the new disk. Use fdisk utility as shown below:
** BE SURE TO USE THE CORRECT DISK OR DATA WILL BE LOST
[root@goddard /]# fdisk /dev/xvdf --> new drive to be used by fdisk Welcome to fdisk (util-linux 2.23.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table Building a new DOS disklabel with disk identifier 0xc0060bd5. Command (m for help): p --> p to print the current partitions of the disk Disk /dev/xvdf: 10.7 GB, 10737418240 bytes, 20971520 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 Disk label type: dos Disk identifier: 0xc0060bd5 Device Boot Start End Blocks Id System Command (m for help): n --> n to create a new partition Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p --> p for primary partition Partition number (1-4, default 1): --> default (just press Enter) First sector (2048-20971519, default 2048): --> default (just press Enter) Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519): --> default (Enter) Using default value 20971519 Partition 1 of type Linux and of size 10 GiB is set Command (m for help): p --> print again to see the new created partition Disk /dev/xvdf: 10.7 GB, 10737418240 bytes, 20971520 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 Disk label type: dos Disk identifier: 0xc0060bd5 Device Boot Start End Blocks Id System /dev/xvdf1 2048 20971519 10484736 83 Linux --> NEW partition created
**IF you made a mistake on the above points, press q, then Enter to quit without saving. Then start fdisk again. If all is correct, then continue below:
Command (m for help): w --> save and exit the changes you made The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
Verify the new partition created:
[root@goddard /]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 30G 0 disk ├─xvda1 202:1 0 1M 0 part └─xvda2 202:2 0 30G 0 part / xvdf 202:80 0 10G 0 disk └─xvdf1 202:81 0 10G 0 part --> This is the new partition
5. Format the New Partition as ext4
Now we’ll need to format the partition to ext4 (default for Centos 6).
[root@goddard /]# mkfs.ext4 /dev/xvdf1 --> Be sure to input the correct partition mke2fs 1.42.9 (28-Dec-2013) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 655360 inodes, 2621184 blocks 131059 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=2151677952 80 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done
6. Create a Temporary Mount for the New Partition
Now we can mount the drive and start the copying of data.
Create a temporary folder:
[root@goddard /]# mkdir /mysqlnew
Change the ownership of the folder to mysql:
[root@goddard /]# chown -R mysql.mysql /mysqlnew
Mount the new partition:
[root@goddard /]# mount /dev/xvdf1 /mysqlnew
Verify it is mounted:
[root@goddard /]# df -PTh Filesystem Type Size Used Avail Use% Mounted on /dev/xvda2 xfs 30G 5.6G 25G 19% / devtmpfs devtmpfs 477M 0 477M 0% /dev tmpfs tmpfs 496M 0 496M 0% /dev/shm tmpfs tmpfs 496M 13M 484M 3% /run tmpfs tmpfs 496M 0 496M 0% /sys/fs/cgroup tmpfs tmpfs 100M 0 100M 0% /run/user/1000 /dev/xvdf1 ext4 9.8G 37M 9.2G 1% /mysqlnew --> This is the temporary mount
7. Copy the Database data to the Temporary Folder
Stop the myslqd service first:
[root@goddard /]# service mysqld stop
Verify mysqld is stopped successfully:
[root@goddard /]# service mysqld status
Start the copying of database data. This will take a long time depeding on how big you data is.
[root@goddard /]# cp -pav /var/lib/mysql/* /mysqlnew/ ‘/var/lib/mysql/aria_log.00000001’ -> ‘/mysqlnew/aria_log.00000001’ ‘/var/lib/mysql/aria_log_control’ -> ‘/mysqlnew/aria_log_control’ ‘/var/lib/mysql/ibdata1’ -> ‘/mysqlnew/ibdata1’ ‘/var/lib/mysql/ib_logfile0’ -> ‘/mysqlnew/ib_logfile0’ ‘/var/lib/mysql/ib_logfile1’ -> ‘/mysqlnew/ib_logfile1’ ‘/var/lib/mysql/mysql’ -> ‘/mysqlnew/mysql’ ‘/var/lib/mysql/mysql/db.frm’ -> ‘/mysqlnew/mysql/db.frm’ . . [output truncated...]
Verify the temporary folder has the files. The contents should be the same as the original
[root@goddard /]# ls -l /mysqlnew total 28720 -rw-rw---- 1 mysql mysql 16384 Apr 30 03:08 aria_log.00000001 -rw-rw---- 1 mysql mysql 52 Apr 30 03:08 aria_log_control -rw-rw---- 1 mysql mysql 18874368 Apr 30 03:08 ibdata1 -rw-rw---- 1 mysql mysql 5242880 Apr 30 03:08 ib_logfile0 -rw-rw---- 1 mysql mysql 5242880 Apr 30 03:07 ib_logfile1 drwx------ 2 root root 16384 Apr 30 04:27 lost+found drwx------ 2 mysql mysql 4096 Apr 30 03:07 mysql drwx------ 2 mysql mysql 4096 Apr 30 03:07 performance_schema drwx------ 2 mysql mysql 4096 Apr 30 03:07 test
This is the original folder for comparison:
[root@goddard /]# ls -l /var/lib/mysql/ total 28700 -rw-rw---- 1 mysql mysql 16384 Apr 30 03:08 aria_log.00000001 -rw-rw---- 1 mysql mysql 52 Apr 30 03:08 aria_log_control -rw-rw---- 1 mysql mysql 18874368 Apr 30 03:08 ibdata1 -rw-rw---- 1 mysql mysql 5242880 Apr 30 03:08 ib_logfile0 -rw-rw---- 1 mysql mysql 5242880 Apr 30 03:07 ib_logfile1 drwx------ 2 mysql mysql 4096 Apr 30 03:07 mysql drwx------ 2 mysql mysql 4096 Apr 30 03:07 performance_schema drwx------ 2 mysql mysql 6 Apr 30 03:07 test
Compare the size of the copied files to the original files if they are the same:
[root@goddard /]# du -sh /var/lib/mysql /mysqlnew 30M /var/lib/mysql 30M /mysqlnew
You can now umount the temporary folder:
[root@goddard /]# umount /mysqlnew
Verify it is unmounted:
[root@goddard /]# df -PTh --> /mysqlnew should not be displayed anymore Filesystem Type Size Used Avail Use% Mounted on /dev/xvda2 xfs 30G 5.6G 25G 19% / devtmpfs devtmpfs 477M 0 477M 0% /dev tmpfs tmpfs 496M 0 496M 0% /dev/shm tmpfs tmpfs 496M 13M 484M 3% /run tmpfs tmpfs 496M 0 496M 0% /sys/fs/cgroup tmpfs tmpfs 100M 0 100M 0% /run/user/1000
8. Create a Permanent Mount of the New Drive
Now that we have a new copy we can move the old /var/lib/mysql:
[root@goddard /]# mv /var/lib/mysql /var/lib/mysql.bak
Create the new folder and set the ownership:
[root@goddard /]# mkdir /var/lib/mysql
[root@goddard /]# chown -R mysql.mysql /var/lib/mysql
Next well need the UUID of the new Drive:
[root@goddard /]# blkid /dev/xvdf1
/dev/xvdf1: UUID="42e73888-c3fb-41c6-916d-85d3e4d50f32" TYPE="ext4" --> copy the UUID
Edit the fstab:
[root@goddard /]# nano /etc/fstab
Add the below line with the correct UUID of the drive: (this is a single only)
UUID=42e73888-c3fb-41c6-916d-85d3e4d50f32 /var/lib/mysql ext4 defaults 0 0
Save and exit the /etc/fstab file.
Mount the new disk on /var/lib/mysql:
[root@goddard /]# mount /var/lib/mysql
Change the ownership again just to make sure:
[root@goddard /]# chown -R mysql.mysql /var/lib/mysql
Verify you mounted /var/lib/mysql successfully:
[root@goddard /]# df -PTh Filesystem Type Size Used Avail Use% Mounted on /dev/xvda2 xfs 30G 5.6G 25G 19% / devtmpfs devtmpfs 477M 0 477M 0% /dev tmpfs tmpfs 496M 0 496M 0% /dev/shm tmpfs tmpfs 496M 13M 484M 3% /run tmpfs tmpfs 496M 0 496M 0% /sys/fs/cgroup tmpfs tmpfs 100M 0 100M 0% /run/user/1000 /dev/xvdf1 ext4 9.8G 66M 9.2G 1% /var/lib/mysql --> this is the new mysql disk
Verify the files are in there:
[root@goddard /]# ls -la /var/lib/mysql total 28728 drwxr-xr-x 6 mysql mysql 4096 Apr 30 04:30 . drwxr-xr-x. 37 root root 4096 Apr 30 04:36 .. -rw-rw---- 1 mysql mysql 16384 Apr 30 03:08 aria_log.00000001 -rw-rw---- 1 mysql mysql 52 Apr 30 03:08 aria_log_control -rw-rw---- 1 mysql mysql 18874368 Apr 30 03:08 ibdata1 -rw-rw---- 1 mysql mysql 5242880 Apr 30 03:08 ib_logfile0 -rw-rw---- 1 mysql mysql 5242880 Apr 30 03:07 ib_logfile1 drwx------ 2 mysql mysql 16384 Apr 30 04:27 lost+found drwx------ 2 mysql mysql 4096 Apr 30 03:07 mysql drwx------ 2 mysql mysql 4096 Apr 30 03:07 performance_schema drwx------ 2 mysql mysql 4096 Apr 30 03:07 test
9. Start the mysqld Service and Test
After mounting the drive, start the mysqld service.
[root@goddard /]# service mysqld start
[root@goddard /]# service mysqld status
Now test the application and query the database if everything has been imported successfully.
10. Post-checks
To completely test the new drive is mounted during startup and no errors found, I suggest you REBOOT the server from the Amazon web console.
Once data is verified, we can now delete the old backup data to reclaim the space for the OS.
** BE SURE THAT YOU DELETE THE BACKUP FOLDER ONLY!!!
[root@goddard /]# rm -rf /var/lib/mysql.bak
———————————————
masterkenneth