#!/bin/bash # ============================================================================== # Jellyfin SQLite Database Repair Script # # This script automates the process of recovering a corrupted Jellyfin # library.db file by dumping its content to an SQL file and re-importing # it into a new, clean database. # # MUST BE RUN AS ROOT OR WITH SUDO. # ============================================================================== # --- Configuration --- JELLYFIN_DATA_DIR="/var/lib/jellyfin/data" DB_FILE="library.db" DUMP_FILE="library_dump.sql" # --- End Configuration --- # --- Safety Checks --- # Check if running as root if [ "$EUID" -ne 0 ]; then echo "ERROR: This script must be run as root or with sudo." exit 1 fi # Check if sqlite3 is installed if ! command -v sqlite3 &> /dev/null; then echo "ERROR: sqlite3 is not installed. Please install it first." echo "On Debian/Ubuntu: sudo apt-get install sqlite3" exit 1 fi # Navigate to the data directory or exit if it doesn't exist cd "$JELLYFIN_DATA_DIR" || { echo "ERROR: Could not find Jellyfin data directory at $JELLYFIN_DATA_DIR"; exit 1; } echo "--- Jellyfin DB Repair Initialized ---" # --- Step 1: Stop Jellyfin and Backup --- echo "[1/8] Stopping the Jellyfin service..." systemctl stop jellyfin echo "Service stopped." # Create a timestamped backup TIMESTAMP=$(date +%F-%T) CORRUPT_DB_BACKUP="library.db.corrupt.$TIMESTAMP" echo "[2/8] Backing up corrupted database to $CORRUPT_DB_BACKUP..." if [ -f "$DB_FILE" ]; then cp "$DB_FILE" "$CORRUPT_DB_BACKUP" echo "Backup created." else echo "ERROR: $DB_FILE not found! Cannot proceed." systemctl start jellyfin # Try to start the service again exit 1 fi # --- Step 2: Dump the Database --- echo "[3/8] Dumping data from the corrupted database to $DUMP_FILE..." # We use .dump, which will try to read everything possible. # Using 'tee' to avoid permission issues with redirection. sqlite3 "$DB_FILE" .dump | tee "$DUMP_FILE" > /dev/null echo "Dump complete." # --- Step 3: Fix the Dump File if Necessary --- echo "[4/8] Checking dump file for errors..." # If the dump process encountered an unrecoverable error, it ends with ROLLBACK. # We must change it to COMMIT to save the salvaged data. if grep -q "ROLLBACK;" "$DUMP_FILE"; then echo "-> Found 'ROLLBACK'. Changing to 'COMMIT' to salvage data..." sed -i '$ s/ROLLBACK; -- due to errors/COMMIT;/' "$DUMP_FILE" echo "-> Dump file patched." else echo "-> No 'ROLLBACK' found. Dump file appears clean." fi # --- Step 4: Restore from Dump --- echo "[5/8] Moving old corrupted database aside..." mv "$DB_FILE" "${DB_FILE}.repaired-from" echo "[6/8] Importing data into a new, clean database. This may take a moment..." sqlite3 "$DB_FILE" < "$DUMP_FILE" # --- Step 5: Verification and Cleanup --- # Check if the new database file was created and is not empty if [ ! -s "$DB_FILE" ]; then echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" echo "!! CRITICAL ERROR: The new database is empty! !!" echo "!! The repair has FAILED. Restoring old DB. !!" echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" mv "${DB_FILE}.repaired-from" "$DB_FILE" # Restore the moved file systemctl start jellyfin exit 1 fi echo "-> New database created successfully." # Run integrity check echo "[7/8] Verifying integrity of the new database..." INTEGRITY_CHECK=$(sqlite3 "$DB_FILE" "PRAGMA integrity_check;") if [ "$INTEGRITY_CHECK" == "ok" ]; then echo "-> SUCCESS! Integrity check passed." else echo "-> WARNING: Integrity check on new DB reported: $INTEGRITY_CHECK" echo "-> The database may still have issues, but is likely usable." fi # --- Step 6: Finalize --- echo "[8/8] Setting correct file permissions and restarting Jellyfin..." chown jellyfin:jellyfin "$DB_FILE" chmod 664 "$DB_FILE" systemctl start jellyfin echo "-> Jellyfin service started." echo "" echo "--- Repair Process Complete ---" echo "Your Jellyfin database has been repaired and the service restarted." echo "Please check your Jellyfin web interface to ensure everything is working." echo "Backup files ($CORRUPT_DB_BACKUP, ${DB_FILE}.repaired-from, $DUMP_FILE) have been kept in $JELLYFIN_DATA_DIR for safety." echo "" echo "IMPORTANT: Repeated corruption is a sign of a failing disk. Please check your disk health."