Files @ 42155469350e
Branch filter:

Location: majic-scripts/database/mybackup.sh - annotation

branko
Noticket: Added a small script for creating quick backups of files before making changes to them.
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
ee91736e4686
#!/bin/bash
#
# mybackup.sh
#
# Copyright (C) 2010, Branko Majic <branko@majic.rs>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

program="mybackup.sh"
version="0.1"

function usage() {
    cat <<EOF
$program $version, a non-interactive utility for backing-up the MySQL datbase
with mysqldump.

Usage: $program -D dir [-c (bz2|gz)] [-M mail] [-t (e|w|a)] [-l logfile] [database[ database2...]]

$program is a non-interactive utility for backing-up the MySQL database using
the mysqldump utility. If no databases are specified, the utility will back-up
all the databases. Database backups are named in the pattern:

database.YYYYMMDD_HHmmSS[.gz|bz2]

YYYY stands for year, MM for month, DD for day, HH for hour, mm for minutes, and
SS for seconds. Compression suffix is added in case the compression was
requested. If the file by the same name already exists, it is not overwritten,
and a warning is issued.

User and password for the script must be specified using the \$HOME/.my.cnf
file. The user used for backup must have the select permissions for the
databases it will backup.

$program accepts the following options:

    -d dir      Directory where the backups should reside.
    -c (bz2|gz) Compress the MySQL database dumps using either bzip2 or gzip.
    -m mail     Mail the report about performed back-up to the specified e-mail
                address. (optional)
    -t level    Set the threshold for when sending mails. Supported thresholds
                are ERROR, WARN, or INFO.
    -l logfile  Log the activity in the specified log file. Default is
                /var/log/mybackup/mybackup.log.

    -v          show script version and licensing information
    -h          show usage help


Please report bugs and send feature requests to <branko@majic.rs>.
EOF
}

function version() {
        cat <<EOF
$program, version $version

+-----------------------------------------------------------------------+
| Copyright (C) 2010, Branko Majic <branko@majic.rs>                    |
|                                                                       |
| This program is free software: you can redistribute it and/or modify  |
| it under the terms of the GNU General Public License as published by  |
| the Free Software Foundation, either version 3 of the License, or     |
| (at your option) any later version.                                   |
|                                                                       |
| 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.                          |
|                                                                       |
| You should have received a copy of the GNU General Public License     |
| along with this program.  If not, see <http://www.gnu.org/licenses/>. |
+-----------------------------------------------------------------------+

EOF
}

#
# Helper function that generates a timestamp for the log. Current date is used
# for the timestmap.
#
# Outputs:
#     Current date in format 'YYYY-MM-DD HH:mm:SS'.
#
function timestamp() {
    date '+%Y-%m-%d %H:%M:%S'
}

#
# Helper function for logging the events. The events are logged into a file and
# into a variable "logCache". This variable can be used later on for sending
# mail notifications etc. Entries in logCache are generated taking the threshold
# into account.
#
# Arguments:
#     $1 - Event level, INFO, WARN, or ERROR.
#     $2 - Message which should be written to log.
#
function logMessage() {
    local level="$1"
    local message="$2"
    local logEntry

    if [[ $level == "INFO" || $level == "WARN" || $level == "ERROR" ]]; then
        logEntry="$(timestamp) $level $message"
        echo "$logEntry" >> "$logFile"
        if [[ $level == INFO && $mailThreshold == INFO ]]; then
            logCache[${#logCache[@]}]="$logEntry"
        elif [[ $level == WARN && ($mailThreshold == WARN || $mailThreshold == INFO) ]]; then
            logCache[${#logCache[@]}]="$logEntry"
        elif [[ $level == ERROR ]]; then
            logCache[${#logCache[@]}]="$logEntry"
        fi
    fi
}

# If no arguments were given, just show usage help.
if [[ -z $1 ]]; then
    usage
    exit 0
fi

# Setup static variables
dateFormat="+%Y%m%d_%H%M%S"

# Setup default argument values
mailThreshold="WARN"
logFile="/var/log/mybackup/mybackup.log"

# Parse the arguments
while getopts "d:c:m:t:l:vh" opt; do
    case "$opt" in
        d) backupDirectory="$OPTARG";;
        c) compression="$OPTARG";;
        m) mail="$OPTARG";;
        t) mailThreshold="$OPTARG";;
        l) logFile="$OPTARG";;
        v) version
           exit 0;;
        h) usage
           exit 0;;
        *) usage
           exit 1;;
    esac
done
i=$OPTIND
shift $(($i-1))

# Verify parameters
if [[ -z $backupDirectory ]]; then
    echo "No backup directory was supplied." >&2
    exit 2
fi
if [[ ($compression != "bz2" && $compression != "gz") && -n $compression ]]; then
    echo "Compression type '$compression' is not supported." >&2
    exit 3
fi
if [[ $mailThreshold != "INFO" && $mailThreshold != "WARN" && $mailThreshold != "ERROR" ]]; then
    echo "Unrecognised threshold '$mailThreshold'" >&2
    exit 3
fi

# Setup the compression command
if [[ $compression == "bz2" ]]; then
    compressionCommand="bzip2"
elif [[ $compression == "gz" ]]; then
    compressionCommand="gzip"
else
    compressionCommand="cat"
fi

# Retrieve a list of all the databases provided at the command line
databases=()
while [[ -n $1 ]]; do
    databases=(${databases[@]} $1)
    shift
done

# If no databases were specified, back-up all the MySQL databases
if [[ ${#databases[@]} == 0 ]]; then
    if ! databases=($(mysql --batch --skip-column-names -e 'SHOW DATABASES')); then
        logMessage ERROR "Could not retrieve the list of databases. Aborting backup."
        exit 4
    fi
fi

# Add a dot to the compression so it's easier to build-up extensions
if [[ -n $compression ]]; then
    compression=".$compression"
fi

# Create the backup directory if it doesn't exist
mkdir -p "$backupDirectory"

logMessage INFO "Starting the back-up of databases to $backupDirectory"

for db in ${databases[@]}; do
    outputFile="$db.$(date $dateFormat)${compression:-}"
    if [[ -e $outputFile ]]; then
        logMessage WARN "File already exists ($outputFile), skipping"
    else
        logMessage INFO "Starting the back-up of database $db"
        mysqldump --single-transaction "$db" | "$compressionCommand" > "$backupDirectory/$outputFile"
        exitCodes=(${PIPESTATUS[@]})
        if [[ ${exitCodes[0]} != 0 ]]; then
            logMessage ERROR "Failed to back-up $db. Command 'mysqldump' exited with error code ${exitCodes[0]}"
        fi
        if [[ ${exitCodes[1]} != 0 ]]; then
            logMessage ERROR "Failed to back-up $db. Compression command '$compressionCommand' exited with error code ${exitCodes[1]}"
        fi
        if [[ ${exitCodes[0]} == 0 && ${exitCodes[1]} == 0 ]]; then
            logMessage INFO "Finished the back-up of database $db"
        fi
    fi
    
done

logMessage INFO "Finished the back-up of databases to $backupDirectory"

if [[ -n $mail && ${logCache[@]} != 0 ]]; then
    {
        cat <<EOF
During backup of MySQL databases, the following messages of threshold
$mailThreshold have been logged:

EOF
        for line in "${logCache[@]}"; do
            echo "$line";
        done
    } | mail -s "mybackup report for $(hostname -f)" -e "$mail"
fi