Just downloaded, built and test a tool for Hot Backup of MySQL InnoDB databases: xtrabackup from Percona.
You can try the apt/rpm repository too.
You get two backup tools, that are quite easy to use:
- xtrabackup – a C program that merges redo logs and InnoDB files to create Hot Backups;
- innobackupex – Â a perl wrapper around xtrabackup.
To backup your databases, prepare a mysql-owned /opt/backup_mysql/
#useradd backup -m -d /opt/backup_mysql;
Then run just run
# innobackupex  –user=root –password=password /opt/backup_mysql/
Once backup is finished (it took about 17 seconds for a 300Mb DB entirely fitting memory), you have a timestamped directory in /opt/backup_mysql/. You can use it as a new datadir to test your backup simply starting a new mysql instance.
UPDATE: latest innobackupex releases require you to APPLY redo logs to the datafiles. This is done in two steps
Apply redo logs:
# innobackupex --apply-log /opt/backup_mysql/2012-06-12_19-22-54/
Check innobackupex output
120612 19:22:57 innobackupex: completed OK!
REMEMBER: ALWAYS CHECK THAT YOUR BACKUP IS CONSISTENT! Unless you are sure to be able to recover the data your backup is not done ;)
To improve isolation you could even start this backup instance with another user, using eg. –user=backup. So, check backup permissions:
# chown -R backup.backup ~backup
Change user:
# su - backup
Start our server
$ /usr/bin/mysqld --datadir=/opt/backup_mysql/2012-06-12_19-22-54/ \
--socket=/opt/backup_mysql/backup_mysql.sock \
--skip-networking
This new instance won’t listen on any port (–skip-networking) but only on your backup_mysql.sock, so that it won’t interfere with existing instances.
Now we can check if our backup is fine, running mysql and issuing some queries:
# mysql --socket=/opt/backup_mysql/backup_mysql.sock -uroot -p > show databases \G *************************** 1. row *************************** Database: employees > use employees; > show table status \G ... a lot of table informations ... mysql> select count(salary) from salaries; +---------------+ | count(salary) | +---------------+ | 2844047 | +---------------+ 1 row in set (4.55 sec) mysql> select sum(salary) as HR_Budget from salaries; +--------------+ | HR_Budget | +--------------+ | 181480757419 | +--------------+ 1 row in set (0.83 sec) > select sum(salary) as HR_Budget from salaries;