Skip to content

Instantly share code, notes, and snippets.

@zzf01
Created August 3, 2025 15:33
Show Gist options
  • Select an option

  • Save zzf01/95fd4054763a5fda9c14cd677f14b502 to your computer and use it in GitHub Desktop.

Select an option

Save zzf01/95fd4054763a5fda9c14cd677f14b502 to your computer and use it in GitHub Desktop.
mariadb-backup restore
#!/bin/bash
BACKUP_BASE="$1"
TARGET_INC_FILE="$2"
if [ ! -d "$BACKUP_BASE" ]; then
echo "$BACKUP_BASE is not a valid directory"
echo "Usage: $0 <backup_dir> [stop_after_incremental_file]"
exit 1
fi
# === CONFIGURATION ===
FULL_BACKUP_DIR="$BACKUP_BASE/full"
INCREMENTAL_BASE_DIR="$BACKUP_BASE/inc"
WORKDIR="/tmp/mariadb-restore"
DATADIR="/var/lib/mysql"
TS="$(date '+%F_%H-%M-%S')"
LOGFILE="$BACKUP_BASE/logs/restore_$TS.log"
MBACKUP_LOGFILE="$BACKUP_BASE/logs/restore_$TS.mariabackup.log"
log() {
echo "[$(date '+%F %T')] $1" >> "$LOGFILE"
}
confirm() {
echo -e "\n⚠️ This will overwrite your current MariaDB data directory: $DATADIR"
read -p "👉 Is MariaDB stopped and do you want to proceed with restore? (yes/no): " confirm
if [[ "$confirm" != "yes" ]]; then
echo "❌ Aborted by user."
exit 1
fi
}
check_disk_space() {
total_size=$(find "$FULL_BACKUP_DIR" "$INCREMENTAL_BASE_DIR" -type f -name '*.zst' -exec du -b {} + | awk '{sum += $1} END {print sum}')
available_space=$(df -B1 "$WORKDIR" | awk 'NR==2 {print $4}')
threshold=$((total_size * 10))
log "Total backup size: $total_size bytes"
log "Available WORKDIR space: $available_space bytes"
if (( available_space < threshold )); then
echo "⚠️ Warning: Less than 10x the compressed backup size is available in $WORKDIR"
echo "Required: $threshold bytes, Available: $available_space bytes"
read -p "Continue anyway? (yes/no): " answer
if [[ "$answer" != "yes" ]]; then
echo "❌ Aborted by user due to insufficient space."
exit 1
fi
fi
}
# === MAIN EXECUTION ===
log "Starting restore process..."
mkdir -p "$WORKDIR"
cd "$WORKDIR" || exit 1
LATEST_FULL_ZST=$(find "$FULL_BACKUP_DIR" -type f -name '*.mbstream.zst' | sort | tail -n 1)
if [[ -n "$LATEST_FULL_ZST" ]]; then
check_disk_space
log "Detected compressed full backup: $LATEST_FULL_ZST"
zstd -dc "$LATEST_FULL_ZST" | mbstream -x -C "$WORKDIR"
else
log "❌ No full backup found."
exit 1
fi
log "Preparing full backup..."
mariabackup --prepare --target-dir="$WORKDIR" &>> "$MBACKUP_LOGFILE"
mapfile -t INCS < <(find "$INCREMENTAL_BASE_DIR" -type f -name '*.zst' | sort)
for inc in "${INCS[@]}"; do
inc_file_name=$(basename "$inc")
INC_TMP="/tmp/restore_inc_$(basename "$inc" .zst)"
mkdir -p "$INC_TMP"
log "Decompressing incremental: $inc"
zstd -dc "$inc" | mbstream -x -C "$INC_TMP"
log "Applying incremental to full: $inc"
mariabackup --prepare \
--target-dir="$WORKDIR" \
--incremental-dir="$INC_TMP" &>> "$MBACKUP_LOGFILE"
rm -rf "$INC_TMP"
if [[ -n "$TARGET_INC_FILE" && "$inc_file_name" == "$TARGET_INC_FILE" ]]; then
log "Reached target incremental file: $TARGET_INC_FILE. Stopping here."
break
fi
done
confirm
log "Restoring backup to $DATADIR using mariadb-backup --copy-back --target-dir=$WORKDIR"
mv ${DATADIR}/ ${DATADIR}.save
mariadb-backup --copy-back --target-dir="$WORKDIR"
chown -R mysql:mysql "$DATADIR"
rm -rf "$WORKDIR"
log "✅ Restore complete. You can now start MariaDB."
echo "✅ Restore complete. You can now start MariaDB: sudo systemctl start mariadb"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment