Drupal DB backup bash script with Drush and Git

I like to make incremental backups of my drupal databases. To do that I’ve tried combine the best practices* into one bash script that I can run periodically and easily.
The end result is a bash function that’s easy and user friendly.
It works by leveraging Drush aliases and the drush sql-dump command in combination with git.

Usage is simple. From the command line:

$ dg_db_backup drush.alias "commit message" 

Note: dg_db_backup -> drush git database backup

The commit message is optional. The drush alias is not.
There are some prerequisites. You do have to define a drush alias with a site var: %site and an sql dump directory: var: %dump. You also need to create a separate git repo for your drupal db backups.
The advantage of using the %dump var is that the dump directory can be outside your drupal site.

Now if you tend to back up the same site often you can create an alias to reduce the required typing:
I use “d7backdb”
Here’s the code I keep in my .bash_alias file:

alias d7backdb='dg_db_backup d7.test.local '

Here’s the script code (placed in my .bashrc file).

#—————————————-
#Directory Functions
#—————————————-
function currentDir(){
SOURCE=”$1″
while [ -h “$SOURCE” ] ; do SOURCE=”$(readlink “$SOURCE”)”; done
DIR=”$( cd -P “$( dirname “$SOURCE” )” && pwd )”
echo $DIR
}

#—————————————-
#Drush Backup Functions
#—————————————-
function drushbackdb(){ #drush backup db. Usage: drushbackdb drush.alias
#if the first var is blank
if [[ ! -n “$1” ]] ; then
echo -e “n#drush db backup. Usage: drushbackdb drush.alias”;
else
local drush_alias=”$1″
cd `drush dd @$drush_alias:%site`;
drush @$drush_alias sql-dump –ordered-dump –structure-tables-key=common –no-cache –result-file=`drush dd @$drush_alias:%dump`;
fi # end if [[ ! -n “$1” ]]
}

function gitbackdb() { #git add and commit db backup. Usage: gitbackdb drush.alias “commit message”
#if the first var is blank
if [[ ! -n “$1” ]] ; then
echo -e “n#git add and commit db backup. Usage: gitbackdb drush.alias “commit message””;
else
local drush_alias=”$1″;
#if 2nd var is blank
if [[ ! -n “$2″ ]] ; then
local git_commit_msg=”auto-commit of DB Dump”;
else
local git_commit_msg=”$2″;
fi #end if [[ ! -n “$2″ ]]

cd `drush dd @$drush_alias:%dumpdir`;
git add `drush dd @$drush_alias:%dump`;
git commit -am”$git_commit_msg”;
echo “#BackupedDB. Use to restore: `drush @$drush_alias sql-connect` < `drush dd @$drush_alias:%dump`.
#To push your commit use: cd `drush dd @$drush_alias:%dumpdir`; git push orign master; cd -";
fi # end if [[ ! -n "$1" ]]
}

function dg_db_backup(){ #drush git db backup. Usage: dg_db_backup drush.alias "commit message"
#if the first var is blank
if [[ ! -n "$1" ]] ; then
echo -e "n#drush git db backup. Usage: dg_db_backup drush.alias "commit message"";
else
local drush_alias="$1";
local git_commit_msg="$2";
#capture current dir so in order to return the user back to where they called the command
#Relies on currentDir function
local currentDir=`currentDir`;

#backup db
drushbackdb $drush_alias;
#commit backup
gitbackdb $drush_alias "$git_commit_msg";

#cd `drush dd @$drush_alias:%site`;
cd $currentDir;
fi # end if [[ ! -n "$1" ]]
}

If add this to your .bashrc file don’t forget to reload the file:

$ source ~/.bashrc

Commentary:

You’ll notice that there’s 4 functions in that script.
The one I use most is the last: dg_db_backup() which calls the other three:

  • currentDir()
  • drushbackdb()
  • gitbackdb()

Some code I learned recently that was helpful in writing this

‘cd -‘: This returns you to your last directory. Thank Paul!

$ cd -

‘drush dd’: This displays the directory. Surrounding that with back ticks ‘`’ lets you use the result. i.e.

cd `drush dd @myDrush.alias:%site`;

‘if [[ ! -n “$1” ]] ; then …’: this code snippet checks if your var is blank.

Good stuff.

Otherwise I think the code includes some comments so it may be self-explanatory. Leave me a comment if you disagree and I’ll break it down.

Example

Here’s an example of usage to back up my local dev site with a drush alias of ‘@d7.test.local’. Note: I don’t include the @ symbol in the function. The code could be changed to accommodate that I suppose.
$ dg_db_backup d7.test.local “testing backup 9”
Database dump saved to /BACKUP/PATH/backups/d7.mytestsite.com_backup/d7.mytestsite.com_test_drpl7.sql [success]
[master 5859782] testing backup 9
1 file changed, 3 insertions(+), 3 deletions(-)
#BackupedDB. Use to restore: `drush @d7.test.local sql-connect` < `drush dd @d7.test.local:%dump`.
#To push your commit use: cd `drush dd @d7.test.local:%dumpdir`; git push orign master; cd –
$
Since I have an bash alias for backing up this site frequently I could have also called:

d7backdb "testing backup 9"

Notes

*Note: one of the best practices I used as a resource can be found here: home.chrishunters.com/blogs

Future development

I expect that this script will evolve. Suggestions are welcome.

  • It may be nice to make this more consistent with normal drush usage. That is; when you call a drush command without an alias drush expects to be inside a directory of drush compatible site. At which point aliases aren’t needed. It may be handy to make the drush aliases in this script optional.
  • In addition, it may be useful to verify that the drush %dump var exists prior to running the script.

I’ll post updates here.

Leave a Comment