miglioramento script full e incremental e commenti
This commit is contained in:
@@ -1,66 +1,100 @@
|
||||
#!/bin/bash
|
||||
# Backup FULL con atomicità, cleanup, log completi e sicurezza operativa
|
||||
# Sicuro per cluster Galera
|
||||
# Autore: Marco + Copilot
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Aumenta i file descriptor disponibili
|
||||
ulimit -n 65536
|
||||
|
||||
# Directory base dei backup
|
||||
BACKUP_BASE=/var/backups/tscale01
|
||||
|
||||
# Timestamp per la directory del backup
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
# Directory finale del backup FULL
|
||||
TARGET="$BACKUP_BASE/backup-full-$TIMESTAMP"
|
||||
|
||||
# File di log generale
|
||||
LOGFILE=/var/log/mariadb-backup.log
|
||||
|
||||
# Lockfile per evitare esecuzioni concorrenti
|
||||
LOCKFILE=/var/lock/mariadb-backup.lock
|
||||
|
||||
# assicurati che il logfile esista e abbia permessi restrittivi
|
||||
# Nome del server per i log
|
||||
SERVER_NAME=$(hostname -s)
|
||||
|
||||
# Assicura che il logfile esista e abbia permessi sicuri
|
||||
touch "$LOGFILE"
|
||||
chown root:root "$LOGFILE"
|
||||
chmod 600 "$LOGFILE"
|
||||
|
||||
#verifico file lock per non sovrapporre backup
|
||||
(
|
||||
flock -n 9 || { echo "[$(date '+%F %T')] SKIP: another backup is running" >> "$LOGFILE"; exit 0; }
|
||||
# FLOCK: evita che due backup partano insieme
|
||||
flock -n 9 || {
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] SKIP: another backup is running" >> "$LOGFILE"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Crea directory del backup
|
||||
mkdir -p "$TARGET"
|
||||
chown mysql:mysql "$TARGET"
|
||||
chmod 750 "$TARGET"
|
||||
|
||||
TMPLOG=$(mktemp /tmp/mariadb-backup.XXXXXX)
|
||||
# File temporaneo per catturare errori del backup
|
||||
TMPLOG=$(mktemp /tmp/mariadb-backup-full.XXXXXX)
|
||||
|
||||
echo "---------------------" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] START backup full $TARGET" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] START backup FULL $TARGET" >> "$LOGFILE"
|
||||
|
||||
if mariadb-backup --defaults-file=/etc/mysql/backup.conf --backup --target-dir="$TARGET" --verbose >"$TMPLOG" 2>&1; then
|
||||
echo "[$(date '+%F %T')] NOTE: full created UNPREPARED at $TARGET" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] END backup full $TARGET" >> "$LOGFILE"
|
||||
# Esecuzione backup FULL
|
||||
if mariadb-backup \
|
||||
--defaults-file=/etc/mysql/backup.conf \
|
||||
--backup \
|
||||
--target-dir="$TARGET" \
|
||||
--verbose >"$TMPLOG" 2>&1; then
|
||||
|
||||
# misura dimensione apparente (byte logici)
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] NOTE: FULL created UNPREPARED at $TARGET" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] END backup FULL $TARGET" >> "$LOGFILE"
|
||||
|
||||
# Misura dimensione apparente (byte logici)
|
||||
size_apparent_bytes=$(find "$TARGET" -type f -printf '%s\n' 2>/dev/null | awk '{s+=$1} END{print s+0}')
|
||||
size_apparent_human=$(numfmt --to=iec --suffix=B "$size_apparent_bytes" 2>/dev/null || echo "${size_apparent_bytes}B")
|
||||
|
||||
# misura spazio su disco effettivo (byte allocati)
|
||||
# Misura spazio su disco effettivo (byte allocati)
|
||||
size_disk_bytes=$(du -s --block-size=1 "$TARGET" 2>/dev/null | cut -f1 || echo 0)
|
||||
size_disk_human=$(numfmt --to=iec --suffix=B "$size_disk_bytes" 2>/dev/null || echo "${size_disk_bytes}B")
|
||||
|
||||
echo "[$(date '+%F %T')] SIZE apparent: $size_apparent_human ($size_apparent_bytes bytes) for $TARGET" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] SIZE on-disk: $size_disk_human ($size_disk_bytes bytes) for $TARGET" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] SIZE apparent: $size_apparent_human ($size_apparent_bytes bytes)" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] SIZE on-disk: $size_disk_human ($size_disk_bytes bytes)" >> "$LOGFILE"
|
||||
|
||||
echo "[$(date '+%F %T')] RESULT: OK, no errors" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] RESULT: OK, no errors" >> "$LOGFILE"
|
||||
|
||||
rm -f "$TMPLOG"
|
||||
|
||||
else
|
||||
echo "[$(date '+%F %T')] ERROR during backup for $TARGET. See $TMPLOG" >> "$LOGFILE"
|
||||
# Backup fallito → log + cleanup directory
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] ERROR during FULL backup for $TARGET. See $TMPLOG" >> "$LOGFILE"
|
||||
tail -n 200 "$TMPLOG" >> "$LOGFILE"
|
||||
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] CLEANUP: removing incomplete FULL backup directory $TARGET" >> "$LOGFILE"
|
||||
rm -rf "$TARGET"
|
||||
|
||||
rm -f "$TMPLOG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# rotazione: mantieni 7 giorni solo per i full (log dettagliato come per gli incrementali)
|
||||
# Rotazione: mantieni 7 giorni di FULL
|
||||
TO_DELETE=$(find "$BACKUP_BASE" -maxdepth 1 -type d -name 'backup-full-*' -mtime +7 -print 2>/dev/null || true)
|
||||
|
||||
if [ -n "$TO_DELETE" ]; then
|
||||
echo "[$(date '+%F %T')] ROTATE: removing old fulls:" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] ROTATE: removing old FULL backups:" >> "$LOGFILE"
|
||||
echo "$TO_DELETE" >> "$LOGFILE"
|
||||
echo "$TO_DELETE" | tr '\n' '\0' | xargs -0 -r rm -rf --
|
||||
else
|
||||
echo "[$(date '+%F %T')] ROTATE: no fulls to remove (<=7 days)" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] ROTATE: no FULL backups to remove (<=7 days)" >> "$LOGFILE"
|
||||
fi
|
||||
|
||||
echo " " >> "$LOGFILE"
|
||||
|
||||
@@ -1,77 +1,115 @@
|
||||
#!/bin/bash
|
||||
# Backup INCREMENTAL con atomicità, cleanup, log completi e sicurezza operativa
|
||||
# Sicuro per cluster Galera
|
||||
# Autore: Marco + Copilot
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Aumenta i file descriptor disponibili
|
||||
ulimit -n 65536
|
||||
|
||||
# Directory base dei backup
|
||||
BACKUP_BASE=/var/backups/tscale01
|
||||
|
||||
# Prefissi per full e incremental
|
||||
FULL_PREFIX=backup-full-
|
||||
INC_PREFIX=backup-inc-
|
||||
|
||||
# Timestamp per la directory del backup
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
# Directory finale del backup INCREMENTAL
|
||||
TARGET="$BACKUP_BASE/${INC_PREFIX}${TIMESTAMP}"
|
||||
|
||||
# File di log generale
|
||||
LOGFILE=/var/log/mariadb-backup.log
|
||||
|
||||
# Lockfile per evitare esecuzioni concorrenti
|
||||
LOCKFILE=/var/lock/mariadb-backup.lock
|
||||
|
||||
# assicurati che il logfile esista e abbia permessi restrittivi
|
||||
# Nome del server per i log
|
||||
SERVER_NAME=$(hostname -s)
|
||||
|
||||
# Assicura che il logfile esista e abbia permessi sicuri
|
||||
touch "$LOGFILE"
|
||||
chown root:root "$LOGFILE"
|
||||
chmod 600 "$LOGFILE"
|
||||
|
||||
#verifico file lock per non sovrapporre backup
|
||||
(
|
||||
flock -n 9 || { echo "[$(date '+%F %T')] SKIP: another backup is running" >> "$LOGFILE"; exit 0; }
|
||||
# FLOCK: evita che due backup partano insieme
|
||||
flock -n 9 || {
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] SKIP: another backup is running" >> "$LOGFILE"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Trova l'ultimo FULL disponibile
|
||||
LATEST_FULL=$(ls -1d ${BACKUP_BASE}/${FULL_PREFIX}* 2>/dev/null | sort | tail -n1 || true)
|
||||
|
||||
if [ -z "$LATEST_FULL" ]; then
|
||||
echo "[$(date '+%F %T')] ERROR: no full backup found in $BACKUP_BASE. Create a full backup first." >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] ERROR: no FULL backup found. Create a FULL backup first." >> "$LOGFILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BASE_DIR="$LATEST_FULL"
|
||||
|
||||
# Crea directory del backup
|
||||
mkdir -p "$TARGET"
|
||||
chown mysql:mysql "$TARGET"
|
||||
chmod 750 "$TARGET"
|
||||
|
||||
# File temporaneo per catturare errori del backup
|
||||
TMPLOG=$(mktemp /tmp/mariadb-backup-inc.XXXXXX)
|
||||
|
||||
echo "---------------------" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] START incremental backup $TARGET (base: $BASE_DIR)" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] START incremental backup $TARGET (base: $BASE_DIR)" >> "$LOGFILE"
|
||||
|
||||
if mariadb-backup --defaults-file=/etc/mysql/backup.conf --backup --target-dir="$TARGET" --incremental-basedir="$BASE_DIR" --verbose >"$TMPLOG" 2>&1; then
|
||||
echo "[$(date '+%F %T')] END incremental backup $TARGET" >> "$LOGFILE"
|
||||
# Esecuzione backup INCREMENTAL
|
||||
if mariadb-backup \
|
||||
--defaults-file=/etc/mysql/backup.conf \
|
||||
--backup \
|
||||
--target-dir="$TARGET" \
|
||||
--incremental-basedir="$BASE_DIR" \
|
||||
--verbose >"$TMPLOG" 2>&1; then
|
||||
|
||||
# misura dimensione apparente (byte logici)
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] END incremental backup $TARGET" >> "$LOGFILE"
|
||||
|
||||
# Misura dimensione apparente (byte logici)
|
||||
size_apparent_bytes=$(find "$TARGET" -type f -printf '%s\n' 2>/dev/null | awk '{s+=$1} END{print s+0}')
|
||||
size_apparent_human=$(numfmt --to=iec --suffix=B "$size_apparent_bytes" 2>/dev/null || echo "${size_apparent_bytes}B")
|
||||
|
||||
# misura spazio su disco effettivo (byte allocati)
|
||||
# Misura spazio su disco effettivo (byte allocati)
|
||||
size_disk_bytes=$(du -s --block-size=1 "$TARGET" 2>/dev/null | cut -f1 || echo 0)
|
||||
size_disk_human=$(numfmt --to=iec --suffix=B "$size_disk_bytes" 2>/dev/null || echo "${size_disk_bytes}B")
|
||||
|
||||
echo "[$(date '+%F %T')] SIZE apparent: $size_apparent_human ($size_apparent_bytes bytes) for $TARGET" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] SIZE on-disk: $size_disk_human ($size_disk_bytes bytes) for $TARGET" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] SIZE apparent: $size_apparent_human ($size_apparent_bytes bytes)" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] SIZE on-disk: $size_disk_human ($size_disk_bytes bytes)" >> "$LOGFILE"
|
||||
|
||||
echo "[$(date '+%F %T')] RESULT: OK, no errors" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] RESULT: OK, no errors" >> "$LOGFILE"
|
||||
|
||||
rm -f "$TMPLOG"
|
||||
|
||||
else
|
||||
echo "[$(date '+%F %T')] ERROR during incremental backup for $TARGET. See $TMPLOG" >> "$LOGFILE"
|
||||
# Backup fallito → log + cleanup directory
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] ERROR during incremental backup for $TARGET. See $TMPLOG" >> "$LOGFILE"
|
||||
tail -n 200 "$TMPLOG" >> "$LOGFILE"
|
||||
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] CLEANUP: removing incomplete incremental backup directory $TARGET" >> "$LOGFILE"
|
||||
rm -rf "$TARGET"
|
||||
|
||||
rm -f "$TMPLOG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# rotazione: mantieni esattamente 11 incrementali più recenti
|
||||
# Rotazione: mantieni esattamente 11 incrementali più recenti
|
||||
cd "$BACKUP_BASE" || exit 1
|
||||
TO_DELETE=$(ls -1d ${INC_PREFIX}* 2>/dev/null | sort | head -n -11 || true)
|
||||
|
||||
if [ -n "$TO_DELETE" ]; then
|
||||
echo "[$(date '+%F %T')] ROTATE: removing old incrementals:" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] ROTATE: removing old incrementals:" >> "$LOGFILE"
|
||||
echo "$TO_DELETE" >> "$LOGFILE"
|
||||
echo "$TO_DELETE" | xargs -r -d '\n' rm -rf --
|
||||
else
|
||||
echo "[$(date '+%F %T')] ROTATE: no incrementals to remove (<=11 present)" >> "$LOGFILE"
|
||||
echo "[$(date '+%F %T')] [$SERVER_NAME] ROTATE: no incrementals to remove (<=11 present)" >> "$LOGFILE"
|
||||
fi
|
||||
|
||||
echo " " >> "$LOGFILE"
|
||||
|
||||
Reference in New Issue
Block a user