仙台の山奥で自転車に乗ったり転んだり

愛車の GIOS でサイクリングしたりポタリングしたり、それをブログに記録してみたり。ロードバイクや自転車や坂のことを書いてみたり。ときたまプログラムのことを忘れないようにメモってみたり。

バックアップのスクリプト

汎用的なMySQLサーバのデータベースをバックアップスクリプトです。システムの仕様でバックアップはNASに保管するので、バックアップデータをマウントしたNFSに保存しています。
ついでにバックアップが必要になった時のケースや障害の内容などにあわせて、全データベースと各データベースのダンプをそれぞれ保存しています。用途を考慮すると2つのスクリプトに分割した方がいい気もしますが、運用が煩雑になりそうなので避けました。

cronでまわすのでエラーなどメッセージの出し方に迷いましたが、試しに logger コマンドを使って syslog に書き出してみてますが……、logger コマンドの使い方がよくわかってないです。

#!/bin/sh

set -e
set -u

MYSQLUSER="username"
MYSQLPASS="password"
MYSQLHOST="localhost"

BACKUPDIR=/mnt/nfs-backup-datastore
NFS_URI=backup:/var/nas/MySQL
SAVED_DAYS=10

TMPDIR=/tmp/mysql-backup.$$
trap "exit 1" HUP INT PIPE QUIT TERM
trap "rm -f ${TMPDIR}/*; rmdir ${TMPDIR}; rm -f ${BACKUPDIR}/lock" EXIT

mkdir -p $TMPDIR

SELFID=`id | sed -e 's/uid=//' -e 's/(.*//'`
if [ $SELFID -ne 0 ]; then
    # failed
    ERRMSG="You are not root, You cannot execute this script."
    logger -t mysqldump $ERRMSG
    echo $ERRMSG
    exit 100
fi

if [ -f "${BACKUPDIR}/lock" ]; then
    # failed
    ERRMSG="Data directory to be backup is not empty!"
    logger -t mysqldump $ERRMSG
    echo $ERRMSG
    exit 101
fi

DATABASES=`
    mysql \
         --skip-column-names \
         --batch \
         --host=${MYSQLHOST} \
         --user=${MYSQLUSER} \
         --password=${MYSQLPASS} \
         --execute='SHOW DATABASES;'
`
if [ $? -ne 0 ]; then
    # failed
    ERRMSG="Failed to listup the databases on the MySQL server"
    logger -t mysqldump $ERRMSG
    echo $ERRMSG
    exit 200
fi

TODAY=`date +%Y%m%d`

BACKUP=${TMPDIR}/all-databases.${TODAY}.dump.sql
mysqldump \
    --host=${MYSQLHOST} \
    --user=${MYSQLUSER} \
    --password=${MYSQLPASS} \
    --opt \
    --all-databases > $BACKUP
if [ $? -eq 0 ]; then
    logger -t mysqldump "Successful in the preparation of the all databases backup"
else
    ERRMSG="Failed in the preparation of the all databases backup"
    logger -t mysqldump $ERRMSG
    echo $ERRMSG
    exit 201
fi

for DBNAME in $DATABASES
do
    #if [ "x${DBNAME}" = "xmysql" ]; then
    #    continue
    #fi
    #if [ "x${DBNAME}" = "xinformation_schema" ]; then
    #    continue
    #fi
    BACKUP=${TMPDIR}/${DBNAME}.${TODAY}.dump.sql
    mysqldump \
        --host=${MYSQLHOST} \
        --user=${MYSQLUSER} \
        --password=${MYSQLPASS} \
        --opt \
        $DBNAME > $BACKUP
    if [ $? -eq 0 ]; then
        logger -t mysqldump "Successful in the preparation of the database backup: ${DBNAME}"
    else
        # warning
        logger -t mysqldump "Failed in the preparation of the database backup: ${DBNAME}"
    fi
done

if [ ! -d "${BACKUPDIR}/nas" ]; then
    mkdir -p ${BACKUPDIR}/nas
fi
(mount -t nfs -o rw ${NFS_URI} ${BACKUPDIR}/nas && touch ${BACKUPDIR}/lock)

mv ${TMPDIR}/*.${TODAY}.dump.sql ${BACKUPDIR}/nas/
find ${BACKUPDIR}/nas -type f -mtime  +${SAVED_DAYS} -print0 | xargs -0 rm -f

(umount -t nfs ${BACKUPDIR}/nas && rmdir ${BACKUPDIR}/nas)
(rm -f ${BACKUPDIR}/lock && rmdir $BACKUPDIR)

logger -t mysqldump "Backup of the database on MySQL server was completed"