In Part 1 I explained how to move your MySQL instance onto an XFS volume. Now I show you the frankenstein script I created, stealing bits and adapting from other people’s attempts.
Below is the full script. It’s quite self explanatory. It firstly collects the instance i.d. which it’ll then use in all the other calls. It then finds the MySQL volume based on the device mounted where the data files are. To get an adequate snapshot it then connects the the MySQL daemon and causes the databases to go read only before it freezes the filesystem. Next it calls to the EC2 API for a snapshot to be generated of that volume and once the call has been completed (which doesn’t take long) it unfreezes the filesystem and restores the databases to read/write.
That’s the hard work done. The next step is to loop through the remaining volumes and just take a straight snapshot.
Finally it finds the snapshots for all the volumes and clears out any over the amount defined by MY_SNAPSHOTS.
#!/bin/bash
export EC2_HOME=<put your EC2 tools home here>
export JAVA_HOME=<put your jre home here>
export EC2_URL=<put the amazon api url here e.g. https://ec2.eu-west-1.amazonaws.com>
export PATH=$PATH:$EC2_HOME/bin
export EC2_CERT=<path to amazon cert here>
export EC2_PRIVATE_KEY=<path to amazon key here>
MY_MYSQL_MOUNT_POINT=<mysql data directory here e.g. /var/lib/mysql>
MY_SNAPSHOTS=<days of snapshots you want to keey e.g. 7>
MY_MYSQL_VOLUME=$(cat /proc/mounts |grep ${MY_MYSQL_MOUNT_POINT} |awk {'print $1'})
MY_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
echo "Finding MySQL Volumes";
VOLUME_LIST=$(ec2-describe-volumes --filter "attachment.instance-id=${MY_INSTANCE_ID}" | grep ATTACHMENT | grep ${MY_MYSQL_VOLUME} | awk {'print $2'})
for VOLUME in $(echo $VOLUME_LIST); do
VOLUME_NAME=$(ec2-describe-volumes $VOLUME | sed -n 3p | awk {'print $5'})
echo "Connecting and locking MYSQL"
mysql -u root <<-EOFMYSQL
flush tables with read lock;
show master status;
system echo "Freezing system for backup"
system xfs_freeze -f /var/lib/mysql
system echo "Creating MySQL Snapshot..."
system ec2-create-snapshot -d "$VOLUME_NAME daily backup" $VOLUME
system echo "Unfreeze XFS"
system xfs_freeze -u /var/lib/mysql
unlock tables;
exit
EOFMYSQL
done
echo "Finding Other Volumes";
VOLUME_LIST=$(ec2-describe-volumes --filter "attachment.instance-id=${MY_INSTANCE_ID}" | grep ATTACHMENT | grep -v ${MY_MYSQL_VOLUME} | awk {'print $2'})
for VOLUME in $(echo $VOLUME_LIST); do
VOLUME_NAME=$(ec2-describe-volumes $VOLUME | sed -n 3p | awk {'print $5'})
echo "Creating Snapshot..."
ec2-create-snapshot -d "$VOLUME_NAME daily backup" $VOLUME
done
echo "Clearing Old Snapshots";
VOLUME_LIST=$(ec2-describe-volumes --filter "attachment.instance-id=${MY_INSTANCE_ID}" | grep ATTACHMENT | awk '{ print $2 }')
for VOLUME in $(echo $VOLUME_LIST); do
NUMBER_SNAPSHOTS=`ec2-describe-snapshots | grep $VOLUME | grep -v "Created by CreateImage" | wc -l`
echo "Snapshots: $NUMBER_SNAPSHOTS"
if [ "$NUMBER_SNAPSHOTS" -gt "$MY_SNAPSHOTS" ]; then
ec2-describe-snapshots --filter "volume-id=$VOLUME" | grep -v "Created by CreateImage" | sort -k 5 | head -$(($NUMBER_SNAPSHOTS-$MY_SNAPSHOTS)) | awk '{print "Deleting: $2; system("ec2-delete-snapshot " $2)}'
fi
done
echo "Done!"
Recent Comments