Q-Spot.org

IT-Stuff

Backup MySQL/MariaDB with Bacula/Bareos

Note:
In the following text, I call the software MySQL and Bacula, but this works with MariaDB and Bareos, too.

There are many ways to backup a MySQL or MariaDB server - most of them include some kind of "mysqldump to disk and backup that directory".

This works, but it would be nice if you could just pipe the backup to your backup server? You could save the disk space and reduce the time needed.

If you ask Google, you'll find some nice examples how to do this with Bacula and the bpipe plugin. But there is a little catch: Only one dumpfile will be created and backed up. If you have a server with more than one database, and chances are that you need to restore them independently (e.g. hosting multiple client databases), you are out of luck if you're looking for an easy solution.

But there is a way (with a little bash voodoo) - all you need are named pipes, zip (tar/cpio will not work!), mysqldump and a small bash script (debian variant):

#!/bin/bash
UMASK=`umask`
umask 0007
test -d /srv/backup/ || mkdir -p /srv/backup/
umask 0077

# get the database names
DBS=`echo "SHOW DATABASES" | mysql --defaults-extra-file=/etc/mysql/debian.cnf mysql | tail -n +2 | \
     grep -v "information_schema"| grep -v "performance_schema"| grep -v "ndbinfo"`
cd /srv/backup/

# create fifo files with mysqldump processes writing to them
DUMPS=""
for db in $DBS; do
    mkfifo $db.sql
    mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --ignore-table=mysql.event --single-transaction \
       -q -e -K "$db" > $db.sql &
    DUMPS="$DUMPS $db.sql"
done

# backup everything and pipe it to stdout
# don't forget the -q or you will get nasty stuff in the header of the file
zip -FI -q - $DUMPS | cat

# cleanup
for db in $DBS; do
    rm $db.sql
done

umask $UMASK

 

This script creates a named pipe for each database, with a mysqldump process piping the dump of the database to it. All you need to do now is to collect the data from the pipes in a zip file and send it to the backup tool. This will only work with zip because tar needs to know the size (we don't have one) before it adds the file to the archive.

The Bacula fileset can be defined like:

FileSet {.
  Name = "MySQLPipe".
  Include {
    Options {
      signature = MD5
      compression = gzip
    }
    Plugin = "bpipe:file=/MYSQL/mysql_dumps.zip:reader=sudo /etc/bareos/mysql-dump.sh:
              writer=/etc/bareos/mysql-restore.sh"
  }
}


As you can see, you need a second script to restore the backup on the client. Lets just put the backup somewhere:

#!/bin/bash
cat > /restore/mysql_dump.zip


If you look into the archive, you'll see the dumps as named pipe files with a size, but as soon as you extract them you'll have simple SQL dumps ready to restore your data.