Проверяем целостность бэкапов MySQL

28 Ноя
2011

В этом топике я хочу рассказать вам о том, как проверить бэкапы MySQL баз данных, снятых с помощью утилиты mysqldump.

В один прекрасный день, я не смог поднять базу с бэкапа, благо, что это было не критично и в итоге, встала задача, что их нужно как-то проверять на целостность.

Бэкапы снимал с помощью AutoMySQLBackup скрипта.

Как снимаются бэкапы


Скрипт я чуточку дописал. Патч на automysqlbackup.sh:

--- prod/automysqlbackup 2011-11-15 11:20:12.193119699 +0600
+++ dev/automysqlbackup 2011-11-18 15:43:49.797113371 +0600
@@ -89,6 +89,14 @@
# For connections to localhost. Sometimes the Unix socket file must be specified.
SOCKET=

+# Logs
+MDERR=/var/log/mysqldump.error
+MDLOG=/var/log/mysqldump.log
+MDALL=/var/log/mysqldumperr.log
+MD5LOG=/var/log/md5.log
+LATF=/var/log/latest-backup
+TMPFILE=$(mktemp /tmp/XXXXXX)
+CDATE=$(date +%F)
# Command to run before backups (uncomment to use)
#PREBACKUP="/etc/mysql-backup-pre"

@@ -406,7 +414,16 @@

# Database dump function
dbdump () {
-mysqldump --user=$USERNAME --password=$PASSWORD --host=$DBHOST $OPT $1 > $2
+mysqldump --user=$USERNAME --password=$PASSWORD --host=$DBHOST $OPT $1 > $2 2>$TMPFILE
+sed -i "s|^|\[$CDATE\] |" $TMPFILE
+cat $TMPFILE >> $MDALL
+cat /dev/null > $TMPFILE
+ret="$?"
+if [ "$ret" -ne "0" ]; then
+ echo "$1 NOT backuped at `date +%F` with exit status $ret">> $MDERR
+else
+ echo "$1 backuped SUCESSFULLY at `date +%F` with exit status $ret" >> $MDLOG
+fi
return 0
}

@@ -468,7 +485,7 @@

# If backing up all DBs on the server
if [ "$DBNAMES" = "all" ]; then
- DBNAMES="`mysql --user=$USERNAME --password=$PASSWORD --host=$DBHOST --batch --skip-column-names -e "show databases"| sed 's/ /%/g'`"
+ DBNAMES="`mysql --user=$USERNAME --password=$PASSWORD --host=$DBHOST --batch --skip-column-names -e "show databases"| sed 's/ /%/g'|grep -v -E '_schema|^mysql'`"

# If DBs are excluded
for exclude in $DBEXCLUDE
@@ -506,6 +523,8 @@
dbdump "$MDB" "$BACKUPDIR/monthly/$MDB/${MDB}_$DATE.$M.$MDB.sql"
compression "$BACKUPDIR/monthly/$MDB/${MDB}_$DATE.$M.$MDB.sql"
BACKUPFILES="$BACKUPFILES $BACKUPDIR/monthly/$MDB/${MDB}_$DATE.$M.$MDB.sql$SUFFIX"
+ echo `md5sum -b $BACKUPFILES` >> $MD5LOG
+ echo $BACKUPFILES >> $LATF
echo ----------------------------------------------------------------------
done
fi
@@ -542,6 +561,8 @@
dbdump "$DB" "$BACKUPDIR/weekly/$DB/${DB}_week.$W.$DATE.sql"
compression "$BACKUPDIR/weekly/$DB/${DB}_week.$W.$DATE.sql"
BACKUPFILES="$BACKUPFILES $BACKUPDIR/weekly/$DB/${DB}_week.$W.$DATE.sql$SUFFIX"
+ echo `md5sum -b $BACKUPFILES` >> $MD5LOG
+ echo $BACKUPFILES >> $LATF
echo ----------------------------------------------------------------------

# Daily Backup
@@ -553,6 +574,8 @@
dbdump "$DB" "$BACKUPDIR/daily/$DB/${DB}_$DATE.$DOW.sql"
compression "$BACKUPDIR/daily/$DB/${DB}_$DATE.$DOW.sql"
BACKUPFILES="$BACKUPFILES $BACKUPDIR/daily/$DB/${DB}_$DATE.$DOW.sql$SUFFIX"
+ echo `md5sum -b $BACKUPFILES` >> $MD5LOG
+ echo $BACKUPFILES >> $LATF
echo ----------------------------------------------------------------------
fi
done
@@ -569,6 +592,8 @@
dbdump "$MDBNAMES" "$BACKUPDIR/monthly/$DATE.$M.all-databases.sql"
compression "$BACKUPDIR/monthly/$DATE.$M.all-databases.sql"
BACKUPFILES="$BACKUPFILES $BACKUPDIR/monthly/$DATE.$M.all-databases.sql$SUFFIX"
+ echo `md5sum -b $BACKUPFILES` >> $MD5LOG
+ echo $BACKUPFILES >> $LATF
echo ----------------------------------------------------------------------
fi

@@ -589,6 +614,8 @@
dbdump "$DBNAMES" "$BACKUPDIR/weekly/week.$W.$DATE.sql"
compression "$BACKUPDIR/weekly/week.$W.$DATE.sql"
BACKUPFILES="$BACKUPFILES $BACKUPDIR/weekly/week.$W.$DATE.sql$SUFFIX"
+ echo `md5sum -b $BACKUPFILES` >> $MD5LOG
+ echo $BACKUPFILES >> $LATF
echo ----------------------------------------------------------------------

# Daily Backup
@@ -601,6 +628,8 @@
dbdump "$DBNAMES" "$BACKUPDIR/daily/$DATE.$DOW.sql"
compression "$BACKUPDIR/daily/$DATE.$DOW.sql"
BACKUPFILES="$BACKUPFILES $BACKUPDIR/daily/$DATE.$DOW.sql$SUFFIX"
+ echo `md5sum -b $BACKUPFILES` >> $MD5LOG
+ echo $BACKUPFILES >> $LATF
echo ----------------------------------------------------------------------
fi
echo Backup End Time `date`
@@ -685,6 +714,5 @@
# Clean up Logfile
eval rm -f "$LOGFILE"
eval rm -f "$LOGERR"
-
+eval rm -f "$TMPFILE"
exit $STATUS
-


Проверка целостности бэкапа


Всё. Теперь мы знаем имя файла с последним бэкапом, пишем лог ошибок mysqldump в формате «date +%F $ERROR» и снимаем md5-hash от файла бэкапа.

Так как бэкапы получаются сжатые gzip’ом, и вне сжатого бэкапа находится примерно такая строка:

-- MySQL dump 10.13 Distrib 5.5.16, for Linux (i686)


А в конце примерно такая:

-- Dump completed on 2011-11-15 17:22:16


то мы можем использовать zcat и проверять целостность примерно таким скриптом:

#!/bin/bash
CDATE=`date +%F`
LF=`cat /var/log/latest-backup| grep $CDATE`
LOG=/var/log/checker.log
BEGIN=`zcat $LF | grep ^'-- M' | wc -l`
END=`zcat $LF | grep ^'-- Dump c' | wc -l`
if [ "$BEGIN" == "1" ];then
if [ "$END" == "1" ];then
echo `date +%F-%H-%M` $LF is OK >> $LOG
else
echo `date +%F-%H-%M` $LF is corrupted >> $LOG
fi
else
echo `date +%F-%H-%M` $LF is corrupted >> $LOG
fi


Добавляем скрипты в крон, проверяем логи.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх