#!/bin/bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # shellcheck source=./mysql_common.sh source "$SCRIPT_DIR/mysql_common.sh" BASE_DIR="${BASE_DIR:-/home/admin/mysql_backup}" DATE_FORMAT="${DATE_FORMAT:-%d-%m-%Y}" ADD_TIME="${ADD_TIME:-0}" RETENTION="${RETENTION:-7}" ENABLE_COMPRESSION="${ENABLE_COMPRESSION:-1}" LOG_FILE="${LOG_FILE:-/var/log/mysql_backup.log}" timestamp() { date '+%Y-%m-%d %H:%M:%S' } log() { printf '[%s] %s\n' "$(timestamp)" "$*" | tee -a "$LOG_FILE" } dump_globals_file() { local output_file="$1" local tmp_file tmp_file="$(mktemp)" { echo "-- Global users and grants for MySQL" echo "-- Generated at $(timestamp)" } > "$tmp_file" while IFS=$'\t' read -r db_user db_host; do [ -n "$db_user" ] || continue [ -n "$db_host" ] || continue printf "DROP USER IF EXISTS '%s'@'%s';\n" "$db_user" "$db_host" >> "$tmp_file" mysql_exec mysql -Nse "SHOW CREATE USER '${db_user}'@'${db_host}'" >> "$tmp_file" || true echo ";" >> "$tmp_file" while IFS= read -r grant_line; do [ -n "$grant_line" ] || continue printf "%s;\n" "$grant_line" >> "$tmp_file" done < <(mysql_exec mysql -Nse "SHOW GRANTS FOR '${db_user}'@'${db_host}'" || true) echo >> "$tmp_file" done < <( mysql_exec mysql -Nse " SELECT user, host FROM mysql.user WHERE user <> '' AND user NOT IN ('mysql.sys', 'mysql.session', 'mysql.infoschema', 'mariadb.sys') ORDER BY user, host " || true ) if [ "$ENABLE_COMPRESSION" = "1" ]; then gzip -9 < "$tmp_file" > "$output_file" else mv "$tmp_file" "$output_file" return 0 fi rm -f "$tmp_file" } mysql_load_alt_credentials mkdir -p "$BASE_DIR" if [ "$ADD_TIME" = "1" ]; then DATE_STR="$(date +"${DATE_FORMAT}_%H-%M")" else DATE_STR="$(date +"${DATE_FORMAT}")" fi BACKUP_DIR="${BASE_DIR}/${DATE_STR}" mkdir -p "$BACKUP_DIR" log "Start backupu MySQL do ${BACKUP_DIR}" GLOBALS_FILE="${BACKUP_DIR}/_globals.sql" if [ "$ENABLE_COMPRESSION" = "1" ]; then GLOBALS_FILE="${GLOBALS_FILE}.gz" fi dump_globals_file "$GLOBALS_FILE" log "Zapisano ${GLOBALS_FILE##*/}" while IFS= read -r db_name; do [ -n "$db_name" ] || continue target_file="${BACKUP_DIR}/${db_name}.sql" if [ "$ENABLE_COMPRESSION" = "1" ]; then mysqldump_exec --single-transaction --skip-lock-tables --routines --triggers --events --databases "$db_name" | gzip -9 > "${target_file}.gz" log "Backup ${db_name} -> ${target_file##*/}.gz" else mysqldump_exec --single-transaction --skip-lock-tables --routines --triggers --events --databases "$db_name" > "$target_file" log "Backup ${db_name} -> ${target_file##*/}" fi done < <(mysql_non_system_databases) if [ "$RETENTION" -gt 0 ]; then find "$BASE_DIR" -mindepth 1 -maxdepth 1 -type d -mtime +"$RETENTION" -exec rm -rf {} + fi log "Backup MySQL zakończony."