#!/bin/sh # Copyright (C) 2005-2007 Krzysztof Kozlowski # License: GNU General Public License version 2 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # version 2 as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # # http://www.kozik.net.pl # # Ostatnia zmiana: 24.07.2007 # Wersja: 1.1.2 # # Backup baz MySQL # # Wywolanie - nie ma argumentow. Skrypt tworzy backup wybranych baz danych # do danego katalogu. Sam dba o autonumeracje kolejnych plikow kopii zapasowej # i sam kasuje bardzo stare kopie. # # Backup wykonuje mysqldump, czyli efekt ma postac komend SQL spakowane BZIP2. # Wczesniejsze wersje skryptu robily kopie zapasowe (paczki TAR.BZ2) # czystych plikow MySQL-a, ale: # - nie bylo to szybsze # - pozostawialo watpliwosci co do poprawnosci tworzonych backupow # (problem synchronizacji plikow fizycznych ze stanem bazy) # - tworzone pliki byly wieksze # ############################################# # ZMIENNE : # # Bazy danych do backupu, oddziel spacjami : DB_NAMES="" # Lub wszystkie (0/1) DB_ALL=1 # Katalog, gdzie zostana umieszczone pliki kopii zapasowych BCK_DIR="/var/backups/mysql" # Haslo i user MySQL roota SQL_PASS="" SQL_USER="" # Sciezki do uzywanych programow. Powinien sam wykryc, jesli nie wykryje, to uzyje tych wpisanych. PACKER="$(which bzip2 2> /dev/null || echo '/usr/bin/bzip2') -9" MYSQL_DUMP="$(which mysqldump 2> /dev/null || echo '/usr/local/bin/mysqldump')" MYSQL_ADMIN="$(which mysqladmin 2> /dev/null || echo '/usr/local/bin/mysqladmin')" # Trzymaj wszystkie z ostatnich $KEEP_ALL backupow : KEEP_ALL=30 # ############################################# # FUNKCJE : # # --------------------------------------------- # Tworzy katalog backupu dla danej bazy # Wywolanie: # create_dir katalog_wyjsciowy create_dir() { DIR="$1" if [ ! -d "$1" ]; then /bin/mkdir "$1" /bin/chmod 700 "$1" fi } # --------------------------------------------- # --------------------------------------------- # Odczytuje katalog z kopiami zapasowymi i zwraca kolejna liczbe dla pliku backupu # Wywolanie # get_max_nr katalog_wyjsciowy nazwa_bazy sufix_spakowany get_max_nr() { dir=$1 name=$2 sufix=$3 oldies=`/bin/ls ${dir}/${name}.*.${sufix} 2> /dev/null | /usr/bin/cut -f 2 -d '.'` max=0 for i in $oldies ; do if [ $i -gt $max ]; then max=$i fi done max=`expr $max + 1` echo $max } # --------------------------------------------- # --------------------------------------------- # Kasowanie bardzo starych baz # Wywolanie: # delete_old_bcks katalog nazwa_bazy sufix_spakowany ostatnia ile_kopii_trzymac delete_old_bcks() { dir=$1 name=$2 sufix=$3 max=`get_max_nr "${dir}" "${name}" "${sufix}"` keep_nr=`expr ${max} - $4 - 1` if [ -f "${dir}/${name}.${keep_nr}.${sufix}" ]; then find ${dir} -name "${name}.*.${sufix}" -maxdepth 1 ! -newer "${dir}/${name}.${keep_nr}.${sufix}" -delete fi } # --------------------------------------------- # --------------------------------------------- # Przygotowanie do backupu # Wywolanie : # prepare4backup output_dir db_name # [db_name] - nazwa bazy lub puste dla "all" # Wypluwa - wolna nazwe pliku SQL prepare4backup() { output_dir=$1 db_name=$2 if [ "${db_name}" == "" ]; then db_name="all" fi create_dir "${output_dir}" max=`get_max_nr "${output_dir}" "${db_name}" bz2` /usr/bin/mysqladmin -u $SQL_USER --password=${SQL_PASS} flush-hosts flush-logs flush-status flush-tables flush-threads if [ $? -ne 0 ]; then echo "Blad podczas flushowania baz !" exit 3 fi echo "${db_name}.${max}.sql" } # --------------------------------------------- # --------------------------------------------- # Cialo : if [ $DB_ALL -eq 1 ]; then # Backup wszystkich baz echo "Backuping all databases..." # Przygotowanie OUTPUT_DIR="${BCK_DIR}/all" OUT_FILE=`prepare4backup "${OUTPUT_DIR}"` # Wyciaganie z bazy MySQL echo "New all backup as $OUT_FILE" /usr/bin/mysqldump -u $SQL_USER --password=${SQL_PASS} --flush-logs --opt -O net_buffer_length=1 --all-databases > "${OUTPUT_DIR}/${OUT_FILE}" if [ $? -ne 0 ]; then echo "Blad podczas zrzutu baz do pliku $OUT_FILE !" exit 3 fi # Koncowe pakowanie $PACKER "${OUTPUT_DIR}/${OUT_FILE}" delete_old_bcks "${OUTPUT_DIR}" "all" "sql.bz2" $KEEP_ALL if [ $? -ne 0 ]; then echo "Blad podczas czysczenia starych backupow all !" exit 3 fi else for i in $DB_NAMES ; do echo "Backuping $i..." # Przygotowanie OUTPUT_DIR="${BCK_DIR}/${i}" OUT_FILE=`prepare4backup "${OUTPUT_DIR}" ${i}` # Wyciaganie z bazy MySQL # net_buffer_length jest po to, aby nie byly tworzone ogromne linie # zawierajace calego INSERT-a. echo "New $i backup as $OUT_FILE" $MYSQL_DUMP -u $SQL_USER --password=${SQL_PASS} --flush-logs --opt -O net_buffer_length=1 "$i" > "${BCK_DIR}/${i}/${OUT_FILE}" if [ $? -ne 0 ]; then echo "Blad podczas zrzutu bazy $i do pliku $OUT_FILE !" exit 3 fi # Koncowe pakowanie $PACKER "${BCK_DIR}/${i}/${OUT_FILE}" delete_old_bcks "${BCK_DIR}/${i}" "${i}" "sql.bz2" $KEEP_ALL if [ $? -ne 0 ]; then echo "Blad podczas czysczenia starych backupow $i !" exit 3 fi done fi exit 0