diff --git a/DBRepair-WinDev.bat b/DBRepair-Windows.bat similarity index 100% rename from DBRepair-WinDev.bat rename to DBRepair-Windows.bat diff --git a/DBRepair.sh b/DBRepair.sh index 5d01627..1d754d8 100755 --- a/DBRepair.sh +++ b/DBRepair.sh @@ -2,18 +2,51 @@ ######################################################################### # Plex Media Server database check and repair utility script. # # Maintainer: ChuckPa # +# Version: v1.0.0 - RC 1 # +# Date: 05-Mar-2023 # ######################################################################### +# Version for display purposes +Version="v1.0.0 - RC 1" + # Flag when temp files are to be retained Retain=0 # Have the databases passed integrity checks CheckedDB=0 +# By default, we cannot start/stop PMS +HaveStartStop=0 +StartStopUser=0 +StartCommand="" +StopCommand="" + +# Keep track of how many times the user's hit enter with no command (implied EOF) +NullCommands=0 + +# Global variable - main database +CPPL=com.plexapp.plugins.library + +# Initial timestamp +TimeStamp="$(date "+%Y-%m-%d_%H.%M.%S")" + +# Initialize global runtime variables +CheckedDB=0 +Damaged=0 +Fail=0 +HaveStartStop=0 +HostType="" +LOG_TOOL="echo" +ShowMenu=1 + # Universal output function Output() { - echo "$@" - $LOG_TOOL "$@" + if [ $Scripted -gt 0 ]; then + echo \[$(date "+%Y-%m-%d %H.%M.%S")\] "$@" + else + echo "$@" + fi + # $LOG_TOOL \[$(date "+%Y-%m-%d %H.%M.%S")\] "$@" } # Write to Repair Tool log @@ -79,11 +112,15 @@ CheckDatabases() { if CheckDB $CPPL.blobs.db ; then Output "Check complete. PMS blobs database is OK." WriteLog "$1"" - Check $CPPL.blobs.db - PASS" + else Output "Check complete. PMS blobs database is damaged." WriteLog "$1"" - Check $CPPL.blobs.db - FAIL ($SQLerror)" Damaged=1 fi + + # Yes, we've now checked it + CheckedDB=1 fi [ $Damaged -eq 0 ] && CheckedDB=1 @@ -99,7 +136,7 @@ GetDates(){ Tempfile="/tmp/DBRepairTool.$$.tmp" touch "$Tempfile" - for i in $(find . -name 'com.plexapp.plugins.library.db-????-??-??' | sort -r) + for i in $(find . -maxdepth 1 -name 'com.plexapp.plugins.library.db-????-??-??' | sort -r) do # echo Date - "${i//[^.]*db-/}" Date="$(echo $i | sed -e 's/.*.db-//')" @@ -146,6 +183,34 @@ SQLiteOK() { return $CodeError } +# Perform a space check +# Store space available versus space needed in variables +# Return FAIL if needed GE available +# Arg 1, if provided, is multiplier +FreeSpaceAvailable() { + + Multiplier=3 + [ "$1" != "" ] && Multiplier=$1 + + # Available space where DB resides + SpaceAvailable=$(df -m "$AppSuppDir" | tail -1 | awk '{print $4}') + + # Get size of DB and blobs, Minimally needing sum of both + LibSize="$(stat $STATFMT $STATBYTES "$CPPL.db")" + BlobsSize="$(stat $STATFMT $STATBYTES "$CPPL.blobs.db")" + SpaceNeeded=$((LibSize + BlobsSize)) + + # Compute need (minimum $Multiplier existing; current, backup, temp and room to write new) + SpaceNeeded="$(expr $SpaceNeeded '*' $Multiplier)" + SpaceNeeded="$(expr $SpaceNeeded / 1000000)" + + # If need < available, all good + [ $SpaceNeeded -lt $SpaceAvailable ] && return 0 + + # Too close to call, fail + return 1 +} + # Perform the actual copying for MakeBackup() DoBackup() { @@ -169,11 +234,11 @@ DoBackup() { # Make a backup of the current database files and tag with TimeStamp MakeBackups() { - Output "Backup current databases with '-ORIG-$TimeStamp' timestamp." + Output "Backup current databases with '-BACKUP-$TimeStamp' timestamp." for i in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm" do - DoBackup "$1" "${CPPL}.${i}" "$DBTMP/${CPPL}.${i}-ORIG-$TimeStamp" + DoBackup "$1" "${CPPL}.${i}" "$DBTMP/${CPPL}.${i}-BACKUP-$TimeStamp" Result=$? done @@ -195,30 +260,7 @@ ConfirmYesNo() { # Unrecognized if [ "$Answer" != "Y" ] && [ "$Answer" != "N" ]; then - echo "$Input" was not a valid reply. Please try again. - continue - fi - done - - # If no, done. - if [ "$Answer" = "N" ]; then - return 1 - fi - - # User said Yes. Be 100% certain - Answer="" - while [ "$Answer" = "" ] - do - printf "Are you sure (Y/N) ? " - read Input - - # EOF = No - [ "$Input" = "" ] && Answer=N ; [ "$Input" = "n" ] && Answer=N ; [ "$Input" = "N" ] && Answer=N - [ "$Input" = "y" ] && Answer=Y ; [ "$Input" = "Y" ] && Answer=Y - - # Unrecognized - if [ "$Answer" != "Y" ] && [ "$Answer" != "N" ]; then - echo "$Input" was not a valid reply. Please try again. + printf "$Input" was not a valid reply. Please try again. continue fi done @@ -239,7 +281,7 @@ RestoreSaved() { for i in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm" do [ -e "${CPPL}.${i}" ] && rm -f "${CPPL}.${i}" - [ -e "$DBTMP/${CPPL}.${i}-ORIG-$T" ] && mv "$DBTMP/${CPPL}.${i}-ORIG-$T" "${CPPL}.${i}" + [ -e "$DBTMP/${CPPL}.${i}-BACKUP-$T" ] && mv "$DBTMP/${CPPL}.${i}-BACKUP-$T" "${CPPL}.${i}" done } @@ -277,6 +319,11 @@ HostConfig() { # We are done HostType="Synology (DSM 7)" + + # We do have start/stop as root + HaveStartStop=1 + StartCommand="/usr/syno/bin/synopkg start PlexMediaServer" + StopCommand="/usr/syno/bin/synopkg stop PlexMediaServer" return 0 # Synology (DSM 6) @@ -300,9 +347,15 @@ HostConfig() { LOGFILE="$DBDIR/DBRepair.log" HostType="Synology (DSM 6)" + + # We do have start/stop as root + HaveStartStop=1 + StartCommand="/usr/syno/bin/synopkg start PlexMediaServer" + StopCommand="/usr/syno/bin/synopkg stop PlexMediaServer" return 0 fi + # QNAP (QTS & QuTS) elif [ -f /etc/config/qpkg.conf ]; then @@ -317,6 +370,13 @@ HostConfig() { PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid" LOGFILE="$DBDIR/DBRepair.log" + # Start/Stop + if [ -e /etc/init.d/plex.sh ]; then + HaveStartStop=1 + StartCommand="/etc/init.d/plex.sh start" + StopCommand="/etc/init.d/plex.sh stop" + fi + HostType="QNAP" return 0 @@ -332,8 +392,8 @@ HostConfig() { # Where is the data AppSuppDir="/var/lib/plexmediaserver/Library/Application Support" - DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases" - PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid" + # DBDIR="$AppSuppDir/Plex Media Server/Plug-in Support/Databases" + # PID_FILE="$AppSuppDir/Plex Media Server/plexmediaserver.pid" # Find the metadata dir if customized if [ -e /etc/systemd/system/plexmediaserver.service.d ]; then @@ -348,7 +408,7 @@ HostConfig() { if [ -d "$NewSuppDir" ]; then AppSuppDir="$NewSuppDir" else - echo "Given application support directory override specified does not exist: '$NewSuppDir'". Ignoring. + Output "Given application support directory override specified does not exist: '$NewSuppDir'. Ignoring." fi fi fi @@ -358,6 +418,10 @@ HostConfig() { LOGFILE="$DBDIR/DBRepair.log" HostType="$(grep ^PRETTY_NAME= /etc/os-release | sed -e 's/PRETTY_NAME=//' | sed -e 's/"//g')" + + HaveStartStop=1 + StartCommand="systemctl start plexmediaserver" + StopCommand="systemctl stop plexmediaserver" return 0 # Netgear ReadyNAS @@ -423,11 +487,37 @@ HostConfig() { LOGFILE="$DBDIR/DBRepair.log" LOG_TOOL="logger" + if [ -d "/var/run/service/svc-plex" ]; then + HaveStartStop=1 + StartCommand="s6-svc -u /var/run/service/svc-plex" + StopCommand="s6-svc -d /var/run/service/svc-plex" + fi + + if [ -d "/var/run/s6/services/plex" ]; then + HaveStartStop=1 + StartCommand="s6-svc -u /var/run/s6/services/plex" + StopCommand="s6-svc -d /var/run/s6/services/plex" + fi + + # lsio stop + if [ -d "/var/run/service/svc-plex" ]; then + HaveStartStop=1 + StartCommand="s6-svc -u /var/run/service/svc-plex" + StopCommand="s6-svc -d /var/run/service/svc-plex" + fi + + # HOTIO + if [ -d /run/service/plex ]; then + HaveStartStop=1 + StartCommand="s6-svc -u /run/service/plex" + StopCommand="s6-svc -d /run/service/plex" + fi + HostType="Docker" return 0 # BINHEX Plex image - elif [ -d "/config/Plex Media Server" ]; then + elif [-f /usr/lib/python3.10/binhex.py ] && [ -d "/config/Plex Media Server" ]; then PLEX_SQLITE="/usr/lib/plexmediaserver/Plex SQLite" AppSuppDir="/config" @@ -494,238 +584,13 @@ HostConfig() { # Simple function to set variables SetLast() { - LastName="$1" LastTimestamp="$2" return 0 } -############################################################# -# Main utility begins here # -############################################################# -# Global variable - main database -CPPL=com.plexapp.plugins.library - -# Initial timestamp -TimeStamp="$(date "+%Y-%m-%d_%H.%M.%S")" - -# Initialize LastName LastTimestamp -SetLast "" "" - -# Identify this host -HostType="" ; LOG_TOOL="echo" -if ! HostConfig; then - Output 'Error: Unknown host. Currently supported hosts are: QNAP, Synology, Netgear, Mac, ASUSTOR, WD (OS5) and Linux Workstation/Server' - exit 1 -fi - -# Is PMS already running? -if $PIDOF 'Plex Media Server' > /dev/null ; then - Output "Plex Media Server is currently running, cannot continue." - Output "Please stop Plex Media Server and restart this utility." - WriteLog "PMS running. Could not continue." - exit 1 -fi - -echo " " -# echo Detected Host: $HostType -WriteLog "============================================================" -WriteLog "Session start: Host is $HostType" - -# Make sure we have a logfile -touch "$LOGFILE" - -# Basic checks; PMS installed -if [ ! -f "$PLEX_SQLITE" ] ; then - Output "PMS is not installed. Cannot continue. Exiting." - WriteLog "Attempt to run utility without PMS installed." - exit 1 -fi - -# Can I write to the Databases directory ? -if [ ! -w "$DBDIR" ]; then - Output "ERROR: Cannot write to the Databases directory. Insufficient privilege or wrong UID. Exiting." - exit 1 -fi - -# Databases exist or Backups exist to restore from -if [ ! -f "$DBDIR/$CPPL.db" ] && \ - [ ! -f "$DBDIR/$CPPL.blobs.db" ] && \ - [ "$(echo com.plexapp.plugins.*-????-??-??)" = "com.plexapp.plugins.*-????-??-??" ]; then - - Output "Cannot locate databases. Cannot continue. Exiting." - WriteLog "No databases or backups found." - exit 1 -fi - -# Set tmp dir so we don't use RAM when in DBDIR -DBTMP="./dbtmp" -mkdir -p "$DBDIR/$DBTMP" -export TMPDIR="$DBTMP" -export TMP="$DBTMP" - -# Work in the Databases directory -cd "$DBDIR" - -# Get the owning UID/GID before we proceed so we can restore -Owner="$(stat $STATFMT '%u:%g' $CPPL.db)" - -# Run entire utility in a loop until all arguments used, EOF on input, or commanded to exit -while true -do - - # Main menu loop - Choice=0; Exit=0 - while [ $Choice -eq 0 ] - do - echo " " - echo " " - echo " Plex Media Server Database Repair Utility ($HostType)" - echo " " - echo "Select" - echo " " - echo " 1. Check database" - echo " 2. Vacuum database" - echo " 3. Reindex database" - echo " 4. Attempt database repair" - echo " 5. Replace current database with newest usable backup copy" - echo " 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace)" - echo " 7. Import Viewstate / Watch history from another PMS database" - echo " 8. Show logfile" - echo " 9. Exit" - echo " " - printf "Enter choice: " - if [ "$1" != "" ]; then - Input="$1" - echo "$1" - shift - else - read Input - - # Handle EOF/forced exit - [ "$Input" = "" ] && Input=8 && Exit=1 - fi - [ "$Input" = "1" ] && Choice=1 - [ "$Input" = "2" ] && Choice=2 - [ "$Input" = "3" ] && Choice=3 - [ "$Input" = "4" ] && Choice=4 - [ "$Input" = "5" ] && Choice=5 - [ "$Input" = "6" ] && Choice=6 - [ "$Input" = "7" ] && Choice=7 - [ "$Input" = "8" ] && Choice=8 - [ "$Input" = "9" ] && Choice=9 - - [ "$Choice" -eq 0 ] && echo " " && echo "'$Input' - Is invalid. Try again" - - # Update timestamp - TimeStamp="$(date "+%Y-%m-%d_%H.%M.%S")" - done - - # Don't get caught; Is PMS already running? - if $PIDOF 'Plex Media Server' > /dev/null ; then - if [ $Choice -lt 8 ]; then - Output "Plex Media Server is currently running, cannot continue." - Output "Please stop Plex Media Server and restart this utility." - WriteLog "PMS running. Could not continue." - continue - fi - fi - - # Spacing for legibility - echo ' ' - - # 1. - Check database - if [ $Choice -eq 1 ]; then - - # CHECK DBs - if CheckDatabases "Check " force ; then - WriteLog "Check - PASS" - CheckedDB=1 - else - WriteLog "Check - FAIL" - CheckedDB=0 - fi - - # 2. Vacuum DB - elif [ $Choice -eq 2 ]; then - - # Clear flags - Fail=0 - Damaged=0 - - # Check databases before Indexing if not previously checked - if ! CheckDatabases "Vacuum " ; then - Damaged=1 - Fail=1 - fi - - # If damaged, exit - if [ $Damaged -eq 1 ]; then - Output "Databases are damaged. Vacuum operation not available. Please repair or replace first." - WriteLog "Vacuum - Databases damaged." - continue - fi - - - # Make a backup - Output "Backing up databases" - if ! MakeBackups "Vacuum "; then - Output "Error making backups. Cannot continue." - WriteLog "Vacuum - MakeBackups - FAIL" - Fail=1 - continue - else - WriteLog "Vacuum - MakeBackups - PASS" - fi - - # Start vacuuming - Output "Vacuuming main database" - SizeStart=$(GetSize $CPPL.db) - - # Vacuum it - "$PLEX_SQLITE" $CPPL.db 'VACUUM;' - Result=$? - - if SQLiteOK $Result; then - SizeFinish=$(GetSize $CPPL.db) - Output "Vacuuming main database successful (Size: ${SizeStart}MB/${SizeFinish}MB)." - WriteLog "Vacuum - Vacuum main database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)." - else - Output "Vaccuming main database failed. Error code $Result from Plex SQLite" - WriteLog "Vacuum - Vacuum main database - FAIL ($Result)" - Fail=1 - fi - - Output "Vacuuming blobs database" - SizeStart=$(GetSize $CPPL.blobs.db) - - # Vacuum it - "$PLEX_SQLITE" $CPPL.blobs.db 'VACUUM;' - Result=$? - - if SQLiteOK $Result; then - SizeFinish=$(GetSize $CPPL.blobs.db) - Output "Vacuuming blobs database successful (Size: ${SizeStart}MB/${SizeFinish}MB)." - WriteLog "Vacuum - Vacuum blobs database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)." - else - Output "Vaccuming blobs database failed. Error code $Result from Plex SQLite" - WriteLog "Vacuum - Vacuum blobs database - FAIL ($Result)" - Fail=1 - fi - - if [ $Fail -eq 0 ]; then - Output "Vacuum complete." - WriteLog "Vacuum - PASS" - SetLast "Vacuum" "$TimeStamp" - else - Output "Vacuum failed." - WriteLog "Vacuum - FAIL" - RestoreSaved "$TimeStamp" - fi - continue - - # 3. Reindex DB - elif [ $Choice -eq 3 ]; then +##### INDEX +DoIndex() { # Clear flag Damaged=0 @@ -733,6 +598,7 @@ do # Check databases before Indexing if not previously checked if ! CheckDatabases "Reindex" ; then Damaged=1 + CheckedDB=1 Fail=1 fi @@ -740,7 +606,7 @@ do # If damaged, exit if [ $Damaged -eq 1 ]; then Output "Databases are damaged. Reindex operation not available. Please repair or replace first." - continue + return fi # Databases are OK, Make a backup @@ -753,7 +619,7 @@ do Output "Error making backups. Cannot continue." WriteLog "Reindex - MakeBackup - FAIL ($Result)" Fail=1 - continue + return fi # Databases are OK, Start reindexing @@ -790,11 +656,47 @@ do RestoreSaved "$TimeStamp" WriteLog "Reindex - FAIL" fi - continue + return $Fail + +} + +##### UNDO +DoUndo(){ + # Confirm there is something to undo + if [ "$LastTimestamp" != "" ]; then + + # Educate user + echo "" + echo "'Undo' restores the databases to the state prior to the last SUCCESSFUL action." + echo "If any action fails before it completes, that action is automatically undone for you." + echo "Be advised: Undo restores the databases to their state PRIOR TO the last action of 'Vacuum', 'Reindex', or 'Replace'" + echo "WARNING: Once Undo completes, there will be nothing more to Undo untl another successful action is completed" + echo "" + + if ConfirmYesNo "Undo '$LastName' performed at timestamp '$LastTimestamp' ? "; then + + Output "Undoing $LastName ($LastTimestamp)" + for j in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm" + do + [ -e "$TMPDIR/$CPPL.$j-BACKUP-$LastTimestamp" ] && mv -f "$TMPDIR/$CPPL.$j-BACKUP-$LastTimestamp" $CPPL.$j + done + + Output "Undo complete." + WriteLog "Undo - Undo ${LastName}, TimeStamp $LastTimestamp" + SetLast "Undo" "" + fi + + else + Output "Nothing to undo." + WriteLog "Undo - Nothing to Undo." + fi + +} + +##### DoRepair +DoRepair() { - # 4. - Attempt DB repair - elif [ $Choice -eq 4 ]; then Damaged=0 Fail=0 @@ -804,7 +706,7 @@ do Output "No main Plex database exists to repair. Exiting." WriteLog "Repair - No main database - FAIL" Fail=1 - continue + return 1 fi # Check size @@ -815,7 +717,7 @@ do Output "Main database is too small/truncated, repair is not possible. Please try restoring a backup. " WriteLog "Repair - Main databse too small - FAIL" Fail=1 - continue + return 1 fi # Continue @@ -826,7 +728,7 @@ do Owner="$(stat $STATFMT '%u:%g' $CPPL.db)" # Attempt to export main db to SQL file (Step 1) - printf 'Export: (main)..' + Output "Exporting Main DB" "$PLEX_SQLITE" $CPPL.db ".output '$TMPDIR/library.plexapp.sql-$TimeStamp'" .dump Result=$? if ! SQLiteOK $Result; then @@ -836,11 +738,11 @@ do Output "Could not successfully export the main database to repair it. Please try restoring a backup." WriteLog "Repair - Cannot recover main database to '$TMPDIR/library.plexapp.sql-$TimeStamp' - FAIL ($Result)" Fail=1 - continue + return 1 fi # Attempt to export blobs db to SQL file - printf '(blobs)..' + Output "Exporting Blobs DB" "$PLEX_SQLITE" $CPPL.blobs.db ".output '$TMPDIR/blobs.plexapp.sql-$TimeStamp'" .dump Result=$? if ! SQLiteOK $Result; then @@ -850,7 +752,7 @@ do Output "Could not successfully export the blobs database to repair it. Please try restoring a backup." WriteLog "Repair - Cannot recover blobs database to '$TMPDIR/blobs.plexapp.sql-$TimeStamp' - FAIL ($Result)" Fail=1 - continue + return 1 fi # Edit the .SQL files if all OK @@ -862,45 +764,43 @@ do fi # Inform user - echo done. Output "Successfully exported the main and blobs databases. Proceeding to import into new databases." WriteLog "Repair - Export databases - PASS" # Library and blobs successfully exported, create new - printf 'Import: (main)..' - "$PLEX_SQLITE" $CPPL.db-$TimeStamp < "$TMPDIR/library.plexapp.sql-$TimeStamp" + Output "Importing Main DB." + "$PLEX_SQLITE" "$TMPDIR/$CPPL.db-REPAIR-$TimeStamp" < "$TMPDIR/library.plexapp.sql-$TimeStamp" Result=$? if ! SQLiteOK $Result; then Output "Error $Result from Plex SQLite while importing from '$TMPDIR/library.plexapp.sql-$TimeStamp'" WriteLog "Repair - Cannot import main database from '$TMPDIR/library.plexapp.sql-$TimeStamp' - FAIL ($Result)" Output "Cannot continue." Fail=1 - continue + return 1 fi - printf '(blobs)..' - "$PLEX_SQLITE" $CPPL.blobs.db-$TimeStamp < "$TMPDIR/blobs.plexapp.sql-$TimeStamp" + Output "Importing Blobs DB." + "$PLEX_SQLITE" "$TMPDIR/$CPPL.blobs.db-REPAIR-$TimeStamp" < "$TMPDIR/blobs.plexapp.sql-$TimeStamp" Result=$? if ! SQLiteOK $Result ; then Output "Error $Result from Plex SQLite while importing from '$TMPDIR/blobs.plexapp.sql-$TimeStamp'" WriteLog "Repair - Cannot import blobs database from '$TMPDIR/blobs.plexapp.sql-$TimeStamp' - FAIL ($Result)" Output "Cannot continue." Fail=1 - continue + return 1 fi # Made it to here, now verify - echo done. - Output "Successfully imported data from exported SQL files." + Output "Successfully imported SQL data." WriteLog "Repair - Import - PASS" # Verify databases are intact and pass testing Output "Verifying databases integrity after importing." # Check main DB - if CheckDB $CPPL.db-$TimeStamp ; then - SizeStart=$(GetSize $CPPL.db) - SizeFinish=$(GetSize $CPPL.db-$TimeStamp) + if CheckDB "$TMPDIR/$CPPL.db-REPAIR-$TimeStamp" ; then + SizeStart=$(GetSize "$CPPL.db") + SizeFinish=$(GetSize "$TMPDIR/$CPPL.db-REPAIR-$TimeStamp") Output "Verification complete. PMS main database is OK." WriteLog "Repair - Verify main database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)." else @@ -910,9 +810,9 @@ do fi # Check blobs DB - if CheckDB $CPPL.blobs.db-$TimeStamp ; then - SizeStart=$(GetSize $CPPL.blobs.db) - SizeFinish=$(GetSize $CPPL.blobs.db-$TimeStamp) + if CheckDB "$TMPDIR/$CPPL.blobs.db-REPAIR-$TimeStamp" ; then + SizeStart=$(GetSize "$CPPL.blobs.db") + SizeFinish=$(GetSize "$TMPDIR/$CPPL.blobs.db-REPAIR-$TimeStamp") Output "Verification complete. PMS blobs database is OK." WriteLog "Repair - Verify blobs database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)." else @@ -924,20 +824,17 @@ do # If not failed, move files normally if [ $Fail -eq 0 ]; then - Output "Saving current databases with '-ORIG-$TimeStamp'" - [ -e $CPPL.db ] && mv $CPPL.db "$TMPDIR/$CPPL.db-ORIG-$TimeStamp" - [ -e $CPPL.blobs.db ] && mv $CPPL.blobs.db "$TMPDIR/$CPPL.blobs.db-ORIG-$TimeStamp" + Output "Saving current databases with '-BACKUP-$TimeStamp'" + [ -e $CPPL.db ] && mv $CPPL.db "$TMPDIR/$CPPL.db-BACKUP-$TimeStamp" + [ -e $CPPL.blobs.db ] && mv $CPPL.blobs.db "$TMPDIR/$CPPL.blobs.db-BACKUP-$TimeStamp" - Output "Making imported databases active" - mv $CPPL.db-$TimeStamp $CPPL.db - mv $CPPL.blobs.db-$TimeStamp $CPPL.blobs.db + Output "Making repaired databases active" + mv "$TMPDIR/$CPPL.db-REPAIR-$TimeStamp" $CPPL.db + mv "$TMPDIR/$CPPL.blobs.db-REPAIR-$TimeStamp" $CPPL.blobs.db - Output "Import complete. Please check your library settings and contents for completeness." + Output "Repair complete. Please check your library settings and contents for completeness." Output "Recommend: Scan Files and Refresh all metadata for each library section." - # Remove .sql temp files from $TMPDIR - # rm -f "$TMPDIR"/*.sql-* - # Ensure WAL and SHM are gone [ -e $CPPL.blobs.db-wal ] && rm -f $CPPL.blobs.db-wal [ -e $CPPL.blobs.db-shm ] && rm -f $CPPL.blobs.db-shm @@ -954,21 +851,24 @@ do WriteLog "Repair - PASS" SetLast "Repair" "$TimeStamp" + return 0 else - rm -f $CPPL.db-$TimeStamp - rm -f $CPPL.blobs.db-$TimeStamp + rm -f "$TMPDIR/$CPPL.db-REPAIR-$TimeStamp" + rm -f "$TMPDIR/$CPPL.blobs.db-REPAIR-$TimeStamp" Output "Repair has failed. No files changed" WriteLog "Repair - $TimeStamp - FAIL" + CheckedDB=0 Retain=1 + return 1 fi - continue +} - # 5. Replace database from backup copy - elif [ $Choice -eq 5 ]; then +##### DoReplace +DoReplace() { - # If Databases already checked, confirm the user really wants to do this + # If Databases already checked, confirm the user really wants to do this Confirmed=0 Fail=0 if CheckDatabases "Replace"; then @@ -979,19 +879,26 @@ do if [ $Damaged -eq 1 ] || [ $Confirmed -eq 1 ]; then # Get list of dates to use - Dates=$(GetDates) + Dates="$(GetDates)" # If no backups, error and exit if [ "$Dates" = "" ] && [ $Damaged -eq 1 ]; then Output "Database is damaged and no backups avaiable." Output "Only available option is Repair." WriteLog "Replace - Scan for usable candidates - FAIL" - continue + return 1 fi Output "Checking for a usable backup." Candidate="" + # Make certain there is ample free space + if ! FreeSpaceAvailable ; then + Output "ERROR: Insufficient free space available on $AppSuppDir. Cannot continue + WriteLog "REPLACE - Insufficient free space available on $AppSuppDir. Aborted. + return 1 + fi + Output "Database backups available are: $Dates" for i in $Dates do @@ -1015,18 +922,18 @@ do if [ $UseThis -eq 1 ]; then # Move database, wal, and shm (keep safe) with timestamp - Output "Saving current databases with timestamp: '-ORIG-$TimeStamp'" + Output "Saving current databases with timestamp: '-BACKUP-$TimeStamp'" for j in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm" do - [ -e $CPPL.$j ] && mv -f $CPPL.$j "$TMPDIR/$CPPL.$j-ORIG-$TimeStamp" + [ -e $CPPL.$j ] && mv -f $CPPL.$j "$TMPDIR/$CPPL.$j-BACKUP-$TimeStamp" done WriteLog "Replace - Move Files - PASS" # Copy this backup into position as primary Output "Copying backup database $Candidate to use as new database." - cp -p $CPPL.db-$Candidate $CPPL.db-$TimeStamp + cp -p $CPPL.db-$Candidate $CPPL.db-REPLACE-$TimeStamp Result=$? if [ $Result -ne 0 ]; then @@ -1038,7 +945,7 @@ do WriteLog "Replace - Copy $CPPL.db-$i - PASS" fi - cp -p $CPPL.blobs.db-$Candidate $CPPL.blobs.db-$TimeStamp + cp -p $CPPL.blobs.db-$Candidate $CPPL.blobs.db-REPLACE-$TimeStamp Result=$? if [ $Result -ne 0 ]; then @@ -1055,12 +962,12 @@ do # Final checks Output "Copy complete. Performing final check" - if CheckDB $CPPL.db-$TimeStamp && \ - CheckDB $CPPL.blobs.db-$TimeStamp ; then + if CheckDB $CPPL.db-REPLACE-$TimeStamp && \ + CheckDB $CPPL.blobs.db-REPLACE-$TimeStamp ; then # Move into position as active - mv $CPPL.db-$TimeStamp $CPPL.db - mv $CPPL.blobs.db-$TimeStamp $CPPL.blobs.db + mv $CPPL.db-REPLACE-$TimeStamp $CPPL.db + mv $CPPL.blobs.db-REPLACE-$TimeStamp $CPPL.blobs.db # done Output "Database recovery and verification complete." @@ -1082,7 +989,7 @@ do for k in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm" do - [ -e "$TMPDIR/$CPPL.$k-ORIG-$TimeStamp" ] && mv -f "$TMPDIR/$CPPL.$k-ORIG-$TimeStamp" $CPPL.$k + [ -e "$TMPDIR/$CPPL.$k-BACKUP-$TimeStamp" ] && mv -f "$TMPDIR/$CPPL.$k-BACKUP-$TimeStamp" $CPPL.$k done WriteLog "Replace - Verify databases - FAIL" Fail=1 @@ -1101,176 +1008,726 @@ do WriteLog "Replace - Select candidate - FAIL" fi fi - - # 6. - Undo last successful action - elif [ $Choice -eq 6 ]; then +} - # Confirm there is something to undo - if [ "$LastTimestamp" != "" ]; then +##### VACUUM +DoVacuum(){ - # Educate user - echo " " - echo "'Undo' restores the databases to the state prior to the last SUCCESSFUL action." - echo "If any action fails before it completes, that action is automatically undone for you." - echo "Be advised: Undo restores the databases to their state PRIOR TO the last action of 'Vacuum', 'Reindex', or 'Replace'" - echo "WARNING: Once Undo completes, there will be nothing more to Undo untl another successful action is completed" - echo " " + # Clear flags + Fail=0 + Damaged=0 - if ConfirmYesNo "Undo '$LastName' performed at timestamp '$LastTimestamp' ? "; then + # Check databases before Indexing if not previously checked + if ! CheckDatabases "Vacuum " ; then + Damaged=1 + Fail=1 + fi - Output "Undoing $LastName ($LastTimestamp)" - for j in "db" "db-wal" "db-shm" "blobs.db" "blobs.db-wal" "blobs.db-shm" - do - [ -e "$TMPDIR/$CPPL.$j-ORIG-$LastTimestamp" ] && mv -f "$TMPDIR/$CPPL.$j-ORIG-$LastTimestamp" $CPPL.$j - done + # If damaged, exit + if [ $Damaged -eq 1 ]; then + Output "Databases are damaged. Vacuum operation not available. Please repair or replace first." + WriteLog "Vacuum - Databases damaged." + return 1 + fi - Output "Undo complete." - WriteLog "Undo - Undo ${LastName}, TimeStamp $LastTimestamp" - SetLast "Undo" "" - fi + # Make a backup + Output "Backing up databases" + if ! MakeBackups "Vacuum "; then + Output "Error making backups. Cannot continue." + WriteLog "Vacuum - MakeBackups - FAIL" + Fail=1 + return 1 + else + WriteLog "Vacuum - MakeBackups - PASS" + fi - else - Output "Nothing to undo." - WriteLog "Undo - Nothing to Undo." + # Start vacuuming + Output "Vacuuming main database" + SizeStart=$(GetSize $CPPL.db) + + # Vacuum it + "$PLEX_SQLITE" $CPPL.db 'VACUUM;' + Result=$? + + if SQLiteOK $Result; then + SizeFinish=$(GetSize $CPPL.db) + Output "Vacuuming main database successful (Size: ${SizeStart}MB/${SizeFinish}MB)." + WriteLog "Vacuum - Vacuum main database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)." + else + Output "Vaccuming main database failed. Error code $Result from Plex SQLite" + WriteLog "Vacuum - Vacuum main database - FAIL ($Result)" + Fail=1 + fi + + Output "Vacuuming blobs database" + SizeStart=$(GetSize $CPPL.blobs.db) + + # Vacuum it + "$PLEX_SQLITE" $CPPL.blobs.db 'VACUUM;' + Result=$? + + if SQLiteOK $Result; then + SizeFinish=$(GetSize $CPPL.blobs.db) + Output "Vacuuming blobs database successful (Size: ${SizeStart}MB/${SizeFinish}MB)." + WriteLog "Vacuum - Vacuum blobs database - PASS (Size: ${SizeStart}MB/${SizeFinish}MB)." + else + Output "Vaccuming blobs database failed. Error code $Result from Plex SQLite" + WriteLog "Vacuum - Vacuum blobs database - FAIL ($Result)" + Fail=1 + fi + + if [ $Fail -eq 0 ]; then + Output "Vacuum complete." + WriteLog "Vacuum - PASS" + SetLast "Vacuum" "$TimeStamp" + else + Output "Vacuum failed." + WriteLog "Vacuum - FAIL" + RestoreSaved "$TimeStamp" + fi +} + +##### (import) Viewstate/Watch history from another DB and import +DoImport(){ + + if ! FreeSpaceAvailable; then + Output "Unable to make backups before importing. Insufficient free space available on $AppSuppDir." + WriteLog "Import - Insufficient free disk space for backups." + return 1 + fi + + printf "Pathname of database containing watch history to import: " + read Input + + # Did we get something? + [ "$Input" = "" ] && return 0 + + # Go see if it's a valid database + if [ ! -f "$Input" ]; then + Output "'$Input' does not exist." + return 1 + fi + + Output "" + WriteLog "Import - Attempting to import watch history from '$Input' " + + # Confirm our databases are intact + if ! CheckDatabases "Import "; then + Output "Error: PMS databases are damaged. Repair needed. Refusing to import." + WriteLog "Import - Verify main database - FAIL" + return 1 + fi + + # Check the given database + Output "Checking database '$Input'" + if ! CheckDB "$Input"; then + Output "Error: Given database '$Input' is damaged. Repair needed. Database not trusted. Refusing to import." + WriteLog "Import - Verify '$Input' - FAIL" + return 1 + fi + WriteLog "Import - Verify '$Input' - PASS" + Output "Check complete. '$Input' is OK." + + + # Make a backup + Output "Backing up PMS databases" + if ! MakeBackups "Import "; then + Output "Error making backups. Cannot continue." + WriteLog "Import - MakeBackups - FAIL" + Fail=1 + return 1 + fi + WriteLog "Import - MakeBackups - PASS" + + + # Export viewstate from DB + Output "Exporting Viewstate & Watch history" + echo ".dump metadata_item_settings metadata_item_views " | "$PLEX_SQLITE" "$Input" | grep -v TABLE | grep -v INDEX > "$TMPDIR/Viewstate.sql-$TimeStamp" + + # Make certain we got something usable + if [ $(wc -l "$TMPDIR/Viewstate.sql-$TimeStamp" | awk '{print $1}') -lt 1 ]; then + Output "No viewstates or history found to import." + WriteLog "Import - Nothing to import - FAIL" + return 1 + fi + + # Make a working copy to import into + Output "Preparing to import Viewstate and History data" + cp -p $CPPL.db "$TMPDIR/$CPPL.db-IMPORT-$TimeStamp" + Result=$? + + if [ $Result -ne 0 ]; then + Output "Error $Result while making a working copy of the PMS main database." + Output " File permissions? Disk full?" + WriteLog "Import - Prepare: Make working copy - FAIL" + return 1 + fi + + # Import viewstates into working copy (Ignore constraint errors during import) + printf 'Importing Viewstate & History data...' + "$PLEX_SQLITE" "$TMPDIR/$CPPL.db-IMPORT-$TimeStamp" < "$TMPDIR/Viewstate.sql-$TimeStamp" 2> /dev/null + +# # Purge duplicates (violations of unique constraint) +# cat < 1); +#EOF + + # Make certain the resultant DB is OK + Output " done." + Output "Checking database following import" + + if ! CheckDB "$TMPDIR/$CPPL.db-IMPORT-$TimeStamp" ; then + + # Import failed discard + Output "Error: Error code $Result during import. Import corrupted database." + Output " Discarding import attempt." + + rm -f "$TMPDIR/$CPPL.db-IMPORT-$TimeStamp" + + WriteLog "Import - Import: $Input - FAIL" + return 1 + fi + + # Import successful; switch to new DB + Output "PMS main database is OK. Making imported database active" + WriteLog "Import - Import: Making imported database active" + + # Move from tmp to active + mv "$TMPDIR/$CPPL.db-IMPORT-$TimeStamp" $CPPL.db + + # We were successful + Output "Viewstate import successful." + WriteLog "Import - Import: $Input - PASS" + + # We were successful + SetLast "Import" "$TimeStamp" + return 0 +} + +##### IsRunning (True if PMS is running) +IsRunning(){ + [ "$($PIDOF 'Plex Media Server')" != "" ] && return 0 + return 1 +} + +##### DoStart (Start PMS if able) +DoStart(){ + + if [ $HaveStartStop -eq 0 ]; then + Output "Start/Stop feature not available" + WriteLog "Start/Stop feature not available" + return 1 + else + + # Check if PMS running + if IsRunning; then + WriteLog "Start - PASS - PMS already runnning" + Output "Start not needed. PMS is running." + return 0 fi - # 7. - Get Viewstate/Watch history from another DB and import - elif [ $Choice -eq 7 ]; then - - printf "Pathname of database containing watch history to import: " - read Input - - # Did we get something? - [ "$Input" = "" ] && continue - - # Go see if it's a valid database - if [ ! -f "$Input" ]; then - Output "'$Input' does not exist." - continue - fi - - Output " " - WriteLog "Import - Attempting to import watch history from '$Input' " - - # Confirm our databases are intact - if ! CheckDatabases "Import "; then - Output "Error: PMS databases are damaged. Repair needed. Refusing to import." - WriteLog "Import - Verify main database - FAIL" - continue - fi - - # Check the given database - Output "Checking database '$Input'" - if ! CheckDB "$Input"; then - Output "Error: Given database '$Input' is damaged. Repair needed. Database not trusted. Refusing to import." - WriteLog "Import - Verify '$Input' - FAIL" - continue - fi - WriteLog "Import - Verify '$Input' - PASS" - Output "Check complete. '$Input' is OK." - - - # Make a backup - Output "Backing up PMS databases" - if ! MakeBackups "Import "; then - Output "Error making backups. Cannot continue." - WriteLog "Import - MakeBackups - FAIL" - Fail=1 - continue - fi - WriteLog "Import - MakeBackups - PASS" - - - # Export viewstate from DB - Output "Exporting Viewstate & Watch history" - echo ".dump metadata_item_settings metadata_item_views " | "$PLEX_SQLITE" "$Input" | grep -v TABLE | grep -v INDEX > "$TMPDIR/Viewstate.sql-$TimeStamp" - - # Make certain we got something usable - if [ $(wc -l "$TMPDIR/Viewstate.sql-$TimeStamp" | awk '{print $1}') -lt 1 ]; then - Output "No viewstates or history found to import." - WriteLog "Import - Nothing to import - FAIL" - continue - fi - - # Make a working copy to import into - Output "Preparing to import Viewstate and History data" - cp -p $CPPL.db $CPPL.db-$TimeStamp + Output "Starting PMS." + $StartCommand > /dev/null 2> /dev/null Result=$? - if [ $Result -ne 0 ]; then - Output "Error $Result while making a working copy of the PMS main database." - Output " File permissions? Disk full?" - WriteLog "Import - Prepare: Make working copy - FAIL" - continue - fi - - # Import viewstates into working copy - printf 'Importing Viewstate & History data...' - "$PLEX_SQLITE" $CPPL.db-$TimeStamp < "$TMPDIR/Viewstate.sql-$TimeStamp" 2> /dev/null - - # Make certain the resultant DB is OK - Output " done." - Output "Checking database following import" - - if ! CheckDB $CPPL.db-$TimeStamp ; then - - # Import failed discard - Output "Error: Error code $Result during import. Import corrupted database." - Output " Discarding import attempt." - - rm -f $CPPL.db-$TimeStamp - - WriteLog "Import - Import: $Input - FAIL" - continue - fi - - # Import successful; switch to new DB - Output "PMS main database is OK. Making imported database active" - WriteLog "Import - Import: Making imported database active" - - # Move from tmp to active - mv $CPPL.db-$TimeStamp $CPPL.db - - # We were successful - Output "Viewstate import successful." - WriteLog "Import - Import: $Input - PASS" - - # We were successful - SetLast "Import" "$TimeStamp" - continue - - # 8. - Show Logfile - elif [ $Choice -eq 8 ]; then - - echo ================================================================================== - cat "$LOGFILE" - echo ================================================================================== - - # 9. - Exit - elif [ $Choice -eq 9 ]; then - - # Ask questions on graceful exit - if [ $Exit -eq 0 ]; then - # Ask if the user wants to remove the DBTMP directory and all backups thus far - if ConfirmYesNo "Ok to remove temporary databases/workfiles for this session?" ; then - - # Here it goes - Output "Deleting all temporary work files." - WriteLog "Exit - Delete temp files." - rm -rf "$TMPDIR" - else - Output "Retaining all temporary work files." - WriteLog "Exit - Retain temp files." - fi + if [ $Result -eq 0 ]; then + WriteLog "Start - PASS" + Output "Started PMS" else - Output "Unexpected exit command. Keeping all temporary work files." - WriteLog "EOFExit - Retain temp files." + WriteLog "Start - FAIL ($Result)" + Output "Could not start PMS. Error code: $Result" + fi + fi + return $Result +} + +##### DoStop (Stop PMS if able) +DoStop(){ + if [ $HaveStartStop -eq 0 ]; then + Output "Start/Stop feature not available" + WriteLog "Start/Stop feature not available" + return 1 + else + + Output "Stopping PMS." + $StopCommand > /dev/null 2> /dev/null + Result=$? + Count=10 + while [ $Result -eq 0 ] && IsRunning && [ $Count -gt 0 ] + do + sleep 1 + Count=$((Count - 1)) + done + + if [ $Result -eq 0 ]; then + WriteLog "Stop - PASS" + Output "Stopped PMS." + else + WriteLog "Stop - FAIL ($Result)" + Output "Could not stop PMS. Error code: $Result" + fi + fi + return $Result +} + +##### UpdateTimestamp +DoUpdateTimestamp() { + TimeStamp="$(date "+%Y-%m-%d_%H.%M.%S")" +} + +############################################################# +# Main utility begins here # +############################################################# + +# Initialize LastName LastTimestamp +SetLast "" "" + +# Are we scripted (command line args) +Scripted=0 +[ "$1" != "" ] && Scripted=1 + +# Identify this host +if ! HostConfig; then + Output 'Error: Unknown host. Current supported hosts are: QNAP, Syno, Netgear, Mac, ASUSTOR, WD (OS5), Linux wkstn/svr' + Output ' Current supported container images: Plexinc, LinuxServer, HotIO, & BINHEX' + exit 1 +fi + +# We might not be root but minimally make sure we have write access +if [ ! -w "$DBDIR" ]; then + echo ERROR: Cannot write to Databases directory. Insufficient privilege. + exit 2 +fi + +echo " " +# echo Detected Host: $HostType +WriteLog "============================================================" +WriteLog "Session start: Host is $HostType" + +# Make sure we have a logfile +touch "$LOGFILE" + +# Basic checks; PMS installed +if [ ! -f "$PLEX_SQLITE" ] ; then + Output "PMS is not installed. Cannot continue. Exiting." + WriteLog "PMS not installed." + exit 1 +fi + +# Set tmp dir so we don't use RAM when in DBDIR +DBTMP="./dbtmp" +mkdir -p "$DBDIR/$DBTMP" +export TMPDIR="$DBTMP" +export TMP="$DBTMP" + + +# If command line args then set flag +Scripted=0 +[ "$1" != "" ] && Scripted=1 + +# Can I write to the Databases directory ? +if [ ! -w "$DBDIR" ]; then + Output "ERROR: Cannot write to the Databases directory. Insufficient privilege or wrong UID. Exiting." + exit 1 +fi + +# Databases exist or Backups exist to restore from +if [ ! -f "$DBDIR/$CPPL.db" ] && \ + [ ! -f "$DBDIR/$CPPL.blobs.db" ] && \ + [ "$(echo com.plexapp.plugins.*-????-??-??)" = "com.plexapp.plugins.*-????-??-??" ]; then + + Output "Cannot locate databases. Cannot continue. Exiting." + WriteLog "Databases or backups not found." + exit 1 +fi + +# Work in the Databases directory +cd "$DBDIR" + +# Get the owning UID/GID before we proceed so we can restore +Owner="$(stat $STATFMT '%u:%g' $CPPL.db)" + +# Sanity check, We are either owner of the DB or root +if [ ! -w $CPPL.db ]; then + + Output "Do not have write permission to the Databases. Exiting." + WriteLog "No write permission to databases+. Exit." + exit 1 +fi + +# Run entire utility in a loop until all arguments used, EOF on input, or commanded to exit +while true +do + + echo " " + echo " " + echo " Plex Media Server Database Repair Utility ($HostType)" + echo " Version $Version" + echo " " + + + Choice=0; Exit=0; NullCommands=0 + + # Main menu loop + while [ $Choice -eq 0 ] + do + if [ $ShowMenu -eq 1 ] && [ $Scripted -eq 0 ]; then + + echo "" + echo "Select" + echo "" + [ $HaveStartStop -gt 0 ] && echo " 1 - 'stop' - Stop PMS" + [ $HaveStartStop -eq 0 ] && echo " 1 - 'stop' - (Not available. Stop manually)" + echo " 2 - 'automatic' - database check, repair/optimize, and reindex in one step." + echo " 3 - 'check' - Perform integrity check of database" + echo " 4 - 'vacuum' - Remove empty space from database" + echo " 5 - 'repair' - Repair/Optimize databases" + echo " 6 - 'reindex' - Rebuild database database indexes" + + [ $HaveStartStop -gt 0 ] && echo " 7 - 'start' - Start PMS" + [ $HaveStartStop -eq 0 ] && echo " 7 - 'start' - (Not available. Start manually)" + echo "" + echo " 8 - 'import' - Import watch history from another database independent of Plex. (risky)" + echo " 9 - 'replace' - Replace current databases with newest usable backup copy (interactive)" + echo " 10 - 'show' - Show logfile" + echo " 11 - 'status' - Report status of PMS (run-state and databases)" + echo " 12 - 'undo' - Undo last successful command" + echo "" + + echo " 99 - exit" + fi + if [ $Scripted -eq 0 ]; then + echo "" + printf "Enter command # -or- command name (4 char min) : " fi - WriteLog "Session end." - WriteLog "============================================================" - exit 0 - fi + # Watch for null command whether scripted or not. + if [ "$1" != "" ]; then + Input="$1" + # echo "$1" + shift + else + read Input + + # Handle EOF/forced exit + if [ "$Input" = "" ] ; then + if [ $NullCommands -gt 4 ]; then + Output "Unexpected EOF / End of command line options, Exiting" + Input="exit" && Exit=1 + else + NullCommands=$(($NullCommands + 1)) + [ $NullCommands -eq 4 ] && echo "WARNING: Next empty command exits as EOF. " + continue + fi + else + NullCommands=0 + fi + fi + + # Update timestamp + DoUpdateTimestamp + + # Validate command input + Command="$(echo $Input | tr '[A-Z]' '[a-z]' | awk '{print $1}')" + echo " " + + case "$Command" in + + # Stop PMS (if available this host) + 1|stop) + + DoStop + ;; + + + # Automatic of all common operations + 2|auto*) + + # Get current status + RunState=0 + + # Check if PMS running + if IsRunning; then + RunState=1 + WriteLog "Auto - FAIL - PMS runnning" + Output "Unable to run automatic sequence. PMS is running. Please stop PlexMediaServer." + continue + fi + + # Is there enough room to work + if ! FreeSpaceAvailable; then + WriteLog "Auto - FAIL - Insufficient free space on $AppSuppDir" + Output "Error: Unable to run automatic sequence. Insufficient free space available on $AppSuppDir" + Output " Space needed = $SpaceNeeded MB, Space available = $SpaveAvailable MB" + continue + fi + + # Start auto + Output "Automatic Check,Repair,Index started." + WriteLog "Auto - START" + + # Check the databases (forced) + Output "" + if CheckDatabases "Check " force ; then + WriteLog "Check - PASS" + CheckedDB=1 + else + WriteLog "Check - FAIL" + CheckedDB=0 + fi + + # Now Repair + Output "" + if ! DoRepair; then + + WriteLog "Repair - FAIL" + WriteLog "Auto - FAIL" + CheckedDB=0 + + Output "Repair failed. Automatic mode cannot continue. Please repair with individual commands" + continue + else + WriteLog "Repair - PASS" + CheckedDB=1 + fi + + # Now Index + DoUpdateTimestamp + Output "" + if ! DoIndex; then + WriteLog "Index - FAIL" + WriteLog "Auto - FAIL" + CheckedDB=0 + + Output "Index failed. Automatic mode cannot continue. Please repair with individual commands" + continue + else + WriteLog "Reindex - PASS" + fi + + # All good to here + WriteLog "Auto - COMPLETED" + Output "Automatic Check, Repair/optimize, & Index successful." + ;; + + + # Check databases + 3|chec*) + + # Check if PMS running + if IsRunning; then + WriteLog "Check - FAIL - PMS runnning" + Output "Unable to check databases. PMS is running." + continue + fi + + # CHECK DBs + if CheckDatabases "Check " force ; then + WriteLog "Check - PASS" + CheckedDB=1 + else + WriteLog "Check - FAIL" + CheckedDB=0 + fi + ;; + + + # Vacuum + 4|vacu*) + + # Check if PMS running + if IsRunning; then + WriteLog "Vacuum - FAIL - PMS runnning" + Output "Unable to vacuum databases. PMS is running." + continue + fi + + DoVacuum + continue + ;; + + # Repair (Same as optimize but assumes damaged so doesn't check) + 5|repa*) + + # Check if PMS running + if IsRunning; then + WriteLog "Repair - FAIL - PMS runnning" + Output "Unable to repair databases. PMS is running." + continue + fi + + # Is there enough room to work + if ! FreeSpaceAvailable; then + WriteLog "Import - FAIL - Insufficient free space on $AppSuppDir" + Output "Error: Unable to repair database. Insufficient free space available on $AppSuppDir" + continue + fi + + + DoRepair + ;; + + + # Index databases + 6|rein*|inde*) + + # Check if PMS running + if IsRunning; then + WriteLog "Index - FAIL - PMS runnning" + Output "Unable to index databases. PMS is running." + continue + fi + + # Is there enough room to work + if ! FreeSpaceAvailable; then + WriteLog "Index - FAIL - Insufficient free space on $AppSuppDir" + Output "Error: Unable to perform processing. Insufficient free space available on $AppSuppDir" + continue + fi + + # First check the databases + if CheckDatabases Check; then + WriteLog "Check - PASS" + CheckedDB=1 + + # Now index + if DoIndex ; then + WriteLog "Reindex - PASS" + else + WriteLog "Reindex - FAIL" + fi + else + WriteLog "Check - FAIL" + CheckedDB=0 + fi + ;; + + + # Start PMS (if available this host) + 7|star*) + + DoStart + ;; + + + # Menu on/off control + menu*) + + # Choices are ON,OFF,YES,NO + Option="$(echo $Input | tr '[A-Z]' '[a-z]' | awk '{print $2}')" + + [ "$Option" = "on" ] && ShowMenu=1 + [ "$Option" = "yes" ] && ShowMenu=1 + [ "$Option" = "off" ] && ShowMenu=0 && echo Menu off: Reenable with \'menu on\' command + [ "$Option" = "no" ] && ShowMenu=0 && echo menu off: Reenable with \'menu on\' command + ;; + + + # Import watch history + 8|impo*) + + DoImport + ;; + + + # Replace (from PMS backup) + 9|repl*) + + # Check if PMS running + if IsRunning; then + WriteLog "Replace - FAIL - PMS runnning" + Output "Unable to replace database from a backup copy. PMS is running." + continue + fi + + # Is there enough room to work + if ! FreeSpaceAvailable; then + WriteLog "Replace - FAIL - Insufficient free space on $AppSuppDir" + Output "Error: Unable to replace from backups. Insufficient free space available on $AppSuppDir" + continue + fi + + DoReplace + ;; + + + # Show loggfile + 10|show*) + + echo ================================================================================== + cat "$LOGFILE" + echo ================================================================================== + ;; + + + # Current status of Plex and databases + 11|stat*) + + Output "" + Output "Status report: $(date)" + if IsRunning ; then + Output " PMS is running." + else + Output " PMS is stopped." + fi + + [ $CheckedDB -eq 0 ] && Output " Databases are not checked, Status unknown." + [ $CheckedDB -eq 1 ] && [ $Damaged -eq 0 ] && Output " Databases are OK." + [ $CheckedDB -eq 1 ] && [ $Damaged -eq 1 ] && Output " Databases were checked and are damaged." + Output "" + ;; + + + # Undo + 12|undo*) + + DoUndo + ;; + + + # Quit/Exit + 99|exit|quit) + + # if cmd line mode, exit clean + if [ $Scripted -eq 1 ]; then + rm -rf $TMPDIR + WriteLog "Exit - Delete temp files." + + else + # Ask questions on interactive exit + if [ $Exit -eq 0 ]; then + # Ask if the user wants to remove the DBTMP directory and all backups thus far + if [ "$Input" = "exit" ] && ConfirmYesNo "Ok to remove temporary databases/workfiles for this session?" ; then + # There it goes + Output "Deleting all temporary work files." + WriteLog "Exit - Delete temp files." + rm -rf "$TMPDIR" + else + Output "Retaining all temporary work files." + WriteLog "Exit - Retain temp files." + fi + else + Output "Unexpected exit command. Keeping all temporary work files." + WriteLog "EOFExit - Retain temp files." + fi + fi + + WriteLog "Session end. $(date)" + WriteLog "============================================================" + exit 0 + ;; + + # Unknown command + *) + WriteLog "Unknown command: '$Input'" + Output "ERROR: Unknown command: '$Input'" + ;; + + esac + done done exit 0 diff --git a/README.md b/README.md index da62508..529a698 100644 --- a/README.md +++ b/README.md @@ -13,28 +13,71 @@ DBRepair provides database repair and maintenance for the most common Plex Medi It is a simple menu-driven utility with a command line backend. ## Situations and errors commonly seen include: - 1. Database is malformed - 2. Corruption - 3. Damaged indexes - 4. Database bloat after optimization - 5. Searching gets sluggish + 1. Searching is sluggish + 2. Database is malformed / damaged / corrupted + 3. Database has bloated from media addition or changes + 4. Damaged indexes damaged ## Functions provided - 1. Check the databases - 2. Vacuum the databases - 3. Reindex the databases - 4. Repair damaged databases - 5. Restore databases from most recent backup - 6. Import Viewstate / Watch history from another PMS database - 7. Undo (undo last operation) - 8. Show logfile of past actions and status + The utility accepts command names. + Command names may be upper/lower case and may also be abbreviated (4 character minimum). + + The following commands (or their number), listed in alphabetical order, are accepted as input. + + AUTO(matic) - Automatically check, repair/optimize, and reindex the databases in one step. + CHEC(k) - Check the main and blob databases integrity + EXIT - Exit the utility + IMPO(rt) - Import viewstate / watch history from another database + REIN(dex) - Rebuild the database indexes + REPL(ace) - Replace the existing databases with a PMS-generated backup + SHOW - Show the log file + STAR(t) - Start PMS (not available on all platforms) + STOP - Stop PMS (not available on all platforms) + UNDO - UNDO the last operation + VACU(um) - Vacuum the databases + + +### The menu + + The menu gives you the option to enter either a 'command number' or the 'command name/abbreviation'. + For clarity, each command's name is 'quoted'. + + + Plex Media Server Database Repair Utility (_host_configuration_name_) + Version v1.0.0 + + Select + + 1 - 'stop' PMS (if available) + 2 - 'automatic' database check, repair/optimize, and reindex in one step. + 3 - 'check' database + 4 - 'vacuum' database + 5 - 'repair' / 'optimize' database + 6 - 'reindex' database + 7 - 'start' PMS (if available) + 8 - 'import' viewstate (Watch history) from another PMS database + 9 - 'replace' current database with newest usable backup copy (interactive) + 10 - 'show' logfile + 11 - 'status' of PMS (Stop/Run and databases) + 12 - 'undo' - Undo last successful command + + 99 - exit + + Enter command # -or- command name (4 char min) : + + ## Hosts currently supported 1. Apple (MacOS) 2. ASUSTOR - 3. Docker (Plex,inc, Linuxserver.io, BinHex & HOTIO via 'docker exec') + 3. Docker containers via 'docker exec' command (inside the running container environment) + - Plex,inc. + - Linuxserver.io + - BINHEX + - HOTIO + - Podman (libgpod) 4. Linux workstation & server 5. Netgear (OS5 Linux-based systems) 6. QNAP (QTS & QuTS) @@ -53,140 +96,128 @@ It is a simple menu-driven utility with a command line backend. ASUSTOR | Public | /volume1/Public binhex | N/A | Container root (adjacent /config) Docker | N/A | Container root (adjacent /config) + Hotio | N/A | Container root (adjacent /config) Linux (wkstn/svr) | N/A | Anywhere Netgear (ReadyNAS) | "your_choice" | "/data/your_choice" QNAP (QTS/QuTS) | Public | /share/Public Synology (DSM 6) | Plex | /volume1/Plex (change volume as required) Synology (DSM 7) | PlexMediaServer | /volume1/PlexMediaServer (change volume as required) Western Digital | Public | /mnt/HD/HD_a2/Public (Does not support 'MyCloudHome' series) - - ``` -### To install & launch on general Linux or most Linux NAS platforms: (Showing with v0.6.1) + +### General installation and usage instructions + 1. Open your browser to https://github.com/ChuckPa/PlexDBRepair/releases/latest - 2. Download the source code (tar.gz) file - 3. Place the tar.gz file in the appropriate directory on the system you'll use it. - 4. Open a command line session (usually Terminal or SSH) - 5. Elevate privilege level to root (sudo) - 6. Extract the utility from the tar or zip file - 7. 'cd' into the extraction directory - 8. Give the utility 'execute' permission - 9. Invoke the utility + 2. Download the source code (tar.gz or ZIP) file + + 3. Knowing the file name will always be of the form 'PlexDBRepair-X.Y.Z.tar.gz' + -- where X.Y.Z is the release number. Use the real values in place of X, Y, and Z. + 4. Place the tar.gz file in the appropriate directory on the system you'll use it. + 5. Open a command line session (usually Terminal or SSH) + 6. Elevate privilege level to root (sudo) if needed. + 7. Extract the utility from the tar or zip file + 8. 'cd' into the extraction directory + 9. Give DBRepair.sh 'execute' permission (chmod +x) + 10. Invoke ./DBRepair.sh -### To install & launch on Synology DSM 6 (Showing with v0.6.1) -``` + + +### EXAMPLE: To install & launch on Synology DSM 6 + cd /volume1/Plex sudo bash - tar xf PlexDBRepair-0.6.4.tar.gz - cd PlexDBRepair-0.6.4 + tar xf PlexDBRepair-x.y.z.tar.gz + cd PlexDBRepair-x.y.z chmod +x DBRepair.sh ./DBRepair.sh -``` -### To launch from the commaand line inside a Docker container: -``` + +### EXAMPLE: Using DBRepair inside containers (manual start/stop included) + +#### (Select containers allow stopping/starting PMS from the menu. See menu for details) + sudo docker exec -it plex /bin/bash - # Stop Plex when using official Plex,inc image - /plex_service.sh -d ---or-- - # Stop Plex when using Linuxserver.io Plex image - s6-svc -d /var/run/service/svc-plex ---or-- - # Stop Plex in binhex containers - kill -15 $(pidof 'Plex Media Server') ---or-- - # Stop Plex in HOTIO containers - s6-svc -d /run/service/plex - - # extract from downloaded version file name then cd into directory - tar xf PlexDBRepair-0.6.4.tar.gz - cd PlexDBRepair-0.6.4 + tar xf PlexDBRepair-1.0.0.tar.gz + cd PlexDBRepair-1.0.0 chmod +x DBRepair.sh ./DBRepair.sh ``` -### To launch from the command line on Linux +### EXAMPLE: Using DBRepair on regular Linux native host (Workstation/Server) ``` sudo bash - systemctl stop plexmediaserver cd /path/to/DBRepair.tar - tar xf PlexDBRepair-0.6.1.tar.gz - cd PlexDBRepair-0.6.1 + tar xf PlexDBRepair-1.0.0.tar.gz + cd PlexDBRepair-1.0.0 chmod +x DBRepair.sh - ./DBRepair.sh + ./DBRepair.sh stop auto start exit ``` -### To launch from the command line on MacOS (on the administrator account) +### EXAMPLE: Using DBRepair from the command line on MacOS (on the administrator account) ``` osascript -e 'quit app "Plex Media Server"' cd ~/Downloads - tar xvf PlexDBRepai PlexDBRepair-0.6.1.tar.gz - cd PlexDBRepai PlexDBRepair-0.6.1 + tar xvf PlexDBRepai PlexDBRepair-1.0.0.tar.gz + cd PlexDBRepai PlexDBRepair-1.0.0 chmod +x DBRepair.sh ./DBRepair.sh -``` -## The menu - Plex Media Server Database Repair Utility - - Select - - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit - -Enter choice: ## Typical usage -``` + This utility can only operate on PMS when PMS is in the stopped state. If PMS is running when you startup the utility, it will tell you. - A. Database is malformed (Backups of com.plexapp.plugins.library.db and com.plexap.plugins.library.blobs.db available) - 1. Check - (Option 1) - Confirm either main or blobs database is damaged - 2. Replace - (Option 5) - Use the most recent valid backup -- OR -- Option 4 (Repair). Check date/time for best action. - -- If Replace fails, use Repair (Option 4) - -- Replace can fail if the database has been damaged for a long time. - 3. Reindex - (Option 3) - Generate new indexes so PMS doesn't need to at startup +These examples + + A. The most common usage will be the "Automatic" function. + + Automatic mode is where DBRepair determines which steps are needed to make your database run optimally. + For most users, Automatic is equivalent to 'Check, Repair, Reindex'. + This repairs minor damage, vacuums out all the unused records, and rebuilds search indexes in one step. + + B. Database is malformed (Backups of com.plexapp.plugins.library.db and com.plexap.plugins.library.blobs.db available) + Note: You may attempt "Repair" sequence + + 1. (3) Check - Confirm either main or blobs database is damaged + 2. (9) Replace - Use the most recent valid backup -- OR -- (5) Repair. Check date/time stamps for best action. + -- If Replace fails, use Repair (5) + -- (Replace can fail if the database has been damaged for a long time.) + 3. (6) Reindex - Generate new indexes so PMS doesn't need to at startup + 4. (99) Exit + + C. Database is malformed - No Backups + 1. (3) Check - Confirm either main or blobs database is damaged + 2. (5) Repair - Salavage as much as possible from the databases and rebuild them into a usable database. + 3. (6) Reindex - Generate new indexes so PMS doesn't need to at startup + 4. (99) Exit + + C. Database sizes excessively large when compared to amount of media indexed (item count) + 1. (3) Check - Make certain both databases are fully intact (repair if needed) + 2. (4) Vacuum - Instruct SQLite to rebuild its tables and recover unused space. + 3. (6) Reindex - Rebuild Indexes. + 4. (99) Exit + + D. User interface has become 'sluggish' as more media was added + 1. (3) Check - Confirm there is no database damage + 2. (5) Repair - You are not really repairing. You are rebuilding the DB in perfect sorted order. + 3. (6) Reindex - Rebuild Indexes. 4. Exit - (Option 9) - B. Database is malformed - No Backups - 1. Check - (Option 1) - Confirm either main or blobs database is damaged - 2. Repair - (Option 4) - Salavage as much as possible from the databases and rebuild them into a usable database. - 3. Reindex - (Option 3) - Generate new indexes so PMS doesn't need to at startup - 4. Exit - (Option 9) - - C. Database sizes excessively large when compared to amount of media indexed (item count) - 1. Check - (Option 1) - Make certain both databases are fully intact (repair if needed) - 2. Vacuum - (Option 2) - Instruct SQLite to rebuild its tables and recover unused space. - 3. Reinex - (Option 3) - Rebuild Indexes. - 4. Exit - (Option 9) - - D. User interface has become 'sluggish' as more media was added - 1. Check - (Option 1) - Confirm there is no database damage - 2. Repair - (Option 4) - You are not really repairing. You are rebuilding the DB in perfect sorted order. - 3. Reindex - (Option 3) - Rebuild Indexes. - 4. Exit - (Option 9) - - E. Undo + E. Undo Undo is a special case where you need the utility to backup ONE step. This is rarely needed. The only time you might want/need to backup one step is if Replace leaves you worse off than you were before. In this case, UNDO then Repair. Undo can only undo the single most-recent action. + (Note: In a future release, you will be able to 'undo' every action taken until the DBs are in their original state) Special considerations: 1. As stated above, this utilty requires PMS to be stopped in order to do what it does. - 2. *TRICK* - This utility CAN sit at the menu prompt with PMS running. + 2. - This utility CAN sit at the menu prompt with PMS running. - You did a few things and want to check BEFORE exiting the utility - If you don't like how it worked out, -- STOP PMS @@ -195,9 +226,9 @@ Special considerations: 3. When satisfied, Exit the utility. - There is no harm in keeping the database temp files (except for space used) - ALL database temps are named with date-time stamps in the name to avoid confusion. - 4. The Logfile (Option 8) shows all actions performed WITH the timestamp so you can locate intermediate databases + 4. The Logfile ('show' command) shows all actions performed WITH timestamp so you can locate intermediate databases if desired for special / manual recovery cases. -``` + ## Scripting support @@ -210,9 +241,9 @@ Special considerations: The command line arguments are the same as if typing at the menu. - Example: ./DBRepair.sh 1 4 3 9 + Example: ./DBRepair.sh stop auto start exit - This executes: Check, Repair, Reindex, and Exit commands + This executes: Stop PMS, Automatic (Check, Repair, Reindex), Start PMS, and Exit commands ## Exiting @@ -222,401 +253,363 @@ Special considerations: You'll be able to ask in the Plex forums about what to do. Be prepared to present the log file to them. -## Sample session +## Sample interactive session + This is a typical manual session if you aren't sure what to do and want the tool to decide. - This sample session shows all the features present. You won't use : - 1. PMS exclusive access to the databases interlock protecting your data - 2. Basic checks, vacuum, and reindex - 3. Full export/import (repair) which also reloads the database in perfect order - 4. Importing viewstate (watch history) data from another database (an older backup) - 5. What the log file details for you. - ``` -bash-4.4# pwd -/volume1/Plex -bash-4.4# ./DBRepair.sh -Plex Media Server is currently running, cannot continue. -Please stop Plex Media Server and restart this utility. -bash-4.4# ./DBRepair.sh -Plex Media Server is currently running, cannot continue. -Please stop Plex Media Server and restart this utility. +bash-4.4# #======================================================================================================= bash-4.4# ./DBRepair.sh Plex Media Server Database Repair Utility (Synology (DSM 7)) + Version v1.0.0 + Select - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit + 1 - 'stop' - Stop PMS + 2 - 'automatic' - database check, repair/optimize, and reindex in one step. + 3 - 'check' - Perform integrity check of database + 4 - 'vacuum' - Remove empty space from database + 5 - 'repair' - Repair/Optimize databases + 6 - 'reindex' - Rebuild database database indexes + 7 - 'start' - Start PMS + + 8 - 'import' - Import watch history from another database independent of Plex. (risky) + 9 - 'replace' - Replace current databases with newest usable backup copy (interactive) + 10 - 'show' - Show logfile + 11 - 'status' - Report status of PMS (run-state and databases) + 12 - 'undo' - Undo last successful command + + 99 - exit + +Enter command # -or- command name (4 char min) : 1 + +Stopping PMS. +Stopped PMS. + +Select + + 1 - 'stop' - Stop PMS + 2 - 'automatic' - database check, repair/optimize, and reindex in one step. + 3 - 'check' - Perform integrity check of database + 4 - 'vacuum' - Remove empty space from database + 5 - 'repair' - Repair/Optimize databases + 6 - 'reindex' - Rebuild database database indexes + 7 - 'start' - Start PMS + + 8 - 'import' - Import watch history from another database independent of Plex. (risky) + 9 - 'replace' - Replace current databases with newest usable backup copy (interactive) + 10 - 'show' - Show logfile + 11 - 'status' - Report status of PMS (run-state and databases) + 12 - 'undo' - Undo last successful command + + 99 - exit + +Enter command # -or- command name (4 char min) : auto -Enter choice: 1 Checking the PMS databases Check complete. PMS main database is OK. Check complete. PMS blobs database is OK. - - Plex Media Server Database Repair Utility (Synology (DSM 7)) - -Select - - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit - -Enter choice: 4 - -Exporting current databases using timestamp: 2022-11-16_15.56.06 -Export: (main)..(blobs)..done. +Exporting current databases using timestamp: 2023-02-25_16.15.11 +Exporting Main DB +Exporting Blobs DB Successfully exported the main and blobs databases. Proceeding to import into new databases. -Import: (main)..(blobs)..done. -Successfully imported data from exported SQL files. +Importing Main DB. +Importing Blobs DB. +Successfully imported data from SQL files. Verifying databases integrity after importing. Verification complete. PMS main database is OK. Verification complete. PMS blobs database is OK. -Saving current databases with '-ORIG-2022-11-16_15.56.06' +Saving current databases with '-BKUP-2023-02-25_16.15.11' Making imported databases active Import complete. Please check your library settings and contents for completeness. Recommend: Scan Files and Refresh all metadata for each library section. - - Plex Media Server Database Repair Utility (Synology (DSM 7)) - -Select - - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit - -Enter choice: 3 - Backing up of databases -Backup current databases with '-ORIG-2022-11-16_15.56.45' +Backup current databases with '-BKUP-2023-02-25_16.20.41' timestamp. Reindexing main database Reindexing main database successful. Reindexing blobs database Reindexing blobs database successful. Reindex complete. - - - Plex Media Server Database Repair Utility (Synology (DSM 7)) +Automatic Check,Repair/optimize,Index successful. Select - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit + 1 - 'stop' PMS + 2 - 'automatic' database check, repair/optimize, and reindex in one step. + 3 - 'check' database + 4 - 'vacuum' database + 5 - 'repair' / 'optimize' database + 6 - 'reindex' database + 7 - 'start' PMS + 8 - 'import' viewstate (Watch history) from another PMS database + 9 - 'replace' current database with newest usable backup copy (interactive) + 10 - 'show' logfile + 11 - 'status' of PMS (Stop/Run and databases) + 12 - 'undo' - Undo last successful command + 99 - exit -Enter choice: 8 +Enter command # -or- command name (4 char min) : start -================================================================================== -2022-11-16 12.32.00 - ============================================================ -2022-11-16 12.32.00 - Session start: Host is Synology (DSM 7) -2022-11-16 13.27.03 - ============================================================ -2022-11-16 13.27.03 - Session start: Host is Synology (DSM 7) -2022-11-16 13.27.03 - PMS running. Could not continue. -2022-11-16 13.28.16 - ============================================================ -2022-11-16 13.28.16 - Session start: Host is Synology (DSM 7) -2022-11-16 13.29.15 - Repair - Export databases - PASS -2022-11-16 13.29.16 - Repair - Import - PASS -2022-11-16 13.29.16 - Repair - Verify main database - PASS (Size: 1MB/1MB). -2022-11-16 13.29.16 - Repair - Verify blobs database - PASS (Size: 1MB/1MB). -2022-11-16 13.29.16 - Repair - Move files - PASS -2022-11-16 13.29.16 - Repair - PASS -2022-11-16 13.32.45 - ============================================================ -2022-11-16 13.32.45 - Session start: Host is Synology (DSM 7) -2022-11-16 13.33.26 - PMS running. Could not continue. -2022-11-16 13.36.34 - ============================================================ -2022-11-16 13.36.34 - Session start: Host is Synology (DSM 7) -2022-11-16 13.36.34 - PMS running. Could not continue. -2022-11-16 13.36.55 - ============================================================ -2022-11-16 13.36.55 - Session start: Host is Synology (DSM 7) -2022-11-16 13.37.10 - PMS running. Could not continue. -2022-11-16 13.41.34 - ============================================================ -2022-11-16 13.41.34 - Session start: Host is Synology (DSM 7) -2022-11-16 13.41.34 - PMS running. Could not continue. -2022-11-16 13.41.57 - ============================================================ -2022-11-16 13.41.57 - Session start: Host is Synology (DSM 7) -2022-11-16 13.42.06 - Check - Check com.plexapp.plugins.library.db - PASS -2022-11-16 13.42.06 - Check - Check com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 13.42.06 - Check - PASS -2022-11-16 13.42.41 - PMS running. Could not continue. -2022-11-16 13.42.41 - PMS running. Could not continue. -2022-11-16 13.46.36 - PMS running. Could not continue. -2022-11-16 13.47.01 - ============================================================ -2022-11-16 13.47.01 - Session start: Host is Synology (DSM 7) -2022-11-16 13.47.32 - PMS running. Could not continue. -2022-11-16 13.47.49 - PMS running. Could not continue. -2022-11-16 13.48.00 - Exit - Delete temp files. -2022-11-16 13.48.00 - Session end. -2022-11-16 13.48.00 - ============================================================ -2022-11-16 15.52.09 - PMS running. Could not continue. -2022-11-16 15.55.02 - PMS running. Could not continue. -2022-11-16 15.55.29 - ============================================================ -2022-11-16 15.55.29 - Session start: Host is Synology (DSM 7) -2022-11-16 15.55.49 - Check - Check com.plexapp.plugins.library.db - PASS -2022-11-16 15.55.50 - Check - Check com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 15.55.50 - Check - PASS -2022-11-16 15.56.11 - Repair - Export databases - PASS -2022-11-16 15.56.20 - Repair - Import - PASS -2022-11-16 15.56.22 - Repair - Verify main database - PASS (Size: 23MB/22MB). -2022-11-16 15.56.22 - Repair - Verify blobs database - PASS (Size: 1MB/1MB). -2022-11-16 15.56.22 - Repair - Move files - PASS -2022-11-16 15.56.22 - Repair - PASS -2022-11-16 15.56.45 - Reindex - MakeBackup com.plexapp.plugins.library.db - PASS -2022-11-16 15.56.45 - Reindex - MakeBackup com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 15.56.45 - Reindex - MakeBackup - PASS -2022-11-16 15.56.47 - Reindex - Reindex: com.plexapp.plugins.library.db - PASS -2022-11-16 15.56.47 - Reindex - Reindex: com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 15.56.47 - Reindex - PASS -================================================================================== - - - Plex Media Server Database Repair Utility (Synology (DSM 7)) +Starting PMS. +Started PMS Select - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit + 1 - 'stop' PMS + 2 - 'automatic' database check, repair/optimize, and reindex in one step. + 3 - 'check' database + 4 - 'vacuum' database + 5 - 'repair' / 'optimize' database + 6 - 'reindex' database + 7 - 'start' PMS + 8 - 'import' viewstate (Watch history) from another PMS database + 9 - 'replace' current database with newest usable backup copy (interactive) + 10 - 'show' logfile + 11 - 'status' of PMS (Stop/Run and databases) + 12 - 'undo' - Undo last successful command + 99 - exit -Enter choice: 7 - -Pathname of database containing watch history to import: /volume1/Plex/backup/com.plexapp.plugins.library.db -Backing up databases -Backup current databases with '-ORIG-2022-11-16_16.02.55' -Exporting Viewstate / Watch history -Making backup copy of main database -Importing Viewstate data -Checking database following import -Viewstate import successful. +Enter command # -or- command name (4 char min) : stat - Plex Media Server Database Repair Utility (Synology (DSM 7)) +Status report: Sat Feb 25 04:38:50 PM EST 2023 + PMS is running. + Databases are OK. + Select - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit + 1 - 'stop' PMS + 2 - 'automatic' database check, repair/optimize, and reindex in one step. + 3 - 'check' database + 4 - 'vacuum' database + 5 - 'repair' / 'optimize' database + 6 - 'reindex' database + 7 - 'start' PMS + 8 - 'import' viewstate (Watch history) from another PMS database + 9 - 'replace' current database with newest usable backup copy (interactive) + 10 - 'show' logfile + 11 - 'status' of PMS (Stop/Run and databases) + 12 - 'undo' - Undo last successful command + 99 - exit -Enter choice: 1 - -Checking the PMS databases -Check complete. PMS main database is OK. -Check complete. PMS blobs database is OK. - - - Plex Media Server Database Repair Utility (Synology (DSM 7)) - -Select - - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit - -Enter choice: 2 - -Backing up databases -Backup current databases with '-ORIG-2022-11-16_16.05.37' -Vacuuming main database -Vacuuming main database successful (Size: 22MB/22MB). -Vacuuming blobs database -Vacuuming blobs database successful (Size: 1MB/1MB). -Vacuum complete. - - - Plex Media Server Database Repair Utility (Synology (DSM 7)) - -Select - - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit - -Enter choice: 3 - -Backing up of databases -Backup current databases with '-ORIG-2022-11-16_16.05.44' -Reindexing main database -Reindexing main database successful. -Reindexing blobs database -Reindexing blobs database successful. -Reindex complete. - - - Plex Media Server Database Repair Utility (Synology (DSM 7)) - -Select - - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit - -Enter choice: 8 - -================================================================================== -2022-11-16 12.32.00 - ============================================================ -2022-11-16 12.32.00 - Session start: Host is Synology (DSM 7) -2022-11-16 13.27.03 - ============================================================ -2022-11-16 13.27.03 - Session start: Host is Synology (DSM 7) -2022-11-16 13.27.03 - PMS running. Could not continue. -2022-11-16 13.28.16 - ============================================================ -2022-11-16 13.28.16 - Session start: Host is Synology (DSM 7) -2022-11-16 13.29.15 - Repair - Export databases - PASS -2022-11-16 13.29.16 - Repair - Import - PASS -2022-11-16 13.29.16 - Repair - Verify main database - PASS (Size: 1MB/1MB). -2022-11-16 13.29.16 - Repair - Verify blobs database - PASS (Size: 1MB/1MB). -2022-11-16 13.29.16 - Repair - Move files - PASS -2022-11-16 13.29.16 - Repair - PASS -2022-11-16 13.32.45 - ============================================================ -2022-11-16 13.32.45 - Session start: Host is Synology (DSM 7) -2022-11-16 13.33.26 - PMS running. Could not continue. -2022-11-16 13.36.34 - ============================================================ -2022-11-16 13.36.34 - Session start: Host is Synology (DSM 7) -2022-11-16 13.36.34 - PMS running. Could not continue. -2022-11-16 13.36.55 - ============================================================ -2022-11-16 13.36.55 - Session start: Host is Synology (DSM 7) -2022-11-16 13.37.10 - PMS running. Could not continue. -2022-11-16 13.41.34 - ============================================================ -2022-11-16 13.41.34 - Session start: Host is Synology (DSM 7) -2022-11-16 13.41.34 - PMS running. Could not continue. -2022-11-16 13.41.57 - ============================================================ -2022-11-16 13.41.57 - Session start: Host is Synology (DSM 7) -2022-11-16 13.42.06 - Check - Check com.plexapp.plugins.library.db - PASS -2022-11-16 13.42.06 - Check - Check com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 13.42.06 - Check - PASS -2022-11-16 13.42.41 - PMS running. Could not continue. -2022-11-16 13.42.41 - PMS running. Could not continue. -2022-11-16 13.46.36 - PMS running. Could not continue. -2022-11-16 13.47.01 - ============================================================ -2022-11-16 13.47.01 - Session start: Host is Synology (DSM 7) -2022-11-16 13.47.32 - PMS running. Could not continue. -2022-11-16 13.47.49 - PMS running. Could not continue. -2022-11-16 13.48.00 - Exit - Delete temp files. -2022-11-16 13.48.00 - Session end. -2022-11-16 13.48.00 - ============================================================ -2022-11-16 15.52.09 - PMS running. Could not continue. -2022-11-16 15.55.02 - PMS running. Could not continue. -2022-11-16 15.55.29 - ============================================================ -2022-11-16 15.55.29 - Session start: Host is Synology (DSM 7) -2022-11-16 15.55.49 - Check - Check com.plexapp.plugins.library.db - PASS -2022-11-16 15.55.50 - Check - Check com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 15.55.50 - Check - PASS -2022-11-16 15.56.11 - Repair - Export databases - PASS -2022-11-16 15.56.20 - Repair - Import - PASS -2022-11-16 15.56.22 - Repair - Verify main database - PASS (Size: 23MB/22MB). -2022-11-16 15.56.22 - Repair - Verify blobs database - PASS (Size: 1MB/1MB). -2022-11-16 15.56.22 - Repair - Move files - PASS -2022-11-16 15.56.22 - Repair - PASS -2022-11-16 15.56.45 - Reindex - MakeBackup com.plexapp.plugins.library.db - PASS -2022-11-16 15.56.45 - Reindex - MakeBackup com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 15.56.45 - Reindex - MakeBackup - PASS -2022-11-16 15.56.47 - Reindex - Reindex: com.plexapp.plugins.library.db - PASS -2022-11-16 15.56.47 - Reindex - Reindex: com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 15.56.47 - Reindex - PASS -2022-11-16 16.03.16 - Import - Attempting to import watch history from '/volume1/Plex/backup/com.plexapp.plugins.library.db' -2022-11-16 16.04.56 - Import - MakeBackup com.plexapp.plugins.library.db - PASS -2022-11-16 16.04.56 - Import - MakeBackup com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 16.04.56 - Import - MakeBackups - PASS -2022-11-16 16.04.59 - Import - Import: /volume1/Plex/backup/com.plexapp.plugins.library.db - PASS -2022-11-16 16.05.34 - Check - Check com.plexapp.plugins.library.db - PASS -2022-11-16 16.05.34 - Check - Check com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 16.05.34 - Check - PASS -2022-11-16 16.05.37 - Vacuum - MakeBackup com.plexapp.plugins.library.db - PASS -2022-11-16 16.05.38 - Vacuum - MakeBackup com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 16.05.38 - Vacuum - MakeBackups - PASS -2022-11-16 16.05.40 - Vacuum - Vacuum main database - PASS (Size: 22MB/22MB). -2022-11-16 16.05.41 - Vacuum - Vacuum blobs database - PASS (Size: 1MB/1MB). -2022-11-16 16.05.41 - Vacuum - PASS -2022-11-16 16.05.44 - Reindex - MakeBackup com.plexapp.plugins.library.db - PASS -2022-11-16 16.05.44 - Reindex - MakeBackup com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 16.05.44 - Reindex - MakeBackup - PASS -2022-11-16 16.05.46 - Reindex - Reindex: com.plexapp.plugins.library.db - PASS -2022-11-16 16.05.46 - Reindex - Reindex: com.plexapp.plugins.library.blobs.db - PASS -2022-11-16 16.05.46 - Reindex - PASS -================================================================================== - - - Plex Media Server Database Repair Utility (Synology (DSM 7)) - -Select - - 1. Check database - 2. Vacuum database - 3. Reindex database - 4. Attempt database repair - 5. Replace current database with newest usable backup copy - 6. Undo last successful action (Vacuum, Reindex, Repair, or Replace) - 7. Import Viewstate / Watch history from another PMS database - 8. Show logfile - 9. Exit - -Enter choice: 9 +Enter command # -or- command name (4 char min) : exit Ok to remove temporary databases/workfiles for this session? (Y/N) ? y Are you sure (Y/N) ? y Deleting all temporary work files. bash-4.4# + ``` +## Sample (typical) scripted session (e.g. via 'cron') + +``` +root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# ./DBRepair.sh stop check auto start exit + + + + Plex Media Server Database Repair Utility (Ubuntu 20.04.5 LTS) + Version v1.0.0 + + +[2023-03-05 18.53.49] Stopping PMS. +[2023-03-05 18.53.49] Stopped PMS. + +[2023-03-05 18.53.49] Checking the PMS databases +[2023-03-05 18.54.22] Check complete. PMS main database is OK. +[2023-03-05 18.54.22] Check complete. PMS blobs database is OK. + +[2023-03-05 18.54.22] Automatic Check,Repair,Index started. +[2023-03-05 18.54.22] +[2023-03-05 18.54.22] Checking the PMS databases +[2023-03-05 18.54.56] Check complete. PMS main database is OK. +[2023-03-05 18.54.56] Check complete. PMS blobs database is OK. +[2023-03-05 18.54.56] +[2023-03-05 18.54.56] Exporting current databases using timestamp: 2023-03-05_18.54.22 +[2023-03-05 18.54.56] Exporting Main DB +[2023-03-05 18.55.30] Exporting Blobs DB +[2023-03-05 18.55.33] Successfully exported the main and blobs databases. Proceeding to import into new databases. +[2023-03-05 18.55.33] Importing Main DB. +[2023-03-05 18.57.04] Importing Blobs DB. +[2023-03-05 18.57.05] Successfully imported SQL data. +[2023-03-05 18.57.05] Verifying databases integrity after importing. +[2023-03-05 18.57.40] Verification complete. PMS main database is OK. +[2023-03-05 18.57.40] Verification complete. PMS blobs database is OK. +[2023-03-05 18.57.40] Saving current databases with '-BACKUP-2023-03-05_18.54.22' +[2023-03-05 18.57.40] Making repaired databases active +[2023-03-05 18.57.40] Repair complete. Please check your library settings and contents for completeness. +[2023-03-05 18.57.40] Recommend: Scan Files and Refresh all metadata for each library section. +[2023-03-05 18.57.40] +[2023-03-05 18.57.40] Backing up of databases +[2023-03-05 18.57.40] Backup current databases with '-BACKUP-2023-03-05_18.57.40' timestamp. +[2023-03-05 18.57.41] Reindexing main database +[2023-03-05 18.58.17] Reindexing main database successful. +[2023-03-05 18.58.17] Reindexing blobs database +[2023-03-05 18.58.17] Reindexing blobs database successful. +[2023-03-05 18.58.17] Reindex complete. +[2023-03-05 18.58.17] Automatic Check, Repair/optimize, & Index successful. + +[2023-03-05 18.58.17] Starting PMS. +[2023-03-05 18.58.17] Started PMS + +root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# + +``` + +====================== +``` + +``` +## Logfile + + The logfile (DBRepair.log) keeps track of all commands issues and their status (PASS/FAIL) with timestamp. + This can be useful when recovering from an interrupted session because temporary files are timestamped. + + +``` +2023-02-25 16.14.39 - ============================================================ +2023-02-25 16.14.39 - Session start: Host is Synology (DSM 7) +2023-02-25 16.14.56 - StopPMS - PASS +2023-02-25 16.16.06 - Check - Check com.plexapp.plugins.library.db - PASS +2023-02-25 16.16.06 - Check - Check com.plexapp.plugins.library.blobs.db - PASS +2023-02-25 16.16.06 - Check - PASS +2023-02-25 16.17.20 - Repair - Export databases - PASS +2023-02-25 16.19.52 - Repair - Import - PASS +2023-02-25 16.20.41 - Repair - Verify main database - PASS (Size: 399MB/399MB). +2023-02-25 16.20.41 - Repair - Verify blobs database - PASS (Size: 1MB/1MB). +2023-02-25 16.20.41 - Repair - Move files - PASS +2023-02-25 16.20.41 - Repair - PASS +2023-02-25 16.20.41 - Repair - PASS +2023-02-25 16.20.46 - Reindex - MakeBackup com.plexapp.plugins.library.db - PASS +2023-02-25 16.20.46 - Reindex - MakeBackup com.plexapp.plugins.library.blobs.db - PASS +2023-02-25 16.20.46 - Reindex - MakeBackup - PASS +2023-02-25 16.21.34 - Reindex - Reindex: com.plexapp.plugins.library.db - PASS +2023-02-25 16.21.35 - Reindex - Reindex: com.plexapp.plugins.library.blobs.db - PASS +2023-02-25 16.21.35 - Reindex - PASS +2023-02-25 16.21.35 - Reindex - PASS +2023-02-25 16.21.35 - Auto - PASS +2023-02-25 16.38.35 - StartPMS - PASS +2023-02-25 16.38.57 - Exit - Delete temp files. +2023-02-25 16.38.58 - Session end. +2023-02-25 16.38.58 - ============================================================ +2023-02-25 16.40.10 - ============================================================ +2023-02-25 16.40.10 - Session start: Host is Synology (DSM 7) +2023-02-25 16.40.27 - StopPMS - PASS +2023-02-25 16.42.23 - Check - Check com.plexapp.plugins.library.db - PASS +2023-02-25 16.42.24 - Check - Check com.plexapp.plugins.library.blobs.db - PASS +2023-02-25 16.42.24 - Check - PASS +2023-02-25 16.43.39 - Repair - Export databases - PASS +2023-02-25 16.46.10 - Repair - Import - PASS +2023-02-25 16.46.58 - Repair - Verify main database - PASS (Size: 399MB/399MB). +2023-02-25 16.46.58 - Repair - Verify blobs database - PASS (Size: 1MB/1MB). +2023-02-25 16.46.59 - Repair - Move files - PASS +2023-02-25 16.46.59 - Repair - PASS +2023-02-25 16.46.59 - Repair - PASS +2023-02-25 16.47.03 - Reindex - MakeBackup com.plexapp.plugins.library.db - PASS +2023-02-25 16.47.03 - Reindex - MakeBackup com.plexapp.plugins.library.blobs.db - PASS +2023-02-25 16.47.03 - Reindex - MakeBackup - PASS +2023-02-25 16.47.52 - Reindex - Reindex: com.plexapp.plugins.library.db - PASS +2023-02-25 16.47.52 - Reindex - Reindex: com.plexapp.plugins.library.blobs.db - PASS +2023-02-25 16.47.52 - Reindex - PASS +2023-02-25 16.47.52 - Reindex - PASS +2023-02-25 16.47.52 - Auto - PASS +2023-02-25 16.48.04 - StartPMS - PASS +2023-02-25 16.48.05 - Exit - Delete temp files. +2023-02-25 16.48.05 - Session end. + +``` + +# Command Reference: + +### Automatic + + Automatic provides automated processing of most checks and repairs. (Check, Repair/Resequence, Index) + In its current state, it will not automatically replace a damaged database from a backup (future) + + It will not stop PMS as not all systems support stopping PMS from within this tool. + +### Check + + Checks the integrity of the Plex main and blobs databases. + +### Exit + + Exits the utility and removes all temporary database files created during processing. + To save all intermediate databases, use the 'Quit' command. + +### Import + + Imports (raw) watch history from another PMS database without ability to check validity + ( This can have side effects of "negative watch count" being displayed. Caution is advised. ) + + +### Reindex + + Rebuilds the database indexes after an import, repair, or replace operation. + These indexes are used by PMS for searching (both internally and your typed searches) + +### Repair + + Extracts/recovers all the usable data fron the existing databases into text (SQL ascii) form. + Repair then creates new SQLite-valid databases from the extracted/recovered data. + + The side effect of this process is a fully defragmented database (optimal for Plex use). + + 100% validity/usability by Plex is not guaranteed as the tool cannot validate each individual + record contained in the database. It can only validate at the SQLite level. + + In most cases, Repair is the preferred option as the records extracted are only those SQLite deemed valid. + +### Replace + + Looks through the list of available PMS backups. + + Starting with the most recent PMS backup, + 1. Check the both db files + 2. If valid, offer as a replacement choice + 3. If accepted (Y/N question) then use as the replacement + else advance to the next available backup + 4. Upon completion, validate one final time. + +### Quit + + Exits the utility but leaves the temporary databases intact (useful for making exhaustive backups) + +### Show + + Shows the activity log. The activity log is date/time stamped of all activity. + +### Start + + On platform environments which support it, and when invoked by the 'root' user, the tool can start PMS. + If not the 'root' user or on a platform which doesn't support it, "Not available" will be indicated. + +### Stop + + On platform environments which support it, and when invoked by the 'root' user, the tool can stop PMS. + If not the 'root' user or on a platform which doesn't support it, "Not available" will be indicated. + + PMS must be in the stopped state in order to operate on the database files. + +### Undo + + Undo allows you to "Undo" the last Import, Repair, Replace, or Vacuum command. + At present, it only allows the ONE most recent operation. + (Future will support undoing more actions) + +### Vacuum + + Instructs SQLite to remove the empty/deleted records and gaps from the databases. + This is most beneficial after deleting whole library sections. + +### \ No newline at end of file diff --git a/ReleaseNotes b/ReleaseNotes new file mode 100644 index 0000000..ca56050 --- /dev/null +++ b/ReleaseNotes @@ -0,0 +1,105 @@ + +Release Notes: v0.8.0 + +Changes: + +1. "Options" have now become "Commands". You may use either the number or the command name or 4 character + abbreviation. + +2. Menu has been resequenced to better reflect typical use sequence. + +3. Commands are not case sensitive. + +4. Commands may be given on the script invocation command line just as "Option number" were. + +5. Some commands accept arguments. These may be entered at the menu command line. If not entered, you will be prompted. + +6. New command "Automatic" (Auto). Automatic performs Check, Repair(or optimize), and Reindex in one step. + +7. PMS can now be stopped/started from within the tool for those environments which support it. + If the host/container does not support start/stop then "Not Available" will be shown in the menu + +8. Logfile and console output has been updated to show full date & time. + Console output will only show full date & time when running in "Command line" mode (commands on invocation line) + +SAMPLE SESSION + +root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# ./DBRepair.sh stop auto start status exit + + + + Plex Media Server Database Repair Utility (Ubuntu 20.04.5 LTS) + Version v1.0.0 - BETA 2 + + +[2023-03-02 16.28.17] Stopping PMS. +[2023-03-02 16.28.19] Stopped PMS. + +[2023-03-02 16.28.19] Automatic Check,Repair,Index started. +[2023-03-02 16.28.19] +[2023-03-02 16.28.19] Checking the PMS databases +[2023-03-02 16.28.21] Check complete. PMS main database is OK. +[2023-03-02 16.28.21] Check complete. PMS blobs database is OK. +[2023-03-02 16.28.21] +[2023-03-02 16.28.21] Exporting current databases using timestamp: 2023-03-02_16.28.19 +[2023-03-02 16.28.21] Exporting Main DB +[2023-03-02 16.28.24] Exporting Blobs DB +[2023-03-02 16.28.24] Successfully exported the main and blobs databases. Proceeding to import into new databases. +[2023-03-02 16.28.24] Importing Main DB. +[2023-03-02 16.28.31] Importing Blobs DB. +[2023-03-02 16.28.31] Successfully imported data from SQL files. +[2023-03-02 16.28.31] Verifying databases integrity after importing. +[2023-03-02 16.28.32] Verification complete. PMS main database is OK. +[2023-03-02 16.28.32] Verification complete. PMS blobs database is OK. +[2023-03-02 16.28.32] Saving current databases with '-BACKUP-2023-03-02_16.28.19' +[2023-03-02 16.28.32] Making imported databases active +[2023-03-02 16.28.32] Import complete. Please check your library settings and contents for completeness. +[2023-03-02 16.28.32] Recommend: Scan Files and Refresh all metadata for each library section. +[2023-03-02 16.28.32] +[2023-03-02 16.28.32] Backing up of databases +[2023-03-02 16.28.32] Backup current databases with '-BACKUP-2023-03-02_16.28.32' timestamp. +[2023-03-02 16.28.33] Reindexing main database +[2023-03-02 16.28.34] Reindexing main database successful. +[2023-03-02 16.28.34] Reindexing blobs database +[2023-03-02 16.28.34] Reindexing blobs database successful. +[2023-03-02 16.28.34] Reindex complete. +[2023-03-02 16.28.34] Automatic Check,Repair/optimize,Index successful. + +[2023-03-02 16.28.34] Starting PMS. +[2023-03-02 16.28.34] Started PMS + +[2023-03-02 16.28.34] +[2023-03-02 16.28.34] Status report: Thu 02 Mar 2023 04:28:34 PM EST +[2023-03-02 16.28.34] PMS is running. +[2023-03-02 16.28.34] Databases are OK. +[2023-03-02 16.28.34] + +root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# cat DBRepair.log +2023-03-02 16.28.17 - ============================================================ +2023-03-02 16.28.17 - Session start: Host is Ubuntu 20.04.5 LTS +2023-03-02 16.28.19 - Stop - PASS +2023-03-02 16.28.19 - Auto - START +2023-03-02 16.28.21 - Check - Check com.plexapp.plugins.library.db - PASS +2023-03-02 16.28.21 - Check - Check com.plexapp.plugins.library.blobs.db - PASS +2023-03-02 16.28.21 - Check - PASS +2023-03-02 16.28.24 - Repair - Export databases - PASS +2023-03-02 16.28.31 - Repair - Import - PASS +2023-03-02 16.28.32 - Repair - Verify main database - PASS (Size: 139MB/139MB). +2023-03-02 16.28.32 - Repair - Verify blobs database - PASS (Size: 1MB/1MB). +2023-03-02 16.28.32 - Repair - Move files - PASS +2023-03-02 16.28.32 - Repair - PASS +2023-03-02 16.28.32 - Repair - PASS +2023-03-02 16.28.33 - Reindex - MakeBackup com.plexapp.plugins.library.db - PASS +2023-03-02 16.28.33 - Reindex - MakeBackup com.plexapp.plugins.library.blobs.db - PASS +2023-03-02 16.28.33 - Reindex - MakeBackup - PASS +2023-03-02 16.28.34 - Reindex - Reindex: com.plexapp.plugins.library.db - PASS +2023-03-02 16.28.34 - Reindex - Reindex: com.plexapp.plugins.library.blobs.db - PASS +2023-03-02 16.28.34 - Reindex - PASS +2023-03-02 16.28.34 - Reindex - PASS +2023-03-02 16.28.34 - Auto - COMPLETED +2023-03-02 16.28.34 - Start - PASS +2023-03-02 16.28.35 - Exit - Delete temp files. +2023-03-02 16.28.35 - Session end. Thu 02 Mar 2023 04:28:35 PM EST +2023-03-02 16.28.35 - ============================================================ +root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# +