mirror of
https://github.com/ChuckPa/PlexDBRepair.git
synced 2025-11-06 11:18:54 -05:00
Compare commits
No commits in common. "master" and "v1.10.03" have entirely different histories.
@ -10,7 +10,7 @@ To contribute to the project, please follow the following instructions:
|
||||
|
||||
### When submitting your work for review and merge:
|
||||
|
||||
1. Create an issue in the DBRepair repo against the current release
|
||||
1. Create an issue in the PlexDBRepair repo against the current release
|
||||
- Describe the deficiency to be addressed in sufficient detail
|
||||
|
||||
2. Complete your work in your branch
|
||||
@ -26,7 +26,7 @@ To contribute to the project, please follow the following instructions:
|
||||
5. In the pull request, provide a description of what change(s) where made
|
||||
- As last text added, on a blank line,
|
||||
- Add the text: `Fixes:` followed by the URL of the open Issue
|
||||
eg: Fixes: https://github.com/ChuckPa/DBRepair/issues/12 (if we were fixing issue 12)
|
||||
eg: Fixes: https://ChuckPa/PlexDBRepair/issues/12 (if we were fixing issue 12)
|
||||
|
||||
- Adding the above text & URL has the following impact:
|
||||
-- The Issue which prompted the change is forever linked to the PR making documentation easy.
|
||||
|
||||
442
DBRepair.sh
442
DBRepair.sh
@ -1,13 +1,13 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
#########################################################################
|
||||
# Database Repair Utility for Plex Media Server. #
|
||||
# Plex Media Server database check and repair utility script. #
|
||||
# Maintainer: ChuckPa #
|
||||
# Version: v1.12.01 #
|
||||
# Date: 21-Oct-2025 #
|
||||
# Version: v1.10.03 #
|
||||
# Date: 17-Mar-2025 #
|
||||
#########################################################################
|
||||
|
||||
# Version for display purposes
|
||||
Version="v1.12.01"
|
||||
Version="v1.10.03"
|
||||
|
||||
# Have the databases passed integrity checks
|
||||
CheckedDB=0
|
||||
@ -65,9 +65,6 @@ DFFLAGS="-m"
|
||||
# If LC_ALL is null, default to C
|
||||
[ "$LC_ALL" = "" ] && export LC_ALL=C
|
||||
|
||||
# Check Restart
|
||||
[ "$DBRepairRestartedAfterUpdate" = "" ] && DBRepairRestartedAfterUpdate=0
|
||||
|
||||
# Universal output function
|
||||
Output() {
|
||||
if [ $Scripted -gt 0 ]; then
|
||||
@ -222,11 +219,11 @@ FreeSpaceAvailable() {
|
||||
[ "$1" != "" ] && Multiplier=$1
|
||||
|
||||
# Available space where DB resides
|
||||
SpaceAvailable=$(df $DFFLAGS "$DBDIR" | tail -1 | awk '{print $4}')
|
||||
SpaceAvailable=$(df $DFFLAGS "$AppSuppDir" | tail -1 | awk '{print $4}')
|
||||
|
||||
# Get size of DB and blobs, Minimally needing sum of both
|
||||
LibSize="$(stat $STATFMT $STATBYTES "${DBDIR}/$CPPL.db")"
|
||||
BlobsSize="$(stat $STATFMT $STATBYTES "${DBDIR}/$CPPL.blobs.db")"
|
||||
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)
|
||||
@ -280,25 +277,21 @@ ConfirmYesNo() {
|
||||
Answer=""
|
||||
while [ "$Answer" != "Y" ] && [ "$Answer" != "N" ]
|
||||
do
|
||||
if [ $Scripted -eq 1 ]; then
|
||||
Answer=Y
|
||||
else
|
||||
printf "%s (Y/N) ? " "$1"
|
||||
read Input
|
||||
printf "%s (Y/N) ? " "$1"
|
||||
read Input
|
||||
|
||||
# EOF = No
|
||||
case "$Input" in
|
||||
YES|YE|Y|yes|ye|y)
|
||||
Answer=Y
|
||||
;;
|
||||
NO|N|no|n)
|
||||
Answer=N
|
||||
;;
|
||||
*)
|
||||
Answer=""
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# EOF = No
|
||||
case "$Input" in
|
||||
YES|YE|Y|yes|ye|y)
|
||||
Answer=Y
|
||||
;;
|
||||
NO|N|no|n)
|
||||
Answer=N
|
||||
;;
|
||||
*)
|
||||
Answer=""
|
||||
;;
|
||||
esac
|
||||
|
||||
# Unrecognized
|
||||
if [ "$Answer" != "Y" ] && [ "$Answer" != "N" ]; then
|
||||
@ -377,7 +370,7 @@ GetOverride() {
|
||||
# Determine which host we are running on and set variables
|
||||
HostConfig() {
|
||||
|
||||
# On all hosts except Mac/FreeBSD
|
||||
# On all hosts except Mac
|
||||
PIDOF="pidof"
|
||||
STATFMT="-c"
|
||||
STATBYTES="%s"
|
||||
@ -626,66 +619,6 @@ HostConfig() {
|
||||
HostType="Mac"
|
||||
return 0
|
||||
|
||||
# FreeBSD 14+
|
||||
elif [ -e /etc/os-release ] && [ "$(cat /etc/os-release | grep FreeBSD)" != "" ]; then
|
||||
|
||||
# Load functions for interacting with FreeBSD RC System
|
||||
. /etc/rc.subr
|
||||
|
||||
# Find PMS
|
||||
PLEXPKG=$(pkg info | grep plexmediaserver | awk '{print $1}')
|
||||
|
||||
if [ "x$PLEXPKG" != "x" ]; then # Plex ports package is installed
|
||||
BsdRcFile=$(pkg list $PLEXPKG | grep "/usr/local/etc/rc.d")
|
||||
BsdService=$(basename $BsdRcFile)
|
||||
# FreeBSD Ports has two packages for Plex - determine which one is installed
|
||||
BsdPlexPass="$(pkg info $PLEXPKG | grep ^Name | awk '{print $3}' | sed -e 's/plexmediaserver//')"
|
||||
|
||||
# Load FreeBSD RC configuration for Plex
|
||||
load_rc_config $BsdService
|
||||
|
||||
# Use FreeBSD RC configuration to set paths
|
||||
if [ "x$plexmediaserver_plexpass_support_path" != "x" ]; then
|
||||
DBDIR="${plexmediaserver_plexpass_support_path}/Plex Media Server/Plug-in Support/Databases"
|
||||
CACHEDIR="${plexmediaserver_plexpass_support_path}/Plex Media Server/Cache"
|
||||
elif [ "x$plexmediaserver_support_path" != "x" ]; then
|
||||
DBDIR="${plexmediaserver_support_path}/Plex Media Server/Plug-in Support/Databases"
|
||||
CACHEDIR="${plexmediaserver_support_path}/Plex Media Server/Cache"
|
||||
else
|
||||
# System is using default Ports package configuration paths
|
||||
DBDIR="/usr/local/plexdata${BsdPlexPass}/Plex Media Server/Plug-in Support/Databases"
|
||||
CACHEDIR="/usr/local/plexdata${BsdPlexPass}/Plex Media Server/Cache"
|
||||
fi
|
||||
|
||||
# Where is the software
|
||||
AppSuppDir=$(dirname `pkg list $PLEXPKG | grep Plex_Media_Server`)
|
||||
PLEX_SQLITE="${AppSuppDir}/Plex SQLite"
|
||||
LOGFILE="$DBDIR/DBRepair.log"
|
||||
LOG_TOOL="logger"
|
||||
TMPDIR="/tmp"
|
||||
SYSTMP="$TMPDIR"
|
||||
else
|
||||
Output "Plex Media Server FreeBSD PKG is not installed!"
|
||||
Fail=1
|
||||
return 1
|
||||
fi
|
||||
|
||||
# FreeBSD uses pgrep and uses different stat options
|
||||
PIDOF="pgrep"
|
||||
STATFMT="-f"
|
||||
STATBYTES="%z"
|
||||
STATPERMS="%Lp"
|
||||
|
||||
# User 'plex' exists on FreeBSD, but the tool may not be run as that service account.
|
||||
RootRequired=1
|
||||
|
||||
HaveStartStop=1
|
||||
StartCommand="/usr/sbin/service ${BsdService} start"
|
||||
StopCommand="/usr/sbin/service ${BsdService} stop"
|
||||
|
||||
HostType="FreeBSD"
|
||||
return 0
|
||||
|
||||
# Western Digital (OS5)
|
||||
elif [ -f /etc/system.conf ] && [ -d /mnt/HD/HD_a2/Nas_Prog/plexmediaserver ] && \
|
||||
grep "Western Digital Corp" /etc/system.conf >/dev/null; then
|
||||
@ -719,7 +652,7 @@ HostConfig() {
|
||||
AppSuppDir="/config"
|
||||
PID_FILE="$AppSuppDir/plexmediaserver.pid"
|
||||
DBDIR="$AppSuppDir/Plug-in Support/Databases"
|
||||
CACHEDIR="$AppSuppDir/Cache/PhotoTranscoder"
|
||||
CACHEDIR="$AppSuppDir/Plex Media Server/Cache/PhotoTranscoder"
|
||||
LOGFILE="$DBDIR/DBRepair.log"
|
||||
LOG_TOOL="logger"
|
||||
|
||||
@ -779,12 +712,6 @@ HostConfig() {
|
||||
LOGFILE="$DBDIR/DBRepair.log"
|
||||
LOG_TOOL="logger"
|
||||
|
||||
if grep rpcinterface /etc/supervisor.conf > /dev/null; then
|
||||
HaveStartStop=1
|
||||
StartCommand="supervisorctl start plexmediaserver"
|
||||
StopCommand="supervisorctl stop plexmediaserver"
|
||||
fi
|
||||
|
||||
HostType="BINHEX"
|
||||
return 0
|
||||
|
||||
@ -1166,7 +1093,7 @@ DoRepair() {
|
||||
[ -e $CPPL.blobs.db ] && mv $CPPL.blobs.db "$TMPDIR/$CPPL.blobs.db-BACKUP-$TimeStamp"
|
||||
|
||||
Output "Making repaired databases active"
|
||||
WriteLog "Repair - Making repaired databases active"
|
||||
WriteLog "Making repaired databases active"
|
||||
mv "$TMPDIR/$CPPL.db-REPAIR-$TimeStamp" $CPPL.db
|
||||
mv "$TMPDIR/$CPPL.blobs.db-REPAIR-$TimeStamp" $CPPL.blobs.db
|
||||
|
||||
@ -1405,183 +1332,6 @@ DoReplace() {
|
||||
fi
|
||||
}
|
||||
|
||||
##### Deflate
|
||||
DoDeflate() {
|
||||
|
||||
Damaged=0
|
||||
Fail=0
|
||||
|
||||
# Verify DBs are here
|
||||
if [ ! -e $CPPL.db ]; then
|
||||
Output "No main Plex database exists to deflate. Exiting."
|
||||
WriteLog "Deflate - No main database - FAIL"
|
||||
Fail=1
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check size
|
||||
Size=$(stat $STATFMT $STATBYTES $CPPL.db)
|
||||
|
||||
# Exit if not valid
|
||||
if [ $Size -lt 300000 ]; then
|
||||
Output "Main database is too small/truncated, deflate is not possible. Please try restoring a backup. "
|
||||
WriteLog "Deflate - Main databse too small - FAIL"
|
||||
Fail=1
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Calculate DBsize in GB
|
||||
DBSize=$(( $Size / 1000000000 + 2 ))
|
||||
# Continue
|
||||
DoUpdateTimestamp
|
||||
#Output "Backing up databases using timestamp: $TimeStamp"
|
||||
|
||||
# Make a backup
|
||||
if ! MakeBackups "Deflate"; then
|
||||
Output "Error making backups. Cannot continue."
|
||||
WriteLog "Deflate - MakeBackups - FAIL"
|
||||
Fail=1
|
||||
return 1
|
||||
else
|
||||
WriteLog "Deflate - MakeBackups - PASS"
|
||||
fi
|
||||
|
||||
# Inform user
|
||||
Output "Starting Deflate (Part 1 of 2 - Repair database table)"
|
||||
Output "Estimated completion is $((DBSize / 3)) minutes but is CPU & I/O speed dependent"
|
||||
Output ""
|
||||
WriteLog "Deflate - Start Deflate Pass 1"
|
||||
|
||||
# Library and blobs successfully exported, create new
|
||||
"$PLEX_SQLITE" "$TMPDIR/$CPPL.db-BACKUP-$TimeStamp" << EOF
|
||||
-- Exclusive DB access
|
||||
BEGIN IMMEDIATE;
|
||||
|
||||
-- Create new table
|
||||
CREATE TABLE temp_bandwidth (
|
||||
id INTEGER PRIMARY KEY,
|
||||
account_id INTEGER,
|
||||
device_id INTEGER,
|
||||
timespan INTEGER,
|
||||
at INTEGER,
|
||||
lan INTEGER,
|
||||
bytes INTEGER
|
||||
);
|
||||
|
||||
-- Copy good data to new table
|
||||
INSERT INTO temp_bandwidth (
|
||||
account_id, device_id, timespan, at, lan, bytes
|
||||
)
|
||||
SELECT account_id, device_id, timespan, at, COALESCE(lan, 0), bytes
|
||||
FROM statistics_bandwidth WHERE account_id not null;
|
||||
|
||||
-- Swap new for old
|
||||
DROP TABLE statistics_bandwidth;
|
||||
ALTER TABLE temp_bandwidth RENAME TO statistics_bandwidth;
|
||||
|
||||
-- Create Indexes
|
||||
CREATE INDEX IF NOT EXISTS index_statistics_bandwidth_on_at
|
||||
ON statistics_bandwidth(at);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS index_statistics_bandwidth_on_account_id_and_timespan_and_at
|
||||
ON statistics_bandwidth(account_id, timespan, at);
|
||||
|
||||
-- Make it so
|
||||
COMMIT;
|
||||
EOF
|
||||
Result=$?
|
||||
if [ $Result -ne 0 ]; then
|
||||
Output "Error: Could not correct statistics_bandwidth table (error $Result)"
|
||||
Output " Please seek additional help"
|
||||
WriteLog "Deflate: Error $Result during dodeflate."
|
||||
Fail=1
|
||||
return $Fail
|
||||
fi
|
||||
|
||||
# Vacuum the DB to the new DB
|
||||
Output "PMS main database successfully repaired."
|
||||
Output "Starting Deflate (Part 2 of 2 - Reduce size)"
|
||||
WriteLog "Deflate - Start Deflate Pass 2"
|
||||
|
||||
"$PLEX_SQLITE" "$TMPDIR/$CPPL.db-BACKUP-$TimeStamp" \
|
||||
"VACUUM main into '$TMPDIR/$CPPL.db-DEFLATE-$TimeStamp'"
|
||||
Result=$?
|
||||
|
||||
# Good result?
|
||||
if [ $Result -eq 0 ]; then
|
||||
Output "PMS main database size reduced."
|
||||
WriteLog "Deflate - PMS main vacuum successful."
|
||||
Output "Verifying PMS main database."
|
||||
if CheckDB "$TMPDIR/$CPPL.db-DEFLATE-$TimeStamp" ; then
|
||||
SizeStart=$(GetSize "$CPPL.db")
|
||||
SizeFinish=$(GetSize "$TMPDIR/$CPPL.db-DEFLATE-$TimeStamp")
|
||||
Output "Verification complete. PMS main database is OK."
|
||||
Output "PMS main database reduced from $SizeStart MB to $SizeFinish MB"
|
||||
WriteLog "Deflate - Verify main database - PASS (Size: ${SizeStart} MB / ${SizeFinish} MB."
|
||||
else
|
||||
Output "Verification complete. PMS main database import failed."
|
||||
WriteLog "Deflate - Verify main database - FAIL ($SQLerror)"
|
||||
Fail=1
|
||||
fi
|
||||
else
|
||||
Output "Error: Error code $Result while vacuuming PMS main DB file."
|
||||
Output " Please seek additional help."
|
||||
return $Fail
|
||||
fi
|
||||
|
||||
# If not failed, move files normally
|
||||
if [ $Fail -eq 0 ]; then
|
||||
|
||||
Output "Saving current main database with '-BLOATED-$TimeStamp'"
|
||||
[ -e $CPPL.db ] && mv $CPPL.db "$TMPDIR/$CPPL.db-BLOATED-$TimeStamp"
|
||||
#[ -e $CPPL.blobs.db ] && mv $CPPL.blobs.db "$TMPDIR/$CPPL.blobs.db-BLOATED-$TimeStamp"
|
||||
|
||||
Output "Making deflated database active"
|
||||
WriteLog "Deflate - Making deflated database active"
|
||||
mv "$TMPDIR/$CPPL.db-DEFLATE-$TimeStamp" $CPPL.db
|
||||
|
||||
# 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
|
||||
[ -e $CPPL.db-wal ] && rm -f $CPPL.db-wal
|
||||
[ -e $CPPL.db-shm ] && rm -f $CPPL.db-shm
|
||||
|
||||
# Set ownership on new files
|
||||
chmod $Perms $CPPL.db $CPPL.blobs.db
|
||||
chown $Owner $CPPL.db $CPPL.blobs.db
|
||||
Result=$?
|
||||
if [ $Result -ne 0 ]; then
|
||||
Output "ERROR: Cannot set permissions on new databases. Error $Result"
|
||||
Output " Please exit tool, keeping temp files, seek assistance."
|
||||
Output " Use files: $TMPDIR/*-DEFLATE-$TimeStamp"
|
||||
WriteLog "Deflate - Move files - FAIL"
|
||||
Fail=1
|
||||
return 1
|
||||
fi
|
||||
|
||||
# We didn't fail, set CheckedDB status true (passed above checks)
|
||||
CheckedDB=1
|
||||
|
||||
WriteLog "Deflate - Move files - PASS"
|
||||
WriteLog "Deflate - PASS"
|
||||
|
||||
|
||||
Output "PMS main database deflate completed."
|
||||
|
||||
|
||||
SetLast "Deflate" "$TimeStamp"
|
||||
return 0
|
||||
else
|
||||
|
||||
rm -f "$TMPDIR/$CPPL.db-REPAIR-$TimeStamp"
|
||||
rm -f "$TMPDIR/$CPPL.blobs.db-REPAIR-$TimeStamp"
|
||||
|
||||
Output "Deflate has failed. No files changed"
|
||||
WriteLog "Deflate - $TimeStamp - FAIL"
|
||||
CheckedDB=0
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
##### VACUUM
|
||||
DoVacuum(){
|
||||
@ -1832,7 +1582,7 @@ DoStop(){
|
||||
else
|
||||
|
||||
if IsRunning; then
|
||||
Output "Stopping PMS. (60 second max delay)"
|
||||
Output "Stopping PMS."
|
||||
else
|
||||
Output "PMS already stopped."
|
||||
return 0
|
||||
@ -1849,7 +1599,7 @@ DoStop(){
|
||||
Count=10
|
||||
while IsRunning && [ $Count -gt 0 ]
|
||||
do
|
||||
sleep 6
|
||||
sleep 3
|
||||
Count=$((Count - 1))
|
||||
done
|
||||
|
||||
@ -1859,7 +1609,7 @@ DoStop(){
|
||||
return 0
|
||||
else
|
||||
WriteLog "Stop - FAIL (Timeout)"
|
||||
Output "Could not stop PMS. PMS did not shutdown within 60 second limit."
|
||||
Output "Could not stop PMS. PMS did not shutdown within 30 second limit."
|
||||
fi
|
||||
fi
|
||||
return $Result
|
||||
@ -1884,9 +1634,9 @@ DoUpdateTimestamp() {
|
||||
|
||||
# Get latest version from Github
|
||||
GetLatestRelease() {
|
||||
Response=$(curl -sL "https://api.github.com/repos/ChuckPa/DBRepair/tags")
|
||||
Response=$(curl -s "https://api.github.com/repos/ChuckPa/PlexDBRepair/tags")
|
||||
if [ $? -eq 0 ]; then
|
||||
LatestVersion="$(echo "$Response" | grep name | awk -F: '{print $2}' | sort -r | head -1 | tr -d \" | tr -d ' ' | tr -d ',')"
|
||||
LatestVersion="$(echo "$Response" | awk -F : '{print $2}' | awk -F \, '{print $1}' | tr -d \")"
|
||||
else
|
||||
LatestVersion="$Version"
|
||||
fi
|
||||
@ -1899,7 +1649,7 @@ DownloadAndUpdate() {
|
||||
Filename="$2"
|
||||
|
||||
# Download the file and check if the download was successful
|
||||
if curl -sL "$Url" --output "${Filename}.tmp"; then
|
||||
if curl -s "$Url" --output "${Filename}.tmp"; then
|
||||
# Check if the file was written to and at least 50000 bytes
|
||||
if [ -f "${Filename}.tmp" ]; then
|
||||
if [ $(stat $STATFMT $STATBYTES "${Filename}.tmp") -gt 50000 ]; then
|
||||
@ -1984,6 +1734,7 @@ DoPrunePhotoTranscoder() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
#############################################################
|
||||
# Main utility begins here #
|
||||
#############################################################
|
||||
@ -2071,7 +1822,7 @@ Scripted=0
|
||||
|
||||
# Identify this host
|
||||
if [ $ManualConfig -eq 0 ] && ! HostConfig; then
|
||||
Output 'Error: Unknown host. Current supported hosts are: QNAP, Syno, Netgear, Mac, ASUSTOR, WD (OS5), Linux wkstn/svr, SNAP, FreeBSD 14+'
|
||||
Output 'Error: Unknown host. Current supported hosts are: QNAP, Syno, Netgear, Mac, ASUSTOR, WD (OS5), Linux wkstn/svr, SNAP'
|
||||
Output ' Current supported container images: Plexinc, LinuxServer, HotIO, & BINHEX'
|
||||
Output ' Manual host configuration is available in most use cases.'
|
||||
Output ' '
|
||||
@ -2156,7 +1907,7 @@ do
|
||||
|
||||
echo " "
|
||||
echo " "
|
||||
echo " Database Repair Utility for Plex Media Server ($HostType)"
|
||||
echo " Plex Media Server Database Repair Utility ($HostType)"
|
||||
echo " Version $Version"
|
||||
echo " "
|
||||
|
||||
@ -2194,16 +1945,16 @@ do
|
||||
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 " 21 - 'prune' - Remove old image files from PhotoTranscoder cache & all temp files left by PMS."
|
||||
echo " 23 - 'deflate' - Deflate a bloated PMS main database."
|
||||
echo " 21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS."
|
||||
[ $IgnoreErrors -eq 0 ] && echo " 42 - 'ignore' - Ignore duplicate/constraint errors."
|
||||
[ $IgnoreErrors -eq 1 ] && echo " 42 - 'honor' - Honor all database errors."
|
||||
|
||||
echo ""
|
||||
echo " 88 - 'update' - Check for updates."
|
||||
echo " 98 - 'quit' - Quit immediately. Keep all temporary files."
|
||||
echo " 99 - 'exit' - Exit with cleanup options."
|
||||
|
||||
echo " 99 - 'quit' - Quit immediately. Keep all temporary files."
|
||||
echo " 'exit' - Exit with cleanup options."
|
||||
fi
|
||||
|
||||
if [ $Scripted -eq 0 ]; then
|
||||
@ -2259,8 +2010,12 @@ do
|
||||
# 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
|
||||
@ -2270,7 +2025,7 @@ do
|
||||
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 = $SpaceAvailable MB"
|
||||
Output " Space needed = $SpaceNeeded MB, Space available = $SpaveAvailable MB"
|
||||
continue
|
||||
fi
|
||||
|
||||
@ -2286,7 +2041,6 @@ do
|
||||
else
|
||||
WriteLog "Check - FAIL"
|
||||
CheckedDB=0
|
||||
continue
|
||||
fi
|
||||
|
||||
# Now Repair
|
||||
@ -2344,6 +2098,7 @@ do
|
||||
fi
|
||||
;;
|
||||
|
||||
|
||||
# Vacuum
|
||||
4|vacu*)
|
||||
|
||||
@ -2513,89 +2268,6 @@ do
|
||||
WriteLog "Prune - PASS"
|
||||
;;
|
||||
|
||||
|
||||
# Deflate the DB because Plex isn't doing a good job during scheduled tasks.
|
||||
23|defl*)
|
||||
|
||||
# Check if PMS running
|
||||
if IsRunning; then
|
||||
WriteLog "Deflate - FAIL - PMS runnning"
|
||||
Output "Unable to deflate. PMS is running. Please stop PlexMediaServer."
|
||||
continue
|
||||
fi
|
||||
|
||||
# Is there enough room to work
|
||||
if ! FreeSpaceAvailable; then
|
||||
WriteLog "Deflate - FAIL - Insufficient free space on $AppSuppDir"
|
||||
Output "Error: Unable to deflate. Insufficient free space available on $AppSuppDir"
|
||||
Output " Space needed = $SpaceNeeded MB, Space available = $SpaceAvailable MB"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Start auto
|
||||
Output "Check and Deflate started."
|
||||
WriteLog "Deflate - START"
|
||||
|
||||
# Check the databases (forced)
|
||||
Output ""
|
||||
if CheckDatabases "Check " force ; then
|
||||
WriteLog "Check - PASS"
|
||||
CheckedDB=1
|
||||
else
|
||||
WriteLog "Check - FAIL"
|
||||
CheckedDB=0
|
||||
fi
|
||||
|
||||
# Now Deflate
|
||||
Output ""
|
||||
if ! DoDeflate; then
|
||||
|
||||
WriteLog "Deflate - FAIL"
|
||||
CheckedDB=0
|
||||
|
||||
Output "Deflate failed. Please repair using Automatic mode."
|
||||
continue
|
||||
else
|
||||
WriteLog "Deflate - PASS"
|
||||
CheckedDB=1
|
||||
fi
|
||||
|
||||
# All good to here
|
||||
WriteLog "Deflate - PASS"
|
||||
Output "Deflate successful."
|
||||
Output "Recommend running "Auto" next to complete optimization of new database."
|
||||
;;
|
||||
|
||||
|
||||
# Records count
|
||||
30|coun*)
|
||||
|
||||
Temp="$DBDIR/DBRepair.tab1"
|
||||
Temp2="$DBDIR/DBRepair.tab2"
|
||||
|
||||
# Ensure clean
|
||||
rm -f "$Temp" "$Temp2"
|
||||
|
||||
# Get list of tables
|
||||
Tables="$("$PLEX_SQLITE" "$DBDIR/com.plexapp.plugins.library.db" .tables | sed 's/ /\n/g')"
|
||||
|
||||
# Separate and sort tables
|
||||
for i in $Tables
|
||||
do
|
||||
echo $i >> "$Temp"
|
||||
done
|
||||
sort < "$Temp" > "$Temp2"
|
||||
|
||||
Tables="$(cat "$Temp2")"
|
||||
|
||||
# Get counts
|
||||
for Table in $Tables
|
||||
do
|
||||
Records=$("$PLEX_SQLITE" "$DBDIR/com.plexapp.plugins.library.db" "select count(*) from $Table;")
|
||||
printf "%36s %-15d\n" $Table $Records
|
||||
done
|
||||
;;
|
||||
|
||||
# Ignore/Honor errors
|
||||
42|igno*|hono*)
|
||||
|
||||
@ -2606,13 +2278,6 @@ do
|
||||
|
||||
88|upda*)
|
||||
|
||||
# Don't update again after restarting after updating
|
||||
if [ $DBRepairRestartedAfterUpdate -eq 1 ]; then
|
||||
Output "Already updated. Continuing."
|
||||
WriteLog "Update - Ignore Update request after updating."
|
||||
continue
|
||||
fi
|
||||
|
||||
DoUpdate=0
|
||||
Output "Checking for update"
|
||||
GetLatestRelease
|
||||
@ -2630,19 +2295,12 @@ do
|
||||
if [ $DoUpdate -eq 1 ]; then
|
||||
if [ -w "$ScriptWorkingDirectory" ]; then
|
||||
Output "Updating from $Version to $LatestVersion"
|
||||
DownloadAndUpdate "https://raw.githubusercontent.com/ChuckPa/DBRepair/master/DBRepair.sh" "$ScriptWorkingDirectory/$ScriptName"
|
||||
DownloadAndUpdate "https://raw.githubusercontent.com/ChuckPa/PlexDBRepair/master/DBRepair.sh" "$ScriptWorkingDirectory/$ScriptName"
|
||||
Result=$?
|
||||
if [ $Result -eq 0 ]; then
|
||||
chmod +x "$ScriptWorkingDirectory/$ScriptName"
|
||||
if [ $Scripted -eq 0 ] && ConfirmYesNo "Restart and use $LatestVersion ?" ; then
|
||||
WriteLog "Restarting after upgrade"
|
||||
Output "Restarting"
|
||||
export DBRepairRestartedAfterUpdate=1
|
||||
exec "$ScriptWorkingDirectory/$ScriptName" "$*"
|
||||
else
|
||||
Output "Restart to launch updated DBRepair.sh ($LatestVersion)"
|
||||
WriteLog "Update - Updated to version $LatestVersion."
|
||||
fi
|
||||
Output "Restart to launch updated DBRepair.sh ($LatestVersion)"
|
||||
WriteLog "Update - Updated to version $LatestVersion."
|
||||
exit 0
|
||||
else
|
||||
Output "Unable to download and update. Error $Result."
|
||||
@ -2656,7 +2314,7 @@ do
|
||||
;;
|
||||
|
||||
# Quit
|
||||
98|quit)
|
||||
99|quit)
|
||||
|
||||
Output "Retaining all temporary work files."
|
||||
WriteLog "Exit - Retain temp files."
|
||||
@ -2664,7 +2322,7 @@ do
|
||||
;;
|
||||
|
||||
# Orderly Exit
|
||||
99|exit)
|
||||
exit)
|
||||
|
||||
# If forced exit set, exit and retain
|
||||
if [ $Exit -eq 1 ]; then
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
Copyright (c) 2025, ChuckPa.
|
||||
Copyright (c) 2022, ChuckPa.
|
||||
|
||||
This software is the intellectual property of ChuckPa
|
||||
and used in conjunction with Plex Media Server (which is Copyright & Trademark of Plex, Inc.)
|
||||
|
||||
It may not be copied, modified, or redistributed in any way without expressly written permission of ChuckPa.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to use the Software for personal use only. The Software may not be modified, merged, published, distributed, sublicensed, and/or used in other form without the express written consent of the author.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
236
README.md
236
README.md
@ -1,9 +1,9 @@
|
||||
# DBRepair (for Plex Media Server)
|
||||
# PlexDBRepair
|
||||
|
||||
[](https://github.com/ChuckPa/DBRepair/issues)
|
||||
[](https://github.com/ChuckPa/DBRepair/releases/latest)
|
||||
[](https://github.com/ChuckPa/DBRepair/releases/latest)
|
||||
[](https://github.com/ChuckPa/DBRepair/releases)
|
||||
[](https://github.com/ChuckPa/PlexDBRepair/issues)
|
||||
[](https://github.com/ChuckPa/PlexDBRepair/releases/latest)
|
||||
[](https://github.com/ChuckPa/PlexDBRepair/releases/latest)
|
||||
[](https://github.com/ChuckPa/PlexDBRepair/releases)
|
||||
[]('')
|
||||

|
||||
|
||||
@ -31,7 +31,6 @@ If sufficient privleges exist (root), and supported by the environment, the opti
|
||||
```
|
||||
AUTO(matic) - Automatically check, repair/optimize, and reindex the databases in one step.
|
||||
CHEC(k) - Check the main and blob databases integrity
|
||||
DEFL(ate) - Deflate a bloated PMS database (faulty statistics data)
|
||||
EXIT - Exit the utility
|
||||
IGNOre/HONOr - Ignore/Honor constraint errors when IMPORTing additional data into DB.
|
||||
IMPO(rt) - Import viewstate / watch history from another database
|
||||
@ -52,7 +51,7 @@ If sufficient privleges exist (root), and supported by the environment, the opti
|
||||
For clarity, each command's name is 'quoted'.
|
||||
|
||||
```
|
||||
Database Repair Utility for Plex Media Server (_host_configuration_name_)
|
||||
Plex Media Server Database Repair Utility (_host_configuration_name_)
|
||||
Version v1.09.00
|
||||
|
||||
Select
|
||||
@ -73,12 +72,11 @@ If sufficient privleges exist (root), and supported by the environment, the opti
|
||||
|
||||
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
|
||||
22 - 'purge' - Purge (delete) all temporary files left behind by PMS & the transcoder.
|
||||
23 - 'deflate' - Deflate a bloated PMS main database.
|
||||
42 - 'ignore' - Ignore duplicate/constraint errors.
|
||||
|
||||
88 - 'update' - Check for updates.
|
||||
98 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
99 'exit' - Exit with cleanup options.
|
||||
99 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
'exit' - Exit with cleanup options.
|
||||
|
||||
Enter command # -or- command name (4 char min) :
|
||||
|
||||
@ -94,13 +92,12 @@ Enter command # -or- command name (4 char min) :
|
||||
- BINHEX
|
||||
- HOTIO
|
||||
- Podman (libgpod)
|
||||
4. FreeBSD (14+)
|
||||
5. Linux workstation & server
|
||||
6. MacOS
|
||||
7. Netgear (OS5 Linux-based systems)
|
||||
8. QNAP (QTS & QuTS)
|
||||
9. Synology (DSM 6 & DSM 7)
|
||||
10. Western Digital (OS5)
|
||||
4. Linux workstation & server
|
||||
5. MacOS
|
||||
6. Netgear (OS5 Linux-based systems)
|
||||
7. QNAP (QTS & QuTS)
|
||||
8. Synology (DSM 6 & DSM 7)
|
||||
9. Western Digital (OS5)
|
||||
```
|
||||
# Installation
|
||||
|
||||
@ -115,11 +112,10 @@ Enter command # -or- command name (4 char min) :
|
||||
-------------------+---------------------+------------------------------------------
|
||||
Apple | Downloads | ~/Downloads
|
||||
Arch Linux | N/A | Anywhere
|
||||
ASUSTOR | Plex | /volume1/Plex
|
||||
ASUSTOR | Public | /volume1/Public
|
||||
Binhex | N/A | Container root (adjacent /config)
|
||||
Docker (Plex,LSIO) | N/A | Container root (adjacent /config)
|
||||
Hotio | N/A | Container root (adjacent /config)
|
||||
FreeBSD (14+) | N/A | Anywhere
|
||||
Kubernetes | N/A | Container root (adjacent /config)
|
||||
Linux (wkstn/svr) | N/A | Anywhere
|
||||
MacOS | N/A | Anywhere
|
||||
@ -138,10 +134,10 @@ Enter command # -or- command name (4 char min) :
|
||||
|
||||
### General installation and usage instructions
|
||||
|
||||
1. Open your browser to https://github.com/ChuckPa/DBRepair/releases/latest
|
||||
1. Open your browser to https://github.com/ChuckPa/PlexDBRepair/releases/latest
|
||||
2. Download the source code (tar.gz or ZIP) file
|
||||
|
||||
3. Knowing the file name will always be of the form 'DBRepair-X.Y.Z.tar.gz'
|
||||
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)
|
||||
@ -160,8 +156,8 @@ Enter command # -or- command name (4 char min) :
|
||||
|
||||
cd /volume1/Plex # use /volume1/PlexMediaServer on DSM 7
|
||||
sudo bash
|
||||
tar xf DBRepair-x.y.z.tar.gz
|
||||
cd DBRepair-x.y.z
|
||||
tar xf PlexDBRepair-x.y.z.tar.gz
|
||||
cd PlexDBRepair-x.y.z
|
||||
chmod +x DBRepair.sh
|
||||
./DBRepair.sh
|
||||
|
||||
@ -172,8 +168,8 @@ Enter command # -or- command name (4 char min) :
|
||||
sudo docker exec -it plex /bin/bash
|
||||
|
||||
# extract from downloaded version file name then cd into directory
|
||||
tar xf DBRepair-x.y.z.tar.gz
|
||||
cd DBRepair-x.y.z
|
||||
tar xf PlexDBRepair-x.y.z.tar.gz
|
||||
cd PlexDBRepair-x.y.z
|
||||
chmod +x DBRepair.sh
|
||||
./DBRepair.sh
|
||||
```
|
||||
@ -181,8 +177,8 @@ Enter command # -or- command name (4 char min) :
|
||||
```
|
||||
sudo bash
|
||||
cd /path/to/DBRepair.tar
|
||||
tar xf DBRepair-x.y.z.tar.gz
|
||||
cd DBRepair-x.y.z
|
||||
tar xf PlexDBRepair-x.y.z.tar.gz
|
||||
cd PlexDBRepair-x.y.z
|
||||
chmod +x DBRepair.sh
|
||||
./DBRepair.sh stop auto start exit
|
||||
```
|
||||
@ -191,8 +187,8 @@ Enter command # -or- command name (4 char min) :
|
||||
```
|
||||
osascript -e 'quit app "Plex Media Server"'
|
||||
cd ~/Downloads
|
||||
tar xf DBRepair-x.y.z.tar.gz
|
||||
cd DBRepair-x.y.z
|
||||
tar xvf PlexDBRepai PlexDBRepair-x.y.z.tar.gz
|
||||
cd PlexDBRepair-x.y.z
|
||||
|
||||
chmod +x DBRepair.sh
|
||||
./DBRepair.sh
|
||||
@ -224,22 +220,23 @@ These examples
|
||||
|
||||
C. Database is malformed - No Backups
|
||||
1. (3) Check - Confirm either main or blobs database is damaged
|
||||
2. (5) Repair - Salvage as much as possible from the databases and rebuild them into a usable database.
|
||||
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
|
||||
|
||||
D. Database sizes excessively large/bloated when compared to amount of media indexed (item count)
|
||||
1. (23) Deflate - Correct the known problem with a database table and recover the wasted space.
|
||||
2. (2) Auto - Perform automated check, repair, and reindex of the deflated database
|
||||
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
|
||||
|
||||
E. User interface has become 'sluggish' as more media was added
|
||||
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. (99) Exit
|
||||
|
||||
F. 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.
|
||||
@ -269,10 +266,14 @@ Attention:
|
||||
-- This is for when DB operations keep getting worse and you don't know what to do.
|
||||
"99" is an old 'Get Smart' TV series reference where agent 99 would try to save agent 86 from harm.
|
||||
|
||||
Community feedback has resulted in:
|
||||
"99" was originally going to be "Quit immediately save all files" but development feedback
|
||||
resulted in this configuration
|
||||
|
||||
"99" or "Exit" - Preferred way to exit and cleanup temp databases
|
||||
"98" or "Quit" - Get out now without deleting the temp databases (Usually used only during unexpected failures)
|
||||
"Exit" is the preferred method to leave.
|
||||
|
||||
"Quit" was desired instead of "99" but there are those who didn't understand the difference or references.
|
||||
|
||||
If community feedback wants both "Quit. save temps" and "Exit, delete temps", behavior is easily changed.
|
||||
|
||||
Also please be aware the script understands interactive versus scripted mode.
|
||||
|
||||
@ -330,7 +331,7 @@ bash-4.4# ./DBRepair.sh
|
||||
|
||||
|
||||
|
||||
Database Repair Utility for Plex Media Server (Ubuntu 20.04.6 LTS)
|
||||
Plex Media Server Database Repair Utility (Ubuntu 20.04.6 LTS)
|
||||
Version v1.03.01
|
||||
|
||||
Select
|
||||
@ -349,14 +350,12 @@ Select
|
||||
11 - 'status' - Report status of PMS (run-state and databases).
|
||||
12 - 'undo' - Undo last successful command.
|
||||
|
||||
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
|
||||
22 - 'purge' - Remove unused temp files.
|
||||
23 - 'deflate' - Deflate a bloated PMS main database.
|
||||
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
|
||||
42 - 'ignore' - Ignore duplicate/constraint errors.
|
||||
|
||||
88 - 'update' - Check for updates.
|
||||
98 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
99 - 'exit' - Exit with cleanup options.
|
||||
99 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
'exit' - Exit with cleanup options.
|
||||
|
||||
Enter command # -or- command name (4 char min) : 1
|
||||
|
||||
@ -379,14 +378,12 @@ Select
|
||||
11 - 'status' - Report status of PMS (run-state and databases).
|
||||
12 - 'undo' - Undo last successful command.
|
||||
|
||||
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
|
||||
22 - 'purge' - Remove unused temp files.
|
||||
23 - 'deflate' - Deflate a bloated PMS main database.
|
||||
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
|
||||
42 - 'ignore' - Ignore duplicate/constraint errors.
|
||||
|
||||
88 - 'update' - Check for updates.
|
||||
98 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
99 - 'exit' - Exit with cleanup options.
|
||||
99 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
'exit' - Exit with cleanup options.
|
||||
|
||||
Enter command # -or- command name (4 char min) : auto
|
||||
|
||||
@ -435,14 +432,12 @@ Select
|
||||
11 - 'status' - Report status of PMS (run-state and databases).
|
||||
12 - 'undo' - Undo last successful command.
|
||||
|
||||
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
|
||||
22 - 'purge' - Remove unused temp files.
|
||||
23 - 'deflate' - Deflate a bloated PMS main database.
|
||||
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
|
||||
42 - 'ignore' - Ignore duplicate/constraint errors.
|
||||
|
||||
88 - 'update' - Check for updates.
|
||||
98 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
99 - 'exit' - Exit with cleanup options.
|
||||
99 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
'exit' - Exit with cleanup options.
|
||||
|
||||
Enter command # -or- command name (4 char min) : start
|
||||
|
||||
@ -465,14 +460,12 @@ Select
|
||||
11 - 'status' - Report status of PMS (run-state and databases).
|
||||
12 - 'undo' - Undo last successful command.
|
||||
|
||||
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
|
||||
22 - 'purge' - Remove unused temp files.
|
||||
23 - 'deflate' - Deflate a bloated PMS main database.
|
||||
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
|
||||
42 - 'ignore' - Ignore duplicate/constraint errors.
|
||||
|
||||
88 - 'update' - Check for updates.
|
||||
98 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
99 - 'exit' - Exit with cleanup options.
|
||||
99 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
'exit' - Exit with cleanup options.
|
||||
|
||||
Enter command # -or- command name (4 char min) : stat
|
||||
|
||||
@ -498,14 +491,12 @@ Select
|
||||
11 - 'status' - Report status of PMS (run-state and databases).
|
||||
12 - 'undo' - Undo last successful command.
|
||||
|
||||
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
|
||||
22 - 'purge' - Remove unused temp files.
|
||||
23 - 'deflate' - Deflate a bloated PMS main database.
|
||||
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
|
||||
42 - 'ignore' - Ignore duplicate/constraint errors.
|
||||
|
||||
88 - 'update' - Check for updates.
|
||||
98 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
99 - 'exit' - Exit with cleanup options.
|
||||
99 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
'exit' - Exit with cleanup options.
|
||||
|
||||
Enter command # -or- command name (4 char min) : exit
|
||||
|
||||
@ -523,7 +514,7 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# ./DBRepair.sh
|
||||
|
||||
|
||||
|
||||
Database Repair Utility for Plex Media Server (Ubuntu 20.04.5 LTS)
|
||||
Plex Media Server Database Repair Utility (Ubuntu 20.04.5 LTS)
|
||||
Version v1.03.01
|
||||
|
||||
|
||||
@ -647,13 +638,6 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases#
|
||||
|
||||
Checks the integrity of the Plex main and blobs databases.
|
||||
|
||||
### Deflate
|
||||
|
||||
Repairs a known error in the PMS main database "statistics_bandwidth" table.
|
||||
After repairing it, it purges all the errant data from the table (reducing DB size)
|
||||
|
||||
This task can take a significant amount of time. It's frequently used when the DB size is an order of magnitude above what it should be (e.g. 31 GB vs 206 MB). Reductions from 134 GB to 210 MB have been realized.
|
||||
|
||||
### Exit
|
||||
|
||||
Exits the utility and removes all temporary database files created during processing.
|
||||
@ -831,77 +815,55 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases#
|
||||
1. Remove the environment variable.
|
||||
2. Run DBRepair again using "automatic". Your databases will revert to the host OS's default.
|
||||
|
||||
### Usage: (QNAP example shown)
|
||||
### Usage: (Linux example shown)
|
||||
|
||||
```
|
||||
# export DBREPAIR_PAGESIZE=65534
|
||||
# ./DBRepair.sh stop deflate auto start exit
|
||||
# ./DBRepair.sh stop auto start exit
|
||||
|
||||
|
||||
|
||||
Database Repair Utility for Plex Media Server (QNAP)
|
||||
Version v1.12.00
|
||||
Plex Media Server Database Repair Utility (Ubuntu 22.04.3 LTS)
|
||||
Version v1.03.01
|
||||
|
||||
|
||||
[2025-10-21 16.54.00] PMS already stopped.
|
||||
[2024-01-14 17.25.35] Stopping PMS.
|
||||
[2024-01-14 17.25.35] Stopped PMS.
|
||||
|
||||
[2025-10-21 16.54.00] Check and Deflate started.
|
||||
[2025-10-21 16.54.00]
|
||||
[2025-10-21 16.54.00] Checking the PMS databases
|
||||
[2025-10-21 16.54.19] Check complete. PMS main database is OK.
|
||||
[2025-10-21 16.54.21] Check complete. PMS blobs database is OK.
|
||||
[2025-10-21 16.54.21]
|
||||
[2025-10-21 16.54.21] Backup current databases with '-BACKUP-2025-10-21_16.54.21' timestamp.
|
||||
[2025-10-21 16.56.29] Starting Deflate (Part 1 of 2 - Repair database table)
|
||||
[2025-10-21 16.56.29] Estimated completion is approx 6 minutes but is CPU & I/O speed dependent
|
||||
[2025-10-21 16.56.29]
|
||||
[2025-10-21 16.56.30] PMS main database successfully repaired.
|
||||
[2025-10-21 16.56.30] Starting Deflate (Part 2 of 2 - Reduce size)
|
||||
[2025-10-21 16.56.35] PMS main database size reduced.
|
||||
[2025-10-21 16.56.35] Verifying PMS main database.
|
||||
[2025-10-21 16.56.50] Verification complete. PMS main database is OK.
|
||||
[2025-10-21 16.56.50] PMS main database reduced from 31586 MB to 206 MB
|
||||
[2025-10-21 16.56.51] Saving current main database with '-BLOATED-2025-10-21_16.54.21'
|
||||
[2025-10-21 16.56.51] Making deflated database active
|
||||
[2025-10-21 16.56.51] PMS main database deflate completed.
|
||||
[2025-10-21 16.56.51] Deflate successful.
|
||||
[2025-10-21 16.56.51] Recommend running Auto next to complete optimization of new database.
|
||||
[2024-01-14 17.25.35] Automatic Check,Repair,Index started.
|
||||
[2024-01-14 17.25.35]
|
||||
[2024-01-14 17.25.35] Checking the PMS databases
|
||||
[2024-01-14 17.25.48] Check complete. PMS main database is OK.
|
||||
[2024-01-14 17.25.48] Check complete. PMS blobs database is OK.
|
||||
[2024-01-14 17.25.48]
|
||||
[2024-01-14 17.25.48] Exporting current databases using timestamp: 2024-01-14_17.25.35
|
||||
[2024-01-14 17.25.48] Exporting Main DB
|
||||
[2024-01-14 17.25.59] Exporting Blobs DB
|
||||
[2024-01-14 17.26.00] Successfully exported the main and blobs databases. Proceeding to import into new databases.
|
||||
[2024-01-14 17.26.00] Importing Main DB.
|
||||
[2024-01-14 17.26.00] Setting Plex SQLite page size (65536)
|
||||
[2024-01-14 17.26.29] Importing Blobs DB.
|
||||
[2024-01-14 17.26.29] Setting Plex SQLite page size (65536)
|
||||
[2024-01-14 17.26.30] Successfully imported databases.
|
||||
[2024-01-14 17.26.30] Verifying databases integrity after importing.
|
||||
[2024-01-14 17.27.43] Verification complete. PMS main database is OK.
|
||||
[2024-01-14 17.27.43] Verification complete. PMS blobs database is OK.
|
||||
[2024-01-14 17.27.43] Saving current databases with '-BACKUP-2024-01-14_17.25.35'
|
||||
[2024-01-14 17.27.43] Making repaired databases active
|
||||
[2024-01-14 17.27.43] Repair complete. Please check your library settings and contents for completeness.
|
||||
[2024-01-14 17.27.43] Recommend: Scan Files and Refresh all metadata for each library section.
|
||||
[2024-01-14 17.27.43]
|
||||
[2024-01-14 17.27.43] Backing up of databases
|
||||
[2024-01-14 17.27.43] Backup current databases with '-BACKUP-2024-01-14_17.27.43' timestamp.
|
||||
[2024-01-14 17.27.44] Reindexing main database
|
||||
[2024-01-14 17.28.08] Reindexing main database successful.
|
||||
[2024-01-14 17.28.08] Reindexing blobs database
|
||||
[2024-01-14 17.28.08] Reindexing blobs database successful.
|
||||
[2024-01-14 17.28.08] Reindex complete.
|
||||
[2024-01-14 17.28.08] Automatic Check, Repair/optimize, & Index successful.
|
||||
|
||||
[2025-10-21 16.56.51] Automatic Check,Repair,Index started.
|
||||
[2025-10-21 16.56.51]
|
||||
[2025-10-21 16.56.51] Checking the PMS databases
|
||||
[2025-10-21 16.57.04] Check complete. PMS main database is OK.
|
||||
[2025-10-21 16.57.05] Check complete. PMS blobs database is OK.
|
||||
[2025-10-21 16.57.05]
|
||||
[2025-10-21 16.57.05] Exporting current databases using timestamp: 2025-10-21_16.56.51
|
||||
[2025-10-21 16.57.05] Exporting Main DB
|
||||
[2025-10-21 16.57.24] Exporting Blobs DB
|
||||
[2025-10-21 16.59.18] Successfully exported the main and blobs databases.
|
||||
[2025-10-21 16.59.18] Start importing into new databases.
|
||||
[2025-10-21 16.59.18] Importing Main DB.
|
||||
[2025-10-21 16.59.18] Setting Plex SQLite page size (65536)
|
||||
[2025-10-21 17.00.19] Importing Blobs DB.
|
||||
[2025-10-21 17.00.19] Setting Plex SQLite page size (65536)
|
||||
[2025-10-21 17.00.32] Successfully imported databases.
|
||||
[2025-10-21 17.00.32] Verifying databases integrity after importing.
|
||||
[2025-10-21 17.01.59] Verification complete. PMS main database is OK.
|
||||
[2025-10-21 17.02.01] Verification complete. PMS blobs database is OK.
|
||||
[2025-10-21 17.02.01] Saving current databases with '-BACKUP-2025-10-21_16.56.51'
|
||||
[2025-10-21 17.02.01] Making repaired databases active
|
||||
[2025-10-21 17.02.01] Repair complete. Please check your library settings and contents for completeness.
|
||||
[2025-10-21 17.02.01] Recommend: Scan Files and Refresh all metadata for each library section.
|
||||
[2025-10-21 17.02.01]
|
||||
[2025-10-21 17.02.01] Backing up of databases
|
||||
[2025-10-21 17.02.01] Backup current databases with '-BACKUP-2025-10-21_17.02.01' timestamp.
|
||||
[2025-10-21 17.02.02] Reindexing main database
|
||||
[2025-10-21 17.02.13] Reindexing main database successful.
|
||||
[2025-10-21 17.02.13] Reindexing blobs database
|
||||
[2025-10-21 17.02.14] Reindexing blobs database successful.
|
||||
[2025-10-21 17.02.14] Reindex complete.
|
||||
[2025-10-21 17.02.14] Automatic Check, Repair/optimize, & Index successful.
|
||||
|
||||
[2025-10-21 17.02.14] Starting PMS.
|
||||
[2025-10-21 17.02.14] Started PMS
|
||||
[2024-01-14 17.28.08] Starting PMS.
|
||||
[2024-01-14 17.28.08] Started PMS
|
||||
|
||||
#
|
||||
```
|
||||
@ -951,7 +913,7 @@ root@Jasper:/mnt/user/appdata/PlexMediaServer# /tmp/DBRepair.sh --databases /mnt
|
||||
|
||||
|
||||
|
||||
Database Repair Utility for Plex Media Server (User Defined)
|
||||
Plex Media Server Database Repair Utility (User Defined)
|
||||
Version v1.09.00
|
||||
|
||||
PlexSQLite = '/var/lib/docker/btrfs/subvolumes/4bb78fb70589d4d2ba56754f4d6bc0edd4cdaa8eab7986943767e09a66cefd19/usr/lib/plexmediaserver//Plex SQLite'
|
||||
@ -975,14 +937,12 @@ Select
|
||||
|
||||
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache older than specific age.
|
||||
22 - 'purge' - Purge (remove) all temporary files left by PMS & Transcoder in Temp Dir.'
|
||||
23 - 'deflate' - Deflate a bloated PMS main database.
|
||||
|
||||
|
||||
42 - 'ignore' - Ignore duplicate/constraint errors.
|
||||
|
||||
88 - 'update' - Check for updates.
|
||||
98 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
99 - 'exit' - Exit with cleanup options.
|
||||
99 - 'quit' - Quit immediately. Keep all temporary files.
|
||||
'exit' - Exit with cleanup options.
|
||||
|
||||
Enter command # -or- command name (4 char min) :
|
||||
```
|
||||
|
||||
92
ReleaseNotes
92
ReleaseNotes
@ -1,69 +1,13 @@
|
||||
# DBRepair
|
||||
# PlexDBRepair
|
||||
|
||||
[](https://github.com/ChuckPa/DBRepair/issues)
|
||||
[](https://github.com/ChuckPa/DBRepair/releases/latest)
|
||||
[](https://github.com/ChuckPa/DBRepair/releases/latest)
|
||||
[](https://github.com/ChuckPa/DBRepair/releases)
|
||||
[](https://github.com/ChuckPa/PlexDBRepair/issues)
|
||||
[](https://github.com/ChuckPa/PlexDBRepair/releases/latest)
|
||||
[](https://github.com/ChuckPa/PlexDBRepair/releases/latest)
|
||||
[](https://github.com/ChuckPa/PlexDBRepair/releases)
|
||||
[]('')
|
||||

|
||||
|
||||
# Release Info:
|
||||
v1.12.00
|
||||
|
||||
1. Deflate capability - Deflate a bloated PMS main database and retain bandwidth statistics.
|
||||
Recommended usage: "Deflate" followed by "Auto" to optimize the DB after reduction.
|
||||
- Method changed to reconstruction of bandwidth table versus selective copy.
|
||||
This results in correct operation of bandwidth statistics functionality
|
||||
as well as significantly improved performance.
|
||||
|
||||
2. ASUSTOR - Documentation error README.md corrected
|
||||
|
||||
|
||||
v1.11.09
|
||||
|
||||
1. HotIO Paths - Path defined for Cache dir (and PhotoTranscoder) incorrect. Fixed.
|
||||
|
||||
v1.11.08
|
||||
|
||||
1. Restart after update - Sometimes restart after update would reference the wrong path. Fixed.
|
||||
|
||||
v1.11.07
|
||||
|
||||
1. Add support FreeBSD - Add support for FreeBSD (14+)
|
||||
Thanks to @cdf-eagles for the work.
|
||||
|
||||
v1.11.06
|
||||
|
||||
1. Restart after update - Correct missing variable initialization.
|
||||
|
||||
v1.11.05
|
||||
|
||||
1. Remove menu option - Deflate menu option wasn't previously removed. Now removed.
|
||||
|
||||
v1.11.04
|
||||
|
||||
1. Binhex start/stop - Add support for stopping and starting PMS in Binhex containers.
|
||||
2. Restart after update - Add option to restart after live updating.
|
||||
3. Remove temp Deflate - Remove deflate function as of PMS 1.41.8 availability
|
||||
|
||||
v1.11.01 - v1.11.03 - Temporary versions to assist PMS database bloat issue.
|
||||
|
||||
v1.11.00
|
||||
|
||||
1. Rename Utility - Rename this tool to be compliant with Plex inc. Trademark Policy.
|
||||
Update all documentation
|
||||
Update Github repository
|
||||
|
||||
v1.10.06
|
||||
|
||||
1. Update tags - When updating, DBRepair would not format cleanly. This update corrects that formatting.
|
||||
It would often show the tags for multiple previous versions. This is undesirable.
|
||||
|
||||
v1.10.05
|
||||
|
||||
1. DB Cleanup - Temporary assist with PMS database cleanups
|
||||
2. Record Count report - Report the number of records in each main DB table. (Monitoring growth)
|
||||
|
||||
v1.10.03
|
||||
|
||||
1. LC_ALL - When LC_ALL="", set LC_ALL=C (MacOS now needs this)
|
||||
@ -318,7 +262,7 @@ These type changes can only be performed by PMS.
|
||||
For clarity, each command's name is 'quoted'.
|
||||
|
||||
|
||||
Database Repair Utility for Plex Media Server (_host_configuration_name_)
|
||||
Plex Media Server Database Repair Utility (_host_configuration_name_)
|
||||
Version v1.0.0
|
||||
|
||||
Select
|
||||
@ -383,10 +327,10 @@ These type changes can only be performed by PMS.
|
||||
|
||||
### General installation and usage instructions
|
||||
|
||||
1. Open your browser to https://github.com/ChuckPa/DBRepair/releases/latest
|
||||
1. Open your browser to https://github.com/ChuckPa/PlexDBRepair/releases/latest
|
||||
2. Download the source code (tar.gz or ZIP) file
|
||||
|
||||
3. Knowing the file name will always be of the form 'DBRepair-X.Y.Z.tar.gz'
|
||||
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)
|
||||
@ -403,8 +347,8 @@ These type changes can only be performed by PMS.
|
||||
|
||||
cd /volume1/Plex
|
||||
sudo bash
|
||||
tar xf DBRepair-x.y.z.tar.gz
|
||||
cd DBRepair-x.y.z
|
||||
tar xf PlexDBRepair-x.y.z.tar.gz
|
||||
cd PlexDBRepair-x.y.z
|
||||
chmod +x DBRepair.sh
|
||||
./DBRepair.sh
|
||||
|
||||
@ -416,8 +360,8 @@ These type changes can only be performed by PMS.
|
||||
sudo docker exec -it plex /bin/bash
|
||||
|
||||
# extract from downloaded version file name then cd into directory
|
||||
tar xf DBRepair-1.0.0.tar.gz
|
||||
cd DBRepair-1.0.0
|
||||
tar xf PlexDBRepair-1.0.0.tar.gz
|
||||
cd PlexDBRepair-1.0.0
|
||||
chmod +x DBRepair.sh
|
||||
./DBRepair.sh
|
||||
```
|
||||
@ -425,8 +369,8 @@ These type changes can only be performed by PMS.
|
||||
```
|
||||
sudo bash
|
||||
cd /path/to/DBRepair.tar
|
||||
tar xf DBRepair-1.0.0.tar.gz
|
||||
cd DBRepair-1.0.0
|
||||
tar xf PlexDBRepair-1.0.0.tar.gz
|
||||
cd PlexDBRepair-1.0.0
|
||||
chmod +x DBRepair.sh
|
||||
./DBRepair.sh stop auto start exit
|
||||
```
|
||||
@ -435,8 +379,8 @@ These type changes can only be performed by PMS.
|
||||
```
|
||||
osascript -e 'quit app "Plex Media Server"'
|
||||
cd ~/Downloads
|
||||
tar xvf PlexDBRepai DBRepair-1.0.0.tar.gz
|
||||
cd PlexDBRepai DBRepair-1.0.0
|
||||
tar xvf PlexDBRepai PlexDBRepair-1.0.0.tar.gz
|
||||
cd PlexDBRepai PlexDBRepair-1.0.0
|
||||
|
||||
chmod +x DBRepair.sh
|
||||
./DBRepair.sh
|
||||
@ -541,7 +485,7 @@ bash-4.4# ./DBRepair.sh
|
||||
|
||||
|
||||
|
||||
Database Repair Utility for Plex Media Server (Synology (DSM 7))
|
||||
Plex Media Server Database Repair Utility (Synology (DSM 7))
|
||||
Version v1.0.0
|
||||
|
||||
|
||||
@ -694,7 +638,7 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# ./DBRepair.sh
|
||||
|
||||
|
||||
|
||||
Database Repair Utility for Plex Media Server (Ubuntu 20.04.5 LTS)
|
||||
Plex Media Server Database Repair Utility (Ubuntu 20.04.5 LTS)
|
||||
Version v1.0.0
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
@echo off
|
||||
REM DBRepair.bat - Database maintenance / rebuild tool for Windows.
|
||||
REM PlexDBRepair.bat - Database maintenance / rebuild tool for Windows.
|
||||
REM
|
||||
REM This tool currently works as a "full shot" service.
|
||||
REM - everything is done without need to interact.
|
||||
@ -12,7 +12,7 @@ setlocal enabledelayedexpansion
|
||||
|
||||
echo.
|
||||
echo NOTE: This script is being replaced with the PowerShell script DBRepair-Windows.ps1,
|
||||
echo which aims to better emulate DBRepair.sh (more options, interactive mode, etc).
|
||||
echo which aims to better emulate DBRepair.sh (more options, interative mode, etc).
|
||||
echo Consider moving over to the new script.
|
||||
echo.
|
||||
|
||||
@ -78,13 +78,13 @@ set "TmpFile=%DBtmp%\results.tmp"
|
||||
|
||||
REM Time now.
|
||||
echo %time% -- ====== Session begins. (%date%) ======
|
||||
echo %time% -- ====== Session begins. (%date%) ====== >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- ====== Session begins. (%date%) ====== >> "%PlexData%\PlexDBRepair.log"
|
||||
|
||||
REM Make certain Plex is NOT running.
|
||||
tasklist | find /I "Plex Media Server.exe" >NUL
|
||||
if %ERRORLEVEL%==0 (
|
||||
echo %time% -- Plex is running. Please stop Plex Media Server and try again.
|
||||
echo %time% -- Plex is running. Please stop Plex Media Server and try again. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Plex is running. Please stop Plex Media Server and try again. >> "%PlexData%\PlexDBRepair.log"
|
||||
exit /B 1
|
||||
)
|
||||
|
||||
@ -94,12 +94,8 @@ cd "%PlexData%"
|
||||
md "%PlexData%\dbtmp" 2>NUL
|
||||
del "%TmpFile%" 2>NUL
|
||||
|
||||
echo %time% -- Performing DB cleanup tasks
|
||||
echo %time% -- Performing DB cleanup tasks >> "%PlexData%\DBRepair.log"
|
||||
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db" "DELETE FROM statistics_bandwidth WHERE account_id IS NULL;"
|
||||
|
||||
echo %time% -- Exporting Main DB
|
||||
echo %time% -- Exporting Main DB >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Exporting Main DB >> "%PlexData%\PlexDBRepair.log"
|
||||
echo .dump | "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db" > "%DBtmp%\library.sql_%TimeStamp%"
|
||||
if not %ERRORLEVEL%==0 (
|
||||
echo %time% -- ERROR: Cannot export Main DB. Aborting.
|
||||
@ -107,7 +103,7 @@ if not %ERRORLEVEL%==0 (
|
||||
)
|
||||
|
||||
echo %time% -- Exporting Blobs DB
|
||||
echo %time% -- Exporting Blobs DB >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Exporting Blobs DB >> "%PlexData%\PlexDBRepair.log"
|
||||
echo .dump | "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db" > "%DBtmp%\blobs.sql_%TimeStamp%"
|
||||
if not %ERRORLEVEL%==0 (
|
||||
echo %time% -- ERROR: Cannot export Blobs DB. Aborting.
|
||||
@ -115,75 +111,75 @@ if not %ERRORLEVEL%==0 (
|
||||
|
||||
REM Now create new databases from SQL statements
|
||||
echo %time% -- Exporting Complete.
|
||||
echo %time% -- Exporting Complete. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Exporting Complete. >> "%PlexData%\PlexDBRepair.log"
|
||||
|
||||
echo %time% -- Creating Main DB
|
||||
echo %time% -- Creating Main DB >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Creating Main DB >> "%PlexData%\PlexDBRepair.log"
|
||||
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" < "%DBtmp%\library.sql_%TimeStamp%"
|
||||
if not %ERRORLEVEL%==0 (
|
||||
echo %time% -- ERROR: Cannot create Main DB. Aborting.
|
||||
echo %time% -- ERROR: Cannot create Main DB. Aborting. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- ERROR: Cannot create Main DB. Aborting. >> "%PlexData%\PlexDBRepair.log"
|
||||
exit /b 3
|
||||
)
|
||||
|
||||
echo %time% -- Verifying Main DB
|
||||
echo %time% -- Verifying Main DB >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Verifying Main DB >> "%PlexData%\PlexDBRepair.log"
|
||||
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "PRAGMA integrity_check(1)" >"%TmpFile%"
|
||||
set /p Result= < "%TmpFile%"
|
||||
del "%TmpFile%"
|
||||
|
||||
echo %time% -- Main DB verification check is: %Result%
|
||||
echo %time% -- Main DB verification check is: %Result% >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Main DB verification check is: %Result% >> "%PlexData%\PlexDBRepair.log"
|
||||
if not "%Result%" == "ok" (
|
||||
echo %time% -- ERROR: Main DB verification failed. Exiting.
|
||||
echo %time% -- ERROR: Main DB verification failed. Exiting. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- ERROR: Main DB verificaion failed. Exiting.
|
||||
echo %time% -- ERROR: Main DB verificaion failed. Exiting. >> "%PlexData%\PlexDBRepair.log"
|
||||
exit /B 4
|
||||
)
|
||||
echo %time% -- Main DB verification successful.
|
||||
echo %time% -- Main DB verification successful. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Main DB verification successful. >> "%PlexData%\PlexDBRepair.log"
|
||||
|
||||
|
||||
echo %time% -- Creating Blobs DB
|
||||
echo %time% -- Creating Blobs DB >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Creating Blobs DB >> "%PlexData%\PlexDBRepair.log"
|
||||
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" < "%DBtmp%\blobs.sql_%TimeStamp%"
|
||||
if not %ERRORLEVEL%==0 (
|
||||
echo %time% -- ERROR: Cannot create Blobs DB. Aborting.
|
||||
echo %time% -- ERROR: Cannot create Blobs DB. Aborting. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- ERROR: Cannot create Blobs DB. Aborting. >> "%PlexData%\PlexDBRepair.log"
|
||||
exit /b 5
|
||||
)
|
||||
|
||||
echo %time% -- Verifying Blobs DB
|
||||
echo %time% -- Verifying Blobs DB >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Verifying Blobs DB >> "%PlexData%\PlexDBRepair.log"
|
||||
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" "PRAGMA integrity_check(1)" > "%TmpFile%"
|
||||
set /p Result= < "%TmpFile%"
|
||||
del "%TmpFile%"
|
||||
|
||||
echo %time% -- Blobs DB verification check is: %Result%
|
||||
echo %time% -- Blobs DB verification check is: %Result% >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Blobs DB verification check is: %Result% >> "%PlexData%\PlexDBRepair.log"
|
||||
if not "%Result%" == "ok" (
|
||||
echo %time% -- ERROR: Blobs DB verification failed. Exiting.
|
||||
echo %time% -- ERROR: Blobs DB verification failed. Exiting. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- ERROR: Blobs DB verificaion failed. Exiting.
|
||||
echo %time% -- ERROR: Blobs DB verificaion failed. Exiting. >> "%PlexData%\PlexDBRepair.log"
|
||||
exit /B 6
|
||||
)
|
||||
echo %time% -- Blobs DB verification successful.
|
||||
echo %time% -- Blobs DB verification successful. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Blobs DB verification successful. >> "%PlexData%\PlexDBRepair.log"
|
||||
echo %time% -- Import and verification complete.
|
||||
echo %time% -- Import and verification complete. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Import and verification complete. >> "%PlexData%\PlexDBRepair.log"
|
||||
|
||||
REM Import complete, now reindex
|
||||
echo %time% -- Reindexing Main DB
|
||||
echo %time% -- Reindexing Main DB >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Reindexing Main DB >> "%PlexData%\PlexDBRepair.log"
|
||||
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "REINDEX;"
|
||||
|
||||
echo %time% -- Reindexing Blobs DB
|
||||
echo %time% -- Reindexing Blobs DB >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Reindexing Blobs DB >> "%PlexData%\PlexDBRepair.log"
|
||||
"%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" "REINDEX;"
|
||||
|
||||
REM Index complete, make active
|
||||
echo %time% -- Reindexing complete.
|
||||
echo %time% -- Reindexing complete. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Reindexing complete. >> "%PlexData%\PlexDBRepair.log"
|
||||
echo %time% -- Moving current DBs to DBTMP and making new databases active
|
||||
echo %time% -- Moving current DBs to DBTMP and making new databases active >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Moving current DBs to DBTMP and making new databases active >> "%PlexData%\PlexDBRepair.log"
|
||||
|
||||
move "%PlexData%\com.plexapp.plugins.library.db" "%PlexData%\dbtmp\com.plexapp.plugins.library.db_%TimeStamp%"
|
||||
move "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "%PlexData%\com.plexapp.plugins.library.db"
|
||||
@ -192,9 +188,9 @@ move "%PlexData%\com.plexapp.plugins.library.blobs.db" "%PlexData%\d
|
||||
move "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" "%PlexData%\com.plexapp.plugins.library.blobs.db"
|
||||
|
||||
echo %time% -- Database repair/rebuild/reindex completed.
|
||||
echo %time% -- Database repair/rebuild/reindex completed. >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- Database repair/rebuild/reindex completed. >> "%PlexData%\PlexDBRepair.log"
|
||||
echo %time% -- ====== Session completed. ======
|
||||
echo %time% -- ====== Session completed. ====== >> "%PlexData%\DBRepair.log"
|
||||
echo %time% -- ====== Session completed. ====== >> "%PlexData%\PlexDBRepair.log"
|
||||
|
||||
exit /b
|
||||
|
||||
@ -205,5 +201,5 @@ REM Output - Write text to the console and the log file
|
||||
:Output
|
||||
|
||||
echo %time% %~1
|
||||
echo %time% %~1 >> "%PlexData%\DBRepair.log"
|
||||
echo %time% %~1 >> "%PlexData%\PlexDBRepair.log"
|
||||
exit /B
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
#########################################################################
|
||||
# Database check and repair utility script for Plex Media Server #
|
||||
# Plex Media Server database check and repair utility script. #
|
||||
# #
|
||||
#########################################################################
|
||||
|
||||
$DBRepairVersion = 'v1.01.02'
|
||||
$PlexDBRepairVersion = 'v1.00.01'
|
||||
|
||||
class DBRepair {
|
||||
[DBRepairOptions] $Options
|
||||
class PlexDBRepair {
|
||||
[PlexDBRepairOptions] $Options
|
||||
|
||||
[string] $PlexDBDir # Path to Plex's Databases directory
|
||||
[string] $PlexCache # Path to the PhotoTranscoder directory
|
||||
@ -14,15 +14,10 @@ class DBRepair {
|
||||
[string] $Timestamp # Timestamp used for temporary database files
|
||||
[string] $LogFile # Path of our log file
|
||||
[string] $Version # Current script version
|
||||
[string] $Stage # Current stage of the script (e.g. "Auto", "Prune", etc.)
|
||||
[bool] $IsError # Whether we're currently in an error state
|
||||
[string] $MainDB = "com.plexapp.plugins.library.db"
|
||||
[string] $BlobsDB = "com.plexapp.plugins.library.blobs.db"
|
||||
|
||||
DBRepair($Arguments, $Version) {
|
||||
$this.Options = [DBRepairOptions]::new()
|
||||
PlexDBRepair($Arguments, $Version) {
|
||||
$this.Options = [PlexDBRepairOptions]::new()
|
||||
$this.Version = $Version
|
||||
$this.IsError = $false
|
||||
$Commands = $this.PreprocessArgs($Arguments)
|
||||
if ($null -eq $Commands) {
|
||||
return
|
||||
@ -45,8 +40,8 @@ class DBRepair {
|
||||
}
|
||||
|
||||
Write-Host "`n"
|
||||
Write-Host " Database Repair Utility for Plex Media Server (Windows $($OS.Major), Build $($OS.Build))"
|
||||
Write-Host " Version $($this.Version) "
|
||||
Write-Host " Plex Media Server Database Repair Utility (Windows $($OS.Major), Build $($OS.Build))"
|
||||
Write-Host " Version $($this.Version) "
|
||||
Write-Host
|
||||
}
|
||||
|
||||
@ -88,8 +83,8 @@ class DBRepair {
|
||||
Write-Host " 42 - 'ignore' - Ignore duplicate/constraint errors."
|
||||
}
|
||||
Write-Host
|
||||
Write-Host " 98 - 'quit' - Quit immediately. Keep all temporary files."
|
||||
Write-Host " 99 'exit' - Exit with cleanup options."
|
||||
Write-Host " 99 - 'quit' - Quit immediately. Keep all temporary files."
|
||||
Write-Host " 'exit' - Exit with cleanup options."
|
||||
Write-Host
|
||||
Write-Host " 'menu x' - Show this menu in interactive mode, where x is on/off/yes/no"
|
||||
}
|
||||
@ -141,7 +136,7 @@ class DBRepair {
|
||||
$AppData = $this.GetAppDataDir()
|
||||
$Success = $this.GetPlexDBDir($AppData) -and $this.GetPlexSQL() -and $this.GetPhotoTranscoderDir($AppData)
|
||||
if ($Success) {
|
||||
$this.LogFile = Join-Path $this.PlexDBDir -ChildPath "DBRepair.log"
|
||||
$this.LogFile = Join-Path $this.PlexDBDir -ChildPath "PlexDBRepair.log"
|
||||
}
|
||||
|
||||
return $Success
|
||||
@ -192,15 +187,9 @@ class DBRepair {
|
||||
|
||||
switch -Regex ($Choice) {
|
||||
"^(1|stop)$" { $this.DoStop() }
|
||||
"^(2|autom?a?t?i?c?)$" {
|
||||
$this.SetStage("Auto")
|
||||
$this.IsError = !$this.RunAutomaticDatabaseMaintenance()
|
||||
}
|
||||
"^(2|autom?a?t?i?c?)$" { $this.RunAutomaticDatabaseMaintenance() }
|
||||
"^(7|start?)$" { $this.StartPMS() }
|
||||
"^(21|(prune?|remov?e?))$" {
|
||||
$this.SetStage("Prune")
|
||||
$this.PrunePhotoTranscoderCache()
|
||||
}
|
||||
"^(21|(prune?|remov?e?))$" { $this.PrunePhotoTranscoderCache() }
|
||||
"^(42|ignor?e?|honor?)$" {
|
||||
if (($this.Options.IgnoreErrors -and ($Choice[0] -eq 'i')) -or (!$this.Options.IgnoreErrors -and ($Choice[0] -eq 'h'))) {
|
||||
Write-Host "Honor/Ignore setting unchanged."
|
||||
@ -211,27 +200,19 @@ class DBRepair {
|
||||
$msg = if ($this.Options.IgnoreErrors) { "Ignoring database errors." } else { "Honoring database errors." }
|
||||
$this.WriteOutputLog($msg)
|
||||
}
|
||||
"^(98|quit)$" {
|
||||
$this.Output("Retaining all temporary work files.")
|
||||
"^(99|quit)$" {
|
||||
$this.Output("Retaining all remporary work files.")
|
||||
$this.WriteLog("Exit - Retain temp files.")
|
||||
$this.WriteEnd()
|
||||
return
|
||||
}
|
||||
"^(99|exit)$" {
|
||||
"^exit$" {
|
||||
if ($EOFExit) {
|
||||
$this.Output("Unexpected exit command. Keeping all temporary work files.")
|
||||
$this.WriteLog("EOFExit - Retain temp files.")
|
||||
return
|
||||
}
|
||||
|
||||
# If our last DB operation failed, we don't want to automatically delete
|
||||
# temporary files when in scripted mode.
|
||||
if ($this.IsError -and $this.Options.Scripted) {
|
||||
$this.Output("Exiting with errors. Keeping all temporary work files.")
|
||||
$this.WriteLog("Exit - Retain temp files.")
|
||||
return
|
||||
}
|
||||
|
||||
$this.CleanDBTemp(!$this.Options.Scripted)
|
||||
$this.WriteEnd()
|
||||
return
|
||||
@ -261,12 +242,13 @@ class DBRepair {
|
||||
[void] DoStop() {
|
||||
$this.WriteLog("Stop - START")
|
||||
$PMS = $this.GetPMS()
|
||||
if ($null -eq $PMS) {
|
||||
if ($PMS) {
|
||||
$this.Output("Stopping PMS.")
|
||||
} else {
|
||||
$this.Output("PMS already stopped.")
|
||||
return
|
||||
}
|
||||
|
||||
$this.Output("Stopping PMS.")
|
||||
|
||||
# Plex doesn't respond to CloseMainWindow because it doesn't have a window,
|
||||
# and Stop-Process does a forced exit of the process, so use taskkill to ask
|
||||
@ -283,11 +265,10 @@ class DBRepair {
|
||||
if ($PMS.HasExited) {
|
||||
$this.WriteLog("Stop - PASS")
|
||||
$this.Output("Stopped PMS.")
|
||||
return
|
||||
} else {
|
||||
$this.OutputWarn("Could not stop PMS. PMS did not shutdown within 30 second limit.")
|
||||
$this.WriteLog("Stop - FAIL (Timeout)")
|
||||
}
|
||||
|
||||
$this.OutputWarn("Could not stop PMS. PMS did not shutdown within 30 second limit.")
|
||||
$this.WriteLog("Stop - FAIL (Timeout)")
|
||||
}
|
||||
|
||||
# Start Plex Media Server if it isn't already running
|
||||
@ -312,14 +293,14 @@ class DBRepair {
|
||||
}
|
||||
|
||||
# All-in-one database utility - Repair/Check/Reindex
|
||||
[bool] RunAutomaticDatabaseMaintenance() {
|
||||
[void] RunAutomaticDatabaseMaintenance() {
|
||||
$this.Output("Automatic Check,Repair,Index started.")
|
||||
$this.WriteLog($this.StageLog("START"))
|
||||
$this.WriteLog("Auto - START")
|
||||
|
||||
if ($this.PMSRunning()) {
|
||||
$this.WriteLog($this.StageLog("FAIL - PMS running"))
|
||||
$this.WriteLog("Auto - FAIL - PMS running")
|
||||
$this.OutputWarn("Unable to run automatic sequence. PMS is running. Please stop PlexMediaServer.")
|
||||
return $false
|
||||
return
|
||||
}
|
||||
|
||||
# Create temporary backup directory
|
||||
@ -329,113 +310,85 @@ class DBRepair {
|
||||
New-Item -Path $DBTemp -ItemType "directory" -ErrorVariable tempDirError *>$null
|
||||
if ($TempDirError) {
|
||||
$this.ExitDBMaintenance("Unable to create temporary database directory", $false)
|
||||
return $false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$this.Output("Exporting Main DB")
|
||||
$MainDBPath = Join-Path $this.PlexDBDir -ChildPath $this.MainDB
|
||||
$MainDBName = "com.plexapp.plugins.library.db"
|
||||
$MainDB = Join-Path $this.PlexDBDir -ChildPath $MainDBName
|
||||
$MainDBSQL = Join-Path $DBTemp -ChildPath "library.sql_$($this.TimeStamp)"
|
||||
if (!$this.FileExists($MainDBPath)) {
|
||||
$this.ExitDBMaintenance("Could not find $($this.MainDB) in database directory", $false)
|
||||
return $false
|
||||
if (!$this.FileExists($MainDB)) {
|
||||
$this.ExitDBMaintenance("Could not find $MainDBName in database directory", $false)
|
||||
return
|
||||
}
|
||||
|
||||
if (!$this.ExportPlexDB($MainDBPath, $MainDBSQL)) { return $false }
|
||||
if (!$this.ExportPlexDB($MainDB, $MainDBSQL)) { return }
|
||||
|
||||
$this.Output("Exporting Blobs DB")
|
||||
$BlobsDBPath = Join-Path $this.PlexDBDir -ChildPath $this.BlobsDB
|
||||
$BlobsDBName = "com.plexapp.plugins.library.blobs.db"
|
||||
$BlobsDB = Join-Path $this.PlexDBDir -ChildPath $BlobsDBName
|
||||
$BlobsDBSQL = Join-Path $DBTemp -ChildPath "blobs.sql_$($this.Timestamp)"
|
||||
if (!$this.FileExists($BlobsDBPath)) {
|
||||
$this.ExitDBMaintenance("Could not find $($this.BlobsDB) in database directory", $false)
|
||||
return $false
|
||||
if (!$this.FileExists($BlobsDB)) {
|
||||
$this.ExitDBMaintenance("Could not find $BlobsDBName in database directory", $false)
|
||||
return
|
||||
}
|
||||
|
||||
if (!$this.ExportPlexDB($BlobsDBPath, $BlobsDBSQL)) { return $false }
|
||||
if (!$this.ExportPlexDB($BlobsDB, $BlobsDBSQL)) { return }
|
||||
|
||||
$this.Output("Successfully exported the main and blobs databases. Proceeding to import into new database.")
|
||||
$this.WriteLog("Repair - Export databases - PASS")
|
||||
|
||||
# Make sure Plex hasn't been started while we were exporting
|
||||
if (!$this.CheckPMS("export")) { return $false }
|
||||
|
||||
$this.Output("Importing Main DB.")
|
||||
$MainDBImport = Join-Path $this.PlexDBDir -ChildPath "$($this.MainDB)_$($this.Timestamp)"
|
||||
if (!$this.ImportPlexDB($MainDBSQL, $MainDBImport)) { return $false }
|
||||
$MainDBImport = Join-Path $this.PlexDBDir -ChildPath "${MainDBName}_$($this.Timestamp)"
|
||||
if (!$this.ImportPlexDB($MainDBSQL, $MainDBImport)) { return }
|
||||
|
||||
$this.Output("Importing Blobs DB.")
|
||||
$BlobsDBImport = Join-Path $this.PlexDBDir -ChildPath "$($this.BlobsDB)_$($this.Timestamp)"
|
||||
if (!$this.ImportPlexDB($BlobsDBSQL, $BlobsDBImport)) { return $false }
|
||||
$this.Output("Creating Blobs DB")
|
||||
$BlobsDBImport = Join-Path $this.PlexDBDir -ChildPath "${BlobsDBName}_$($this.Timestamp)"
|
||||
if (!$this.ImportPlexDB($BlobsDBSQL, $BlobsDBImport)) { return }
|
||||
|
||||
$this.Output("Successfully imported databases.")
|
||||
$this.WriteLog("Repair - Import - PASS")
|
||||
|
||||
$this.Output("Verifying databases integrity after importing.")
|
||||
|
||||
if (!$this.IntegrityCheck($MainDBImport, "Main")) { return $false }
|
||||
if (!$this.IntegrityCheck($MainDBImport, "Main")) { return }
|
||||
$this.Output("Verification complete. PMS main database is OK.")
|
||||
$this.WriteLog("Repair - Verify main database - PASS")
|
||||
|
||||
if (!$this.IntegrityCheck($BlobsDBImport, "Blobs")) { return $false }
|
||||
if (!$this.IntegrityCheck($BlobsDBImport, "Blobs")) { return }
|
||||
$this.Output("Verification complete. PMS blobs database is OK.")
|
||||
$this.WriteLog("Repair - Verify blobs database - PASS")
|
||||
|
||||
if (!$this.CheckPMS("import")) { return $false }
|
||||
|
||||
# Import complete, now reindex
|
||||
$this.WriteOutputLog("Reindexing Main DB")
|
||||
if (!$this.RunSQLCommand("""$MainDBImport"" ""REINDEX;""", "Failed to reindex Main DB")) { return $false }
|
||||
if (!$this.RunSQLCommand("""$MainDBImport"" ""REINDEX;""", "Failed to reindex Main DB")) { return }
|
||||
$this.WriteOutputLog("Reindexing Blobs DB")
|
||||
if (!$this.RunSQLCommand("""$BlobsDBImport"" ""REINDEX;""", "Failed to reindex Blobs DB")) { return $false }
|
||||
if (!$this.RunSQLCommand("""$BlobsDBImport"" ""REINDEX;""", "Failed to reindex Blobs DB")) { return }
|
||||
$this.WriteOutputLog("Reindexing complete.")
|
||||
|
||||
$this.WriteOutputLog("Moving current DBs to DBTMP and making new databases active")
|
||||
if (!$this.CheckPMS("new database copy")) { return $false }
|
||||
|
||||
try {
|
||||
$this.MoveDatabase($MainDBPath, (Join-Path $DBTemp -ChildPath "$($this.MainDB)_$($this.Timestamp)"), "move Main DB to DBTMP")
|
||||
$this.MoveDatabase($MainDBImport, $MainDBPath, "replace Main DB with rebuilt DB")
|
||||
$MoveError = $null
|
||||
Move-Item -Path $MainDB -Destination (Join-Path $DBTemp -ChildPath "${MainDBName}_$($this.TimeStamp)") -ErrorVariable moveError *>$null
|
||||
if ($MoveError) { $this.ExitDBMaintenance("Unable to move Main DB to DBTMP: $MoveError", $false); return }
|
||||
Move-Item -Path $MainDBImport -Destination $MainDB -ErrorVariable moveError *>$null
|
||||
if ($MoveError) { $this.ExitDBMaintenance("Unable to replace Main DB with rebuilt DB: $MoveError", $false); return }
|
||||
|
||||
$this.MoveDatabase($BlobsDBPath, (Join-Path $DBTemp -ChildPath "$($this.BlobsDB)_$($this.Timestamp)"), "move Blobs DB to DBTMP")
|
||||
$this.MoveDatabase($BlobsDBImport, $BlobsDBPath, "replace Blobs DB with rebuilt DB")
|
||||
} catch {
|
||||
$Error.Clear()
|
||||
return $false
|
||||
}
|
||||
Move-Item -Path $BlobsDB -Destination (Join-Path $DBTemp -ChildPath "${BlobsDBName}_$($this.TimeStamp)") -ErrorVariable moveError *>$null
|
||||
if ($MoveError) { $this.ExitDBMaintenance("Unable to move Blobs DB to DBTMP: $MoveError", $false) }
|
||||
Move-Item -Path $BlobsDBImport -Destination $BlobsDB -ErrorVariable moveError *>$null
|
||||
if ($MoveError) { $this.ExitDBMaintenance("Unable to replace Blobs DB with rebuilt DB: $MoveError", $false); return }
|
||||
|
||||
$this.ExitDBMaintenance("Database repair/rebuild/reindex completed.", $true)
|
||||
return $true
|
||||
}
|
||||
|
||||
# Return whether we can continue DB repair (i.e. whether PMS is running) at the given stage in the process.
|
||||
[bool] CheckPMS([string] $SubStage) {
|
||||
if ($this.PMSRunning()) {
|
||||
$SubMessage = if ($SubStage) { "during $SubStage" } else { "" }
|
||||
$this.WriteLog($this.StageLog("FAIL - PMS running $SubMessage"))
|
||||
$this.OutputWarn("Unable to run $($this.Stage.TrimEnd()). PMS is running. Please stop PlexMediaServer.")
|
||||
return $false
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
# Try to move the source file to the destination. If it fails, attempt to find
|
||||
# open file handles (requires handle.exe on PATH) and throw.
|
||||
[void] MoveDatabase([string] $Source, [string] $Destination, [string] $FriendlyString) {
|
||||
$MoveError = $null
|
||||
Move-Item -Path $Source -Destination $Destination -ErrorVariable MoveError *>$null
|
||||
if ($MoveError) {
|
||||
$this.ExitDBMaintenance("Unable to $($FriendlyString): $MoveError", $false)
|
||||
throw "Unable to move database"
|
||||
}
|
||||
}
|
||||
|
||||
# Attempts to prune PhotoTranscoder images that are older than the specified date cutoff (30 days by default)
|
||||
[void] PrunePhotoTranscoderCache() {
|
||||
$this.WriteLog($this.StageLog("START"))
|
||||
$this.WriteLog("Prune - START")
|
||||
if ($this.PMSRunning()) {
|
||||
$this.OutputWarn("Unable to prune Phototranscoder cache. PMS is running.")
|
||||
$this.WriteLog($this.StageLog("FAIL - PMS running"))
|
||||
$this.WriteLog("Prune - FAIL - PMS running")
|
||||
return
|
||||
}
|
||||
|
||||
@ -449,7 +402,7 @@ class DBRepair {
|
||||
|
||||
if ($Prunable -eq 0) {
|
||||
$this.Output("No files found to prune.")
|
||||
$this.WriteLog($this.StageLog("PASS (no files found to prune)"))
|
||||
$this.WriteLog("Prune - PASS (no files found to prune)")
|
||||
return
|
||||
}
|
||||
|
||||
@ -462,13 +415,13 @@ class DBRepair {
|
||||
$Pruned = $PruneResult.PrunableFiles
|
||||
$Total = $PruneResult.TotalFiles
|
||||
$Saved = $PruneResult.SpaceSavings
|
||||
$this.WriteOutputLog($this.StageLog("Removed $Pruned files over $Cutoff days old ($Saved), out of $Total total files"))
|
||||
$this.WriteOutputLog("Prune - Removed $Pruned files over $Cutoff days old ($Saved), out of $Total total files")
|
||||
$this.Output("Pruning completed.")
|
||||
} else {
|
||||
$this.WriteOutputLog($this.StageLog("Prune cancelled by user"))
|
||||
$this.WriteOutputLog("Prune - Prune cancelled by user")
|
||||
}
|
||||
|
||||
$this.WriteLog($this.StageLog("PASS"))
|
||||
$this.WriteLog("Prune - PASS")
|
||||
}
|
||||
|
||||
# Traverses PhotoTranscoder cache to find and delete files older than the specified max age.
|
||||
@ -541,16 +494,6 @@ class DBRepair {
|
||||
$this.WriteLog("============================================================")
|
||||
}
|
||||
|
||||
# Set the current stage (with the right amount of padding)
|
||||
[void] SetStage([string] $Stage) {
|
||||
$this.Stage = $Stage + (" " * [math]::Max(0, 8 - $Stage.Length))
|
||||
}
|
||||
|
||||
# Prepend the current stage to the given text
|
||||
[string] StageLog([string] $text) {
|
||||
return "$($this.Stage) - $text"
|
||||
}
|
||||
|
||||
### File Helpers ###
|
||||
|
||||
# Check whether the given directory exists (and is a directory)
|
||||
@ -573,7 +516,7 @@ class DBRepair {
|
||||
|
||||
### Setup Helpers ###
|
||||
|
||||
# Retrieve Plex's data directory, exiting the script on failure
|
||||
# Retrieve Plex's data directory, exiting the script on falure
|
||||
[string] GetAppDataDir() {
|
||||
$PMSRegistry = $this.GetHKCU()
|
||||
$PlexAppData = $PMSRegistry.LocalAppDataPath
|
||||
@ -688,18 +631,14 @@ class DBRepair {
|
||||
[void] ExitDBMaintenance([string] $Message, [boolean] $Success) {
|
||||
if ($Success) {
|
||||
$this.Output("Automatic Check,Repair,Index succeeded.")
|
||||
$this.WriteLog($this.StageLog("PASS"))
|
||||
$this.WriteLog("Auto - PASS")
|
||||
} else {
|
||||
$this.OutputWarn("Database maintenance failed - $Message")
|
||||
$this.WriteLog($this.StageLog("$Message, cannot continue."))
|
||||
$this.WriteLog($this.StageLog("FAIL"))
|
||||
$this.OutputWarn("Automatic maintenance failed - $Message")
|
||||
$this.WriteLog("Auto - $Message, cannot continue.")
|
||||
$this.WriteLog("Auto - FAIL")
|
||||
}
|
||||
}
|
||||
|
||||
[bool] ExportPlexDB([string] $Source, [string] $Destination) {
|
||||
return $this.RunSQLCommand("""$Source"" "".output '$Destination'"" .dump", "Failed to export '$Source' to '$Destination'")
|
||||
}
|
||||
|
||||
# Run an SQL command.
|
||||
# ErrorMessage is the message to output/write to the log on failure
|
||||
[bool] RunSQLCommand([string] $Command, [string] $ErrorMessage) {
|
||||
@ -750,15 +689,35 @@ class DBRepair {
|
||||
return $true
|
||||
}
|
||||
|
||||
# Import an exported .sql file into a new database
|
||||
[bool] ImportPlexDB($Source, $Destination) {
|
||||
# SQLite's .read can't handle files larger than 2GB on versions <3.45.0 (https://sqlite.org/forum/forumpost/9af57ba66fbb5349),
|
||||
# and Plex SQLite is currently on 3.39.4 (as of PMS 1.41.6).
|
||||
# If the source is smaller than 2GB we can .read it directly, otherwise do things in a more roundabout way.
|
||||
if ($this.FileExists($Source) -and (Get-Item $Source).Length -lt 2GB) {
|
||||
return $this.RunSQLCommand("""$Destination"" "".read '$Source'""", "Failed to import Plex database (importing '$Source' into '$Destination')")
|
||||
[bool] ExportPlexDB([string] $Source, [string] $Destination) {
|
||||
$SqlError = $null
|
||||
$Command = """$Source"" .dump | Set-Content ""$Destination"" -Encoding utf8"
|
||||
|
||||
try {
|
||||
Invoke-Expression "& ""$($this.PlexSQL)"" $Command" -ev SqlError -EA Stop *>$null
|
||||
} catch {
|
||||
$Err = $Error -join "`n"
|
||||
# Even if we ignore errors, we can't continue if the export failed.
|
||||
$this.ExitDBMaintenance("Failed to export '$Source' to '$Destination': '$Err'", $false)
|
||||
$Error.Clear()
|
||||
return $false
|
||||
}
|
||||
|
||||
if ($SqlError) {
|
||||
$Err = $SqlError -join "`n"
|
||||
if ($this.Options.IgnoreErrors) {
|
||||
$this.OutputWarn("Ignoring database errors during export: $Err")
|
||||
} else {
|
||||
$this.ExitDBMaintenance("Failed to export '$Source' to '$Destination': '$Err'", $false)
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
# Import an exported .sql file into a new database
|
||||
[bool] ImportPlexDB($Source, $Destination) {
|
||||
$ImportError = $null
|
||||
$ExitCode = 0
|
||||
$Err = $null
|
||||
@ -801,7 +760,7 @@ class DBRepair {
|
||||
}
|
||||
}
|
||||
|
||||
$this.Options.CanIgnore = $true
|
||||
$this.Options.CanIgnore = $false
|
||||
return $result
|
||||
}
|
||||
|
||||
@ -832,7 +791,7 @@ class DBRepair {
|
||||
|
||||
# Return whether PMS is running
|
||||
[bool] PMSRunning() {
|
||||
return $null -ne $this.GetPMS()
|
||||
return !!$this.GetPMS()
|
||||
}
|
||||
|
||||
# Retrieve the PMS process, if running
|
||||
@ -856,14 +815,14 @@ class DBRepair {
|
||||
}
|
||||
|
||||
# Contains miscellaneous options/state over the course of a session.
|
||||
class DBRepairOptions {
|
||||
class PlexDBRepairOptions {
|
||||
[bool] $Scripted # Whether we're running in scripted or interactive mode
|
||||
[bool] $ShowMenu # Whether to show the menu after each command executes
|
||||
[bool] $IgnoreErrors # Whether to honor or ignore constraint errors on import
|
||||
[bool] $CanIgnore # Some errors can't be ignored (e.g. integrity_check)
|
||||
[int32] $CacheAge # The date cutoff for pruning PhotoTranscoder cached images
|
||||
|
||||
DBRepairOptions() {
|
||||
PlexDBRepairOptions() {
|
||||
$this.CacheAge = 30
|
||||
$this.ShowMenu = $true
|
||||
$this.Scripted = $false
|
||||
@ -898,7 +857,7 @@ $InputEncodingSave = [console]::InputEncoding
|
||||
$OutputEncodingSave = [console]::OutputEncoding
|
||||
[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
|
||||
|
||||
[void]([DBRepair]::new($args, $DBRepairVersion))
|
||||
[void]([PlexDBRepair]::new($args, $PlexDBRepairVersion))
|
||||
|
||||
[console]::OutputEncoding = $OutputEncodingSave
|
||||
[console]::InputEncoding = $InputEncodingSave
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# DBRepair-Windows
|
||||
# PlexDBRepair-Windows
|
||||
|
||||
DBRepair-Windows.ps1 (and DBRepair-Windows.bat) are scripts run from the command line, which have
|
||||
sufficient privilege to read/write the Plex databases in the
|
||||
@ -9,13 +9,13 @@ sufficient privilege to read/write the Plex databases in the
|
||||
Currently, there are two separate Windows scripts, a batch script (.bat) and a PowerShell script
|
||||
(.ps1). The batch script is a one-shot, zero-input script that attempts automatic database
|
||||
maintenance (repair/rebuild, check, and reindex). The PowerShell script is intended to align with
|
||||
DBRepair.sh, offering command-name-based functionality that can either be scripted or
|
||||
PlexDBRepair.sh, offering command-name-based functionality that can either be scripted or
|
||||
interactive.
|
||||
|
||||
In the future, DBRepair-Windows.bat will be removed in favor of DBRepair-Windows.ps1. The batch
|
||||
file is currently kept as a backup while the PowerShell script continues to be expanded and
|
||||
tested. If any unexpected issues arise with the PowerShell script, please open an
|
||||
[issue](https://github.com/ChuckPa/DBRepair/issues) so it can be investigated.
|
||||
[issue](https://github.com/ChuckPa/PlexDBRepair/issues) so it can be investigated.
|
||||
|
||||
## Functions provided
|
||||
|
||||
|
||||
@ -1,25 +1,9 @@
|
||||
# DBRepair-Windows
|
||||
# PlexDBRepair-Windows
|
||||
|
||||
Release notes for the Windows counterpart to DBRepair.sh (DBRepair-Windows.ps1)
|
||||
|
||||
# Release Info
|
||||
|
||||
v1.01.02
|
||||
- Remove `statistics_bandwidth` pruning, as it's now part of PMS 1.41.8
|
||||
- Change `quit` to 98 and `exit` to 99
|
||||
- Minor logging refactoring
|
||||
|
||||
v1.01.01
|
||||
- Add `staticstics_bandwidth` pruning during automatic repair.
|
||||
|
||||
v1.01.00
|
||||
- Rename this tool to be compliant with Plex inc. Trademark Policy.
|
||||
|
||||
v1.00.02
|
||||
- Check whether PMS is running at more points in the process.
|
||||
- Don't remove temp files in scripted mode if the last operation failed.
|
||||
- Better export process that improves upon the UTF-8 fix in v1.00.01.
|
||||
|
||||
v1.00.01
|
||||
- Bug Fix: Ensure UTF-8 characters get exported/imported properly.
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user