#!/bin/zsh -f

# user definable parameters
# days: how many of the latest backups should be kept
days=30
backupdir="/backup/mysql"
store="${backupdir}/store"
logfile="${backupdir}/backup.log"
datecmd=(date --rfc-2822)

umask 0077

# parameters: username, password, hostname, dbname, characterset
function do_backup() {
  username="${1}"
  password="${2}"
  hostname="${3}"
  dbname="${4}"
  charset="${5}"

  echo "
$(${datecmd[@]})
Parameters:
  username=${username}
  password=${(l:${#password}::*:)}
  hostname=${hostname}
  dbname=${dbname}
  characterset=${charset}" >> "${logfile}"

  [[ ${#} -lt 5 ]] && {echo "Not enough parameters!" >> "${logfile}" } && return

  if [[ "${hostname}" == "localhost" || "${hostname}" == "127.0.0.1" ]]; then
    displayname="$(hostname)"
  else
    displayname="${hostname}"
  fi

  backupfile="${backupdir}/${displayname}__${dbname}__$(date +%Y-%m-%d)"
  if [[ -f "${backupfile}.sql.bz2" ]]; then
    rm -f "${backupfile}.sql.bz2" 2>> "${logfile}" || {echo "Backup file already exists and could not be deleted. Backup of target failed." >> "${logfile}"; return}
  fi

  nice -n +19 mysqldump --create-options --default-character-set="${charset}" --host="${hostname}" --hex-blob --lock-tables --password="${password}" --quote-names --user="${username}" "${dbname}" > "${backupfile}.sql" 2>> "${logfile}"
  nice -n +19 bzip2 "${backupfile}.sql"
  [[ ! -f "${backupfile}.sql.bz2" ]] && {echo "Failed to create backup."; return}
  if [[ "$(date +%d)" == "01" && -d "${store}" && -f "${backupfile}.sql.bz2" ]]; then
    echo "Today is the first day of the month. Making a copy of the backup in ${store} ..." >> "${logfile}"
    cp "${backupfile}.sql.bz2" "${store}" >> "${logfile}" 2>&1
  fi

  echo "Cleaning up old backups ..." >> "${logfile}"
  [[ ${days} -gt 0 ]] && ls -1t "${backupdir}/${displayname}__${dbname}__"*".sql.bz2" | tail -n +$((days+1)) | xargs -n 1 -r sh -c 'echo "$@ was deleted." && rm "$@"' delete_backup >> "${logfile}" 2>&1
}


[[ ! -d "${backupdir}" || ! -r "${backupdir}" || ! -x "${backupdir}" || ! -w "${backupdir}" ]] && {echo "Backup directory (${backupdir}) does not exist or is not readable+writeable+searchable by current process. Backup failed." >&2; exit 1}
touch "${logfile}" 2> /dev/null
[[ ! -w "${logfile}" ]] && {echo "Error (${0:t}): cannot write to logfile (${logfile})!" >&2; exit 1}

echo "**********************************
Starting backup at: $(${datecmd[@]})" >> "${logfile}"


# List of backups
# Parameters: username password hostname dbname characterset

do_backup "backup_jack" "very_secret_password1" mysql1.example.com jack_db utf8
do_backup "backup_jane" "very_secret_password2" mysql2.example.com jane_db utf8


echo "
End of backup at: $(${datecmd[@]})
" >> "${logfile}"


