Sida 1 av 1

revidering av backup-script: mysql

Postat: 16 mar 2011, 17:30
av Barre
Tjenis alla bashare.

Har knackat ihop ett litet script för att dumpa alla mysql databaser och tänkte hör med er om åsikter, revidering och dubbelkoll på att jag tänkt optimalt.

Jag har en maskin som tar backup med hjälp av rdiff-backup varje natt, den tar blandannat backup på /var/backups/mysql/current_* på min MySQL server.
På MySQL-servern så körs en dump på samtliga databaser och skapar samtidigt en hard link till current_<db-name>.tar.gz.

Kod: Markera allt

#!/bin/bash

DATE_PREFIX=$(date +%G-%m-%d)

MYSQL_USER="root"
MYSQL_PWD="secret"


BACKUP_DIR="/var/backups/mysql"

GZIP="/bin/gzip"
MYSQLDUMP="/usr/bin/mysqldump"
MYSQLCLIENT="/usr/bin/mysql"
FIND="/usr/bin/find"

DAYS_TO_KEEP_OLD_BACKUPS="4"  #how many days should you keep the old backups

#remove old backups
$FIND $BACKUP_DIR -maxdepth 0 -mtime +$DAYS_TO_KEEP_OLD_BACKUPS -exec rm -f {} \;

# get a list of databases
DBLIST=$( ${MYSQLCLIENT} --skip-column-names --batch --user=$MYSQL_USER --password=$MYSQL_PWD  --execute="SHOW DATABASES;" )

#dump databases in seperate files an gzip them

umask 027
cd $BACKUP_DIR || exit 1

for db in $DBLIST; do
    SKIP_LOCK=""
    [ "$db" == "information_schema" ] && SKIP_LOCK="--skip-lock-tables"
    DUMP_FILE_NAME="${DATE_PREFIX}_${db}.tar.gz"
    $MYSQLDUMP --force --opt $SKIP_LOCK --user=$MYSQL_USER --password=$MYSQL_PWD --databases $db | \
         $GZIP > $DUMP_FILE_NAME
    [ -f current_${db}.tar.gz ] && rm current_${db}.tar.gz
    ln $DUMP_FILE_NAME current_${db}.tar.gz
done
nu hade jag tänkt kolla med er om jag missat någon sanity-check eller gjort något klumpigt i mitt sciptande, jag vet att det finns många extremt bra kodare här som säkert kan komma med någon bra input.

Tack på förhand.

p.s. jag funderar på att lägga in en "exclude databas list", men har inte det behovet ännu, så jag sket i det :)

p.p.s funderar på om inte borttagningen av gamla backupper är onödigt riskabelt? den kontrollerar ju inte filtyp eller filnamn, eller är jag onödigt paranoid?

//Barre

Re: revidering av backup-script: mysql

Postat: 16 mar 2011, 20:13
av Konservburk
Har du tänkt på vad som händer om mysqldump av en eller annan anledning misslyckas? Om den t.ex. inte kan ansluta till mysql-daemonen för att den i sin tur är nere (eller något i den stilen).

Som det ser ut nu så finns risken att du får en backup-fil som är helt tom. Om jag var du så skulle jag se till så att det bara blir en ny backup-fil om mysqldump faktiskt lyckas.

Sen har vi det här med borttagning av gamla backup-filer. Jag tycker det verkar lite riskabelt att helt förlita sig på tiden. Tänk om klockan av någon anledning inte stämmer. Eller om det inte blivit någon lyckad backup de senaste X dagarna. Jag skulle nog i första hand gå efter antalet filer, så att de X antal senaste backup-filerna alltid får vara kvar. Eller ännu hellre att både de X antal senaste backup-filerna och backup-filer som är yngre än Y antal dagar får vara kvar.

Slutligen ett litet skönhetsfel. Varför låter du backup-filerna få filändelsen .tar.gz trots att tar inte är det minsta inblandat?

Finns det förresten någon speciell anledning till att du kör med absoluta sökvägar för gzip, mysqldump, msql och find, men inte när det gäller rm och ln?

Re: revidering av backup-script: mysql

Postat: 16 mar 2011, 21:33
av Barre
Grymt, tack för feedback!
Konservburk skrev:Har du tänkt på vad som händer om mysqldump av en eller annan anledning misslyckas? Om den t.ex. inte kan ansluta till mysql-daemonen för att den i sin tur är nere (eller något i den stilen).

Som det ser ut nu så finns risken att du får en backup-fil som är helt tom. Om jag var du så skulle jag se till så att det bara blir en ny backup-fil om mysqldump faktiskt lyckas.
Ändrat så att mysqldump görs mot en tmp-fil istället och flyttas/länkas om mysqldump genomfördes utan fel
Konservburk skrev: Sen har vi det här med borttagning av gamla backup-filer. Jag tycker det verkar lite riskabelt att helt förlita sig på tiden. Tänk om klockan av någon anledning inte stämmer. Eller om det inte blivit någon lyckad backup de senaste X dagarna. Jag skulle nog i första hand gå efter antalet filer, så att de X antal senaste backup-filerna alltid får vara kvar. Eller ännu hellre att både de X antal senaste backup-filerna och backup-filer som är yngre än Y antal dagar får vara kvar.
Anledningen till att de får ligga kvar är av lättja för att slippa kopiera över eventuell backup från backup-servern, historiken finns i rdiff-backup på enannan server som tar varje natt på current_ filerna (om de ändrats d.v.s)
Konservburk skrev: Slutligen ett litet skönhetsfel. Varför låter du backup-filerna få filändelsen .tar.gz trots att tar inte är det minsta inblandat?
Här skrev fingrarna av sig själv av bara farten, det skall givetvis vara sql.gz och inte tar.gz :)
Konservburk skrev: Finns det förresten någon speciell anledning till att du kör med absoluta sökvägar för gzip, mysqldump, msql och find, men inte när det gäller rm och ln?
Nej, jag vet faktiskt inte varför jag körde med absoluta sökvägar alls, de är borttagna nu.

jag la dessutom till en test på att mysql klienten är installerad (hade glömt det på servern jag testate med :))

Kod: Markera allt

#!/bin/bash

DATE_PREFIX=$(date +%G-%m-%d)

MYSQL_USER="root"
MYSQL_PWD="secret"

BACKUP_DIR="/var/backups/mysql"
DAYS_TO_KEEP_OLD_BACKUPS="4"  #how many days should you keep the old backups

type -P mysql &>/dev/null || { echo "mysql client not found!" >&2; exit 1; }
type -P mysqldump &>/dev/null || { echo "mysqldump not found!" >&2; exit 1; }

#remove old backups
find $BACKUP_DIR -maxdepth 0 -mtime +$DAYS_TO_KEEP_OLD_BACKUPS -exec rm -f {} \;

# get a list of databases
DBLIST=$( mysql --skip-column-names --batch --user=$MYSQL_USER --password=$MYSQL_PWD  --execute="SHOW DATABASES;" ) 
[ $? -ne 0 ] && exit 1


#dump databases in seperate files an gzip them
umask 077
cd $BACKUP_DIR || exit 1
WORKINGFILE=$(tempfile -d /var/backups/mysql)

for db in $DBLIST; do
    SKIP_LOCK=""
    [ "$db" == "information_schema" ] && SKIP_LOCK="--skip-lock-tables"
    DUMP_FILE_NAME="${DATE_PREFIX}_${db}.sql.gz"
    mysqldump --force --opt $SKIP_LOCK --user=$MYSQL_USER --password=$MYSQL_PWD --databases $db | \
         gzip -c > $WORKINGFILE
    if [ ${PIPESTATUS[0]} -eq 0 ]; then
        mv $WORKINGFILE $DUMP_FILE_NAME
        [ -f current_${db}.sql.gz ] && rm current_${db}.sql.gz
        ln $DUMP_FILE_NAME current_${db}.sql.gz
    fi
done
[ -f $WORKINGFILE ] && rm $WORKINGFILE
Det borde väl räcka för kontroll? eventuella fel körs ju ut på stderr och mailas via cron.

Re: revidering av backup-script: mysql

Postat: 16 mar 2011, 22:08
av Konservburk
Jag tycker det ser helt ok ut nu. :)

Re: revidering av backup-script: mysql

Postat: 17 mar 2011, 07:24
av Barre
Tack för hjälpen Konverburk!


såg dock att jag klantade mig när jag skapade det temporära filnamnet, och inte använde variabeln med backup pathen.

så för referens om någon använder detta så har jag ändrat

Kod: Markera allt

WORKINGFILE=$(tempfile -d /var/backups/mysql)
till

Kod: Markera allt

WORKINGFILE=$(tempfile -d $BACKUP_DIR)