Thingy Ma Jig is the blog of Nicholas Thompson and contains any useful tips, sites and general blog-stuff which are considered interesting or handy!
Posted on 27 April 2009 in
tip
linux
How to
geek
Drupal
code
bash
Back in November last year, I wrote a script which handled backing up a drupal database. There were quite a few comments and I've taken some on board and developed the script on a little further to be more "generic".
One of the main complaints/suggestions about my previous snippet was the hard coded nature of it. The follow script offers far more configuration through the command line itself.
#!/bin/bash # Define the options for this command OPTION_SPEC="help,database:,file:,user:,password:,exclude:,exclude-drupal-tables,prefix:" PARSED_OPTIONS=$(getopt -n "$0" -a -o h --long $OPTION_SPEC -- "$@") OPTIONS_RET=$? eval set -- "$PARSED_OPTIONS" # Define an array of tables to be exluded DBEXCLUDE=( ) # Define an array of table prefixes DBPREFIX=( ) # Define a usage help function usage() { cat <<HELP Usage: `basename $0` --database=DATABASE_NAME [OPTIONS] Options: --database=DATABASE_NAME -d DATABASE_NAME Database to dump --file=FILENAME -f FILENAME Filename you to dump the database to, defaults to DATABASE.sql --user=USERNAME -u USERNAME Username for accessing the database, defaults to the user running the script --password=PASSWORD -p PASSWORD Password for accessing the database, defaults to blank --exclude=TABLE_NAME -e TABLE_NAME Name of a table to exclude from the full dump (will do structure only). Multiple excludes can be passed --exclude-drupal-tables Enables a preset of tables which hold temporary/cached data which do not need dumping --prefix=PREFIX -pr PREFIX Optional table prefix. Eg, you might want to exclude a table called "cache" and this table might appear several times with different prefixes Example: drupaldump -d my_database -u joe_bloggs --password=myPassw0rd --file=dump.sql -e cache -e stats -e logs --prefix=foo -pr bar HELP } # Some kind of test on the options... if [ $OPTIONS_RET -ne 0 ] || [ $# -le 0 ]; then usage; exit 1; fi # Loop over all the options and pull out settings for the database, user, password, etc while [ $# -ge 1 ]; do case $1 in --help | -h ) usage; exit 1;; --database | -d ) shift; DB="$1";; --file | -f ) shift; DBFILE="$1";; --user | -u ) shift; DBUSER="$1";; --password | -p ) shift; DBPASS="$1";; --exclude | -e ) shift; DBEXCLUDE[${#DBEXCLUDE[*]}]="$1";; --exclude-drupal-tables | -edt ) DBEXCLUDE=( "${DBEXCLUDE[@]}" accesslog watchdog sessions cache\(_.+\)? search_\(.+\) devel_\(.+\) );; --prefix | -pf ) shift; DBPREFIX[${#DBPREFIX[*]}]="$1";; -- ) shift;; * ) echo "ERROR: unknown flag $1"; usage; exit 1;; esac shift done # Get the database from the commandline if [ ! -n "$DB" ] then # Print an error & usage suggestion echo "`basename $0`: Missing database" usage; exit 1 fi # If the database isn't already set, then set it... if [ ! -n "$DBFILE" ] then # Define the start time - this is used as a filename stub START_TIME=$(date +%Y%m%d%H%M); # Define a default DB File DBFILE="${START_TIME}-${DB}.sql" fi # Create an empty file in that place > $DBFILE # Define the username, if it's not already set if [ ! -n "$DBUSER" ] then DBUSER="" else DBUSER="--user=${DBUSER}" fi # Define the password, if it's not already set if [ ! -n "$DBPASS" ] then DBPASS="" else DBPASS="--password=${DBPASS}" fi # Define the default 'structure only' tables DBEXCLUDE_TABLES="" ELEMENT_COUNT=${#DBEXCLUDE[@]} if [ "$ELEMENT_COUNT" -gt 0 ] then INDEX=0 while [ "$INDEX" -lt "$ELEMENT_COUNT" ] do DBEXCLUDE_TABLES="${DBEXCLUDE_TABLES}|${DBEXCLUDE[$INDEX]}" let "INDEX = $INDEX + 1" done DBEXCLUDE_TABLES="(${DBEXCLUDE_TABLES:1})" fi # Define the structure only optional table prefixes DBPREFIX_TABLES="" ELEMENT_COUNT=${#DBPREFIX[@]} if [ "$ELEMENT_COUNT" -gt 0 ] then INDEX=0 while [ "$INDEX" -lt "$ELEMENT_COUNT" ] do DBPREFIX_TABLES="${DBPREFIX_TABLES}|${DBPREFIX[$INDEX]}" let "INDEX = $INDEX + 1" done DBPREFIX_TABLES="(${DBPREFIX_TABLES:1})?" fi # Define the structure only regex STRUCTURE_ONLY="/^${DBPREFIX_TABLES}${DBEXCLUDE_TABLES}$/" # Get the tables from the database TABLES=`mysql ${DBUSER} ${DBPASS} --batch --skip-column-names -e 'show tables;' ${DB}` if [[ $? > 0 ]] then echo "Exiting for some kind of error... $?" exit 1 fi # Status message echo " Starting dump of ${DB}" # Loop over the tables for T in $TABLES; do # Test if the table matches the 'structure only' regex RESULT=`echo "$T" | gawk "$STRUCTURE_ONLY"` # if a match... if [ $RESULT ] then echo " STRUCTURE : ${T}" NODATA="--no-data" else echo " FULL : ${T}" NODATA="" fi # Dump the table onto the end of the DBFILE with the data or no data option mysqldump ${DBUSER} ${DBPASS} --opt --skip-comments ${NODATA} ${DB} ${T} >> $DBFILE done # Finish Message echo " Done" exit 0
Essentially this is the same script as in my previous post, however I've added functionality to provide a custom username, password, database, file, exclude (structure only) and optional-table-prefix...
Comments & suggestions welcome :)
Oh - one final thing… You can find the file for download in my Drupal Sandbox…
http://cvs.drupal.org/viewvc.py/drupal/contributions/sandbox/nicholasThompson/drupaldump/