Oct 302008
 

With all the databases I run, I need a daily sanity check. I download a copy of each database and do a test load on my system at home. Today I timed that process:

$ time ~/bin/backup-supernews.sh

real 77m57.323s
user 12m52.610s
sys 0m56.136s

There are 11 such databases. The dump files range in size from 5K (globals.sql) to 2.8G (freshports.sql).

The script that does this is pretty simple, but has evolved over the years.

#!/bin/sh
#
# This file does a backup of each database on the nyi server.
# It relies upon a file on nyi to do the actual backup,
# then uses rsync to copy the files from nyi to here.
#

BACKUPDIR=${HOME}/backups/supernews/database-backup

IDENTITY_FILE=${HOME}/.ssh/id_dsa_no_passphrase
SERVER_TO_BACKUP=supernews.example.org

cd ${BACKUPDIR}/postgresql

YYYYMMDD=`eval date "+%Y.%m.%d"`
echo will tar things up into ${YYYYMMDD} format

FILES=`echo *.sql`
echo will be processing ${FILES}
# maybe there are no such files
if [ "x${FILES}" != 'x\*.sql' ]
then
   for i in $FILES
   do
#      mv ${i} archive
      tar -cvzf archive/`basename ${i} .sql`.${YYYYMMDD}.sql.tgz ${i}
   done
else
   echo no files found for processing
fi


cd ${BACKUPDIR}/mysql
FILES=`echo *.sql`

# maybe there are no such files
if [ "x${FILES}" != 'x\*.sql' ]
then
   for i in $FILES
   do
#      mv ${i} archive
      tar -cvzf archive/`basename ${i} .sql`.${YYYYMMDD}.sql.tgz ${i}
   done
fi

cd ${BACKUPDIR}


#
# dump the databases on the remote server
#
logger "dumping the databases on ${SERVER_TO_BACKUP} from `hostname`"
ssh -i ${IDENTITY_FILE} dan@${SERVER_TO_BACKUP} ~dan/bin/backup.sh

#
# use rsync to get local copies
#
/usr/local/bin/rsync -e "ssh -i ${IDENTITY_FILE}" --recursive -avz --stats --progress \
--exclude 'archive' dan@${SERVER_TO_BACKUP}:~/database-backup/ ${BACKUPDIR}

#
# now do a test of the backups to ensure they actually restore

~/bin/test-backups.sh ${BACKUPDIR}

That is the job that archives the old files and downloads the new ones.

The following script loads up that database and is referred to in the last line of the above script:

#!/bin/sh
#
# test the files we've recovered
#

BACKUPDIR=$1
GLOBALS="globals"

PSQL=/usr/local/bin/psql
CREATEDB=/usr/local/bin/createdb
DROPDB=/usr/local/bin/dropdb

cd ${BACKUPDIR}/postgresql

echo dropping test databases
FILES=`echo *.sql`
for i in $FILES
do
        DBNAME=`basename $i .sql`
        if [ ${DBNAME} != ${GLOBALS} ]
        then
                ${DROPDB} ${DBNAME}_test
        fi
done

echo loading GLOBALS
if [ -r "${GLOBALS}.sql" ]
then
        ${PSQL} postgres < ${GLOBALS}.sql
fi

echo creating the databases
for i in $FILES
do
        DBNAME=`basename $i .sql`
        if [ ${DBNAME} != ${GLOBALS} ]
        then
                ${CREATEDB} ${DBNAME}_test -E SQL_ASCII
                ${PSQL}     --quiet ${DBNAME}_test < ${DBNAME}.sql
        fi
done

The final part of the puzzle is the script run on the production server which dumps all the databases required:

#!/bin/sh

PGDUMP=/usr/local/bin/pg_dump
MYSQLDUMP=/usr/local/bin/mysqldump
BACKUPROOT=${HOME}/database-backup

cd ${BACKUPROOT}/postgresql

DATABASES="bsdcert fpphorum freshports.org fsphorum openx nagios \
pentabarf pentabarf_bsdcan pentabarf_pgcon postgres"
for database in ${DATABASES}
do
        echo dumping $database
        if [ -f ${database}.sql ]
        then
                mv ${database}.sql archive
        fi

        ${PGDUMP} ${database} > ${database}.sql

        if [ $? -ne 0 ]
        then
                echo backup of ${database} failed
        fi

done

#
# Now dump the globals
#

if [ -f globals.sql ]
then
        mv globals.sql archive
fi

/usr/local/bin/pg_dumpall -g  > globals.sql

if [ $? -ne 0 ]
then
        echo backup of globals failed
fi



DATABASES="cacti mysql"
cd ${BACKUPROOT}/mysql

for database in ${DATABASES}
do
    echo dumping $database
    if [ -f ${database}.sql ]
    then
        mv ${database}.sql archive
    fi
    ${MYSQLDUMP} -u root ${database} > ${database}.sql
    if [ $? -ne 0 ]
    then
       echo backup of ${database} failed
    fi
done

Any questions? :)

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive