|
|
|
@@ -0,0 +1,104 @@
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
ulimit -n 65536
|
|
|
|
|
|
|
|
|
|
BACKUP_BASE=/var/backups/tscale01
|
|
|
|
|
PREFIX=eqn-bck-logic-
|
|
|
|
|
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
|
|
|
|
TARGET="$BACKUP_BASE/${PREFIX}${TIMESTAMP}"
|
|
|
|
|
|
|
|
|
|
LOGFILE=/var/log/mariadb-backup.log
|
|
|
|
|
LOCKFILE=/var/lock/mariadb-backup.lock
|
|
|
|
|
|
|
|
|
|
SERVER_NAME=$(hostname -s)
|
|
|
|
|
|
|
|
|
|
# binari e opzioni (root senza password)
|
|
|
|
|
MYSQL_BIN=$(command -v mariadb || true)
|
|
|
|
|
MYSQLDUMP_BIN=$(command -v mariadb-dump || true)
|
|
|
|
|
MYSQLDUMP_OPTS="--user=root --single-transaction --quick --skip-lock-tables"
|
|
|
|
|
|
|
|
|
|
# logfile
|
|
|
|
|
touch "$LOGFILE"
|
|
|
|
|
chown root:root "$LOGFILE"
|
|
|
|
|
chmod 600 "$LOGFILE"
|
|
|
|
|
|
|
|
|
|
(
|
|
|
|
|
flock -n 9 || { echo "[$(date '+%F %T')] [$SERVER_NAME] SKIP: another backup is running" >> "$LOGFILE"; exit 0; }
|
|
|
|
|
|
|
|
|
|
if [ -z "$MYSQL_BIN" ]; then
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] ERROR: mariadb client not found in PATH" >> "$LOGFILE"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ -z "$MYSQLDUMP_BIN" ]; then
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] ERROR: mariadb-dump not found in PATH" >> "$LOGFILE"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
mkdir -p "$TARGET"
|
|
|
|
|
chown mysql:mysql "$TARGET"
|
|
|
|
|
chmod 750 "$TARGET"
|
|
|
|
|
|
|
|
|
|
TMPLOG=$(mktemp /tmp/mariadb-backup-logic.XXXXXX)
|
|
|
|
|
|
|
|
|
|
echo "---------------------" >> "$LOGFILE"
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] START logic backup (per-database) $TARGET" >> "$LOGFILE"
|
|
|
|
|
|
|
|
|
|
# elenco database (escludo schemi di sistema)
|
|
|
|
|
DB_LIST=$($MYSQL_BIN -N -e "SHOW DATABASES" | grep -vE '^(information_schema|performance_schema|mysql|sys)$' || true)
|
|
|
|
|
|
|
|
|
|
if [ -z "$DB_LIST" ]; then
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] WARNING: no user databases found to dump" >> "$LOGFILE"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
FAILED=0
|
|
|
|
|
FAILED_DBS=""
|
|
|
|
|
|
|
|
|
|
for db in $DB_LIST; do
|
|
|
|
|
DUMPFILE="$TARGET/${db}.sql"
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] START dump database '$db' -> $DUMPFILE" >> "$LOGFILE"
|
|
|
|
|
|
|
|
|
|
if $MYSQLDUMP_BIN $MYSQLDUMP_OPTS "$db" >"$DUMPFILE" 2>"$TMPLOG"; then
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] END dump database '$db'" >> "$LOGFILE"
|
|
|
|
|
else
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] ERROR dumping database '$db'. See $TMPLOG" >> "$LOGFILE"
|
|
|
|
|
tail -n 100 "$TMPLOG" >> "$LOGFILE"
|
|
|
|
|
FAILED=1
|
|
|
|
|
FAILED_DBS="$FAILED_DBS $db"
|
|
|
|
|
# continuo con i successivi
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# misura dimensioni complessive
|
|
|
|
|
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")
|
|
|
|
|
|
|
|
|
|
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')] [$SERVER_NAME] SIZE apparent: $size_apparent_human ($size_apparent_bytes bytes) for $TARGET" >> "$LOGFILE"
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] SIZE on-disk: $size_disk_human ($size_disk_bytes bytes) for $TARGET" >> "$LOGFILE"
|
|
|
|
|
|
|
|
|
|
if [ "$FAILED" -eq 0 ]; then
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] RESULT: OK, all databases dumped successfully" >> "$LOGFILE"
|
|
|
|
|
else
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] RESULT: PARTIAL, failed databases:$FAILED_DBS" >> "$LOGFILE"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
rm -f "$TMPLOG"
|
|
|
|
|
|
|
|
|
|
# rotazione: mantieni 7 giorni per i logic
|
|
|
|
|
TO_DELETE=$(find "$BACKUP_BASE" -maxdepth 1 -type d -name "${PREFIX}*" -mtime +7 -print 2>/dev/null || true)
|
|
|
|
|
|
|
|
|
|
if [ -n "$TO_DELETE" ]; then
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] ROTATE: removing old logic backups:" >> "$LOGFILE"
|
|
|
|
|
echo "$TO_DELETE" >> "$LOGFILE"
|
|
|
|
|
echo "$TO_DELETE" | tr '\n' '\0' | xargs -0 -r rm -rf --
|
|
|
|
|
else
|
|
|
|
|
echo "[$(date '+%F %T')] [$SERVER_NAME] ROTATE: no logic backups to remove (<=7 days)" >> "$LOGFILE"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo " " >> "$LOGFILE"
|
|
|
|
|
|
|
|
|
|
) 9>"$LOCKFILE"
|