Created
August 3, 2025 15:33
-
-
Save zzf01/95fd4054763a5fda9c14cd677f14b502 to your computer and use it in GitHub Desktop.
mariadb-backup restore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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