Files
shell/jellyfin/fix-jellyfin-db.sh

124 lines
4.3 KiB
Bash
Executable File

#!/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."