1 Commits

Author SHA1 Message Date
danrahn
f031aac81a Merge c9a9a1eb81 into ec9edaf304 2024-05-11 15:30:55 -07:00
11 changed files with 492 additions and 1331 deletions

View File

@@ -10,7 +10,7 @@ To contribute to the project, please follow the following instructions:
### When submitting your work for review and merge: ### 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 - Describe the deficiency to be addressed in sufficient detail
2. Complete your work in your branch 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 5. In the pull request, provide a description of what change(s) where made
- As last text added, on a blank line, - As last text added, on a blank line,
- Add the text: `Fixes:` followed by the URL of the open Issue - 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: - Adding the above text & URL has the following impact:
-- The Issue which prompted the change is forever linked to the PR making documentation easy. -- The Issue which prompted the change is forever linked to the PR making documentation easy.

View File

@@ -1,5 +1,5 @@
@echo off @echo off
REM DBRepair.bat - Database maintenance / rebuild tool for Windows. REM PlexDBRepair.bat - Database maintenance / rebuild tool for Windows.
REM REM
REM This tool currently works as a "full shot" service. REM This tool currently works as a "full shot" service.
REM - everything is done without need to interact. REM - everything is done without need to interact.
@@ -12,7 +12,7 @@ setlocal enabledelayedexpansion
echo. echo.
echo NOTE: This script is being replaced with the PowerShell script DBRepair-Windows.ps1, 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 Consider moving over to the new script.
echo. echo.
@@ -78,13 +78,13 @@ set "TmpFile=%DBtmp%\results.tmp"
REM Time now. REM Time now.
echo %time% -- ====== Session begins. (%date%) ====== 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. REM Make certain Plex is NOT running.
tasklist | find /I "Plex Media Server.exe" >NUL tasklist | find /I "Plex Media Server.exe" >NUL
if %ERRORLEVEL%==0 ( 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.
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 exit /B 1
) )
@@ -94,12 +94,8 @@ cd "%PlexData%"
md "%PlexData%\dbtmp" 2>NUL md "%PlexData%\dbtmp" 2>NUL
del "%TmpFile%" 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
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%" echo .dump | "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db" > "%DBtmp%\library.sql_%TimeStamp%"
if not %ERRORLEVEL%==0 ( if not %ERRORLEVEL%==0 (
echo %time% -- ERROR: Cannot export Main DB. Aborting. 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
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%" echo .dump | "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db" > "%DBtmp%\blobs.sql_%TimeStamp%"
if not %ERRORLEVEL%==0 ( if not %ERRORLEVEL%==0 (
echo %time% -- ERROR: Cannot export Blobs DB. Aborting. echo %time% -- ERROR: Cannot export Blobs DB. Aborting.
@@ -115,75 +111,75 @@ if not %ERRORLEVEL%==0 (
REM Now create new databases from SQL statements REM Now create new databases from SQL statements
echo %time% -- Exporting Complete. 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
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%" "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" < "%DBtmp%\library.sql_%TimeStamp%"
if not %ERRORLEVEL%==0 ( if not %ERRORLEVEL%==0 (
echo %time% -- ERROR: Cannot create Main DB. Aborting. 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 exit /b 3
) )
echo %time% -- Verifying Main DB 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%" "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "PRAGMA integrity_check(1)" >"%TmpFile%"
set /p Result= < "%TmpFile%" set /p Result= < "%TmpFile%"
del "%TmpFile%" del "%TmpFile%"
echo %time% -- Main DB verification check is: %Result% 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" ( if not "%Result%" == "ok" (
echo %time% -- ERROR: Main DB verification failed. Exiting. echo %time% -- ERROR: Main DB verificaion failed. Exiting.
echo %time% -- ERROR: Main DB verification failed. Exiting. >> "%PlexData%\DBRepair.log" echo %time% -- ERROR: Main DB verificaion failed. Exiting. >> "%PlexData%\PlexDBRepair.log"
exit /B 4 exit /B 4
) )
echo %time% -- Main DB verification successful. 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
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%" "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" < "%DBtmp%\blobs.sql_%TimeStamp%"
if not %ERRORLEVEL%==0 ( if not %ERRORLEVEL%==0 (
echo %time% -- ERROR: Cannot create Blobs DB. Aborting. 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 exit /b 5
) )
echo %time% -- Verifying Blobs DB 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%" "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" "PRAGMA integrity_check(1)" > "%TmpFile%"
set /p Result= < "%TmpFile%" set /p Result= < "%TmpFile%"
del "%TmpFile%" del "%TmpFile%"
echo %time% -- Blobs DB verification check is: %Result% 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" ( if not "%Result%" == "ok" (
echo %time% -- ERROR: Blobs DB verification failed. Exiting. echo %time% -- ERROR: Blobs DB verificaion failed. Exiting.
echo %time% -- ERROR: Blobs DB verification failed. Exiting. >> "%PlexData%\DBRepair.log" echo %time% -- ERROR: Blobs DB verificaion failed. Exiting. >> "%PlexData%\PlexDBRepair.log"
exit /B 6 exit /B 6
) )
echo %time% -- Blobs DB verification successful. 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.
echo %time% -- Import and verification complete. >> "%PlexData%\DBRepair.log" echo %time% -- Import and verification complete. >> "%PlexData%\PlexDBRepair.log"
REM Import complete, now reindex REM Import complete, now reindex
echo %time% -- Reindexing Main DB 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;" "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "REINDEX;"
echo %time% -- Reindexing Blobs DB 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;" "%PlexSQL%" "%PlexData%\com.plexapp.plugins.library.blobs.db_%TimeStamp%" "REINDEX;"
REM Index complete, make active REM Index complete, make active
echo %time% -- Reindexing complete. 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
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" "%PlexData%\dbtmp\com.plexapp.plugins.library.db_%TimeStamp%"
move "%PlexData%\com.plexapp.plugins.library.db_%TimeStamp%" "%PlexData%\com.plexapp.plugins.library.db" 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" 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.
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. ======
echo %time% -- ====== Session completed. ====== >> "%PlexData%\DBRepair.log" echo %time% -- ====== Session completed. ====== >> "%PlexData%\PlexDBRepair.log"
exit /b exit /b
@@ -205,5 +201,5 @@ REM Output - Write text to the console and the log file
:Output :Output
echo %time% %~1 echo %time% %~1
echo %time% %~1 >> "%PlexData%\DBRepair.log" echo %time% %~1 >> "%PlexData%\PlexDBRepair.log"
exit /B exit /B

View File

@@ -1,28 +1,19 @@
######################################################################### #########################################################################
# Database check and repair utility script for Plex Media Server # # Plex Media Server database check and repair utility script. #
# # # #
######################################################################### #########################################################################
$DBRepairVersion = 'v1.01.02' class PlexDBRepair {
[PlexDBRepairOptions] $Options
class DBRepair {
[DBRepairOptions] $Options
[string] $PlexDBDir # Path to Plex's Databases directory [string] $PlexDBDir # Path to Plex's Databases directory
[string] $PlexCache # Path to the PhotoTranscoder directory [string] $PlexCache # Path to the PhotoTranscoder directory
[string] $PlexSQL # Path to 'Plex SQLite.exe' [string] $PlexSQL # Path to 'Plex SQLite.exe'
[string] $Timestamp # Timestamp used for temporary database files [string] $Timestamp # Timestamp used for temporary database files
[string] $LogFile # Path of our log file [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) { PlexDBRepair($Arguments) {
$this.Options = [DBRepairOptions]::new() $this.Options = [PlexDBRepairOptions]::new()
$this.Version = $Version
$this.IsError = $false
$Commands = $this.PreprocessArgs($Arguments) $Commands = $this.PreprocessArgs($Arguments)
if ($null -eq $Commands) { if ($null -eq $Commands) {
return return
@@ -33,26 +24,23 @@ class DBRepair {
return return
} }
$this.PrintHeader($true) $this.PrintHeader()
$this.MainLoop($Commands) $this.MainLoop($Commands)
} }
[void] PrintHeader([boolean] $WriteToLog) { [void] PrintHeader() {
$OS = [System.Environment]::OSVersion.Version $OS = [System.Environment]::OSVersion.Version
if ($WriteToLog) { $this.WriteLog("============================================================")
$this.WriteLog("============================================================") $this.WriteLog("Session start: Host is Windows $($OS.Major) (Build $($OS.Build))")
$this.WriteLog("Session start: Host is Windows $($OS.Major) (Build $($OS.Build))")
}
Write-Host "`n" Write-Host "`n"
Write-Host " Database Repair Utility for Plex Media Server (Windows $($OS.Major), Build $($OS.Build))" Write-Host " Plex Media Server Database Repair Utility (Windows $($OS.Major), Build $($OS.Build))"
Write-Host " Version $($this.Version) " Write-Host " Version v1.06.00 "
Write-Host Write-Host
} }
[void] PrintHelp() { [void] PrintHelp() {
# -Help doesn't write to the log, since our log file path isn't set. $this.PrintHeader()
$this.PrintHeader($false)
Write-Host "When run without arguments, starts an interactive session that displays available options" Write-Host "When run without arguments, starts an interactive session that displays available options"
Write-Host "and lets you select the operations you want to perform. Or, to run tasks automatically," Write-Host "and lets you select the operations you want to perform. Or, to run tasks automatically,"
Write-Host "provide them directly to the script, e.g. '.\DBRepair-Windows.ps1 Stop Prune Start Exit'" Write-Host "provide them directly to the script, e.g. '.\DBRepair-Windows.ps1 Stop Prune Start Exit'"
@@ -82,14 +70,9 @@ class DBRepair {
Write-Host " 7 - 'start' - Start PMS" Write-Host " 7 - 'start' - Start PMS"
Write-Host Write-Host
Write-Host " 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache." Write-Host " 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache."
if ($this.Options.IgnoreErrors) {
Write-Host " 42 - 'honor' - Honor all database errors."
} else {
Write-Host " 42 - 'ignore' - Ignore duplicate/constraint errors."
}
Write-Host Write-Host
Write-Host " 98 - 'quit' - Quit immediately. Keep all temporary files." Write-Host " 99 - 'quit' - Quit immediately. Keep all temporary files."
Write-Host " 99 'exit' - Exit with cleanup options." Write-Host " 'exit' - Exit with cleanup options."
Write-Host Write-Host
Write-Host " 'menu x' - Show this menu in interactive mode, where x is on/off/yes/no" Write-Host " 'menu x' - Show this menu in interactive mode, where x is on/off/yes/no"
} }
@@ -141,7 +124,7 @@ class DBRepair {
$AppData = $this.GetAppDataDir() $AppData = $this.GetAppDataDir()
$Success = $this.GetPlexDBDir($AppData) -and $this.GetPlexSQL() -and $this.GetPhotoTranscoderDir($AppData) $Success = $this.GetPlexDBDir($AppData) -and $this.GetPlexSQL() -and $this.GetPhotoTranscoderDir($AppData)
if ($Success) { if ($Success) {
$this.LogFile = Join-Path $this.PlexDBDir -ChildPath "DBRepair.log" $this.LogFile = Join-Path $this.PlexDBDir -ChildPath "PlexDBRepair.log"
} }
return $Success return $Success
@@ -171,19 +154,13 @@ class DBRepair {
$Choice = Read-Host "Enter command # -or- command name (4 char min)" $Choice = Read-Host "Enter command # -or- command name (4 char min)"
if ($Choice -eq "") { if ($Choice -eq "") {
++$NullInput ++$NullInput
if ($NullInput -eq 5) { if ($NullInput -eq 4) {
Write-Warning "Next empty command exists as EOF. "
} elseif ($NullInput -eq 5) {
$this.Output("Unexpected EOF / End of command line options. Exiting. Keeping temp files. ") $this.Output("Unexpected EOF / End of command line options. Exiting. Keeping temp files. ")
$Choice = "exit" $Choice = "exit"
$EOFExit = $true $EOFExit = $true
} else {
if ($NullInput -eq 4) {
Write-Warning "Next empty command exits as EOF. "
}
continue
} }
} else {
$NullInput = 0
} }
} }
@@ -192,46 +169,22 @@ class DBRepair {
switch -Regex ($Choice) { switch -Regex ($Choice) {
"^(1|stop)$" { $this.DoStop() } "^(1|stop)$" { $this.DoStop() }
"^(2|autom?a?t?i?c?)$" { "^(2|autom?a?t?i?c?)$" { $this.RunAutomaticDatabaseMaintenance() }
$this.SetStage("Auto")
$this.IsError = !$this.RunAutomaticDatabaseMaintenance()
}
"^(7|start?)$" { $this.StartPMS() } "^(7|start?)$" { $this.StartPMS() }
"^(21|(prune?|remov?e?))$" { "^(21|(prune?|remov?e?))$" { $this.PrunePhotoTranscoderCache() }
$this.SetStage("Prune") "^(99|quit)$" {
$this.PrunePhotoTranscoderCache() $this.Output("Retaining all remporary work files.")
}
"^(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."
Break
}
$this.Options.IgnoreErrors = !$this.Options.IgnoreErrors
$msg = if ($this.Options.IgnoreErrors) { "Ignoring database errors." } else { "Honoring database errors." }
$this.WriteOutputLog($msg)
}
"^(98|quit)$" {
$this.Output("Retaining all temporary work files.")
$this.WriteLog("Exit - Retain temp files.") $this.WriteLog("Exit - Retain temp files.")
$this.WriteEnd() $this.WriteEnd()
return return
} }
"^(99|exit)$" { "^exit$" {
if ($EOFExit) { if ($EOFExit) {
$this.Output("Unexpected exit command. Keeping all temporary work files.") $this.Output("Unexpected exit command. Keeping all temporary work files.")
$this.WriteLog("EOFExit - Retain temp files.") $this.WriteLog("EOFExit - Retain temp files.")
return 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.CleanDBTemp(!$this.Options.Scripted)
$this.WriteEnd() $this.WriteEnd()
return return
@@ -261,18 +214,19 @@ class DBRepair {
[void] DoStop() { [void] DoStop() {
$this.WriteLog("Stop - START") $this.WriteLog("Stop - START")
$PMS = $this.GetPMS() $PMS = $this.GetPMS()
if ($null -eq $PMS) { if ($PMS) {
$this.Output("Stopping PMS.")
} else {
$this.Output("PMS already stopped.") $this.Output("PMS already stopped.")
return return
} }
$this.Output("Stopping PMS.")
# Plex doesn't respond to CloseMainWindow because it doesn't have a window, # 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 # and Stop-Process does a forced exit of the process, so use taskkill to ask
# PMS to close nicely, and bail if that doesn't work. # PMS to close nicely, and bail if that doesn't work.
$ErrorText = $null $ErrorText = $null
Invoke-Expression "taskkill /im ""Plex Media Server.exe""" 2>$null -ErrorVariable ErrorText Invoke-Expression "taskkill /im ""Plex Media Server.exe""" 2>$null -ErrorVariable errorText
if ($ErrorText) { if ($ErrorText) {
$this.WriteOutputLogWarn("Failed to send terminate signal to PMS, please stop manually.") $this.WriteOutputLogWarn("Failed to send terminate signal to PMS, please stop manually.")
$this.WriteOutputLogWarn($ErrorText -join "`n") $this.WriteOutputLogWarn($ErrorText -join "`n")
@@ -283,11 +237,10 @@ class DBRepair {
if ($PMS.HasExited) { if ($PMS.HasExited) {
$this.WriteLog("Stop - PASS") $this.WriteLog("Stop - PASS")
$this.Output("Stopped PMS.") $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 # Start Plex Media Server if it isn't already running
@@ -312,14 +265,14 @@ class DBRepair {
} }
# All-in-one database utility - Repair/Check/Reindex # All-in-one database utility - Repair/Check/Reindex
[bool] RunAutomaticDatabaseMaintenance() { [void] RunAutomaticDatabaseMaintenance() {
$this.Output("Automatic Check,Repair,Index started.") $this.Output("Automatic Check,Repair,Index started.")
$this.WriteLog($this.StageLog("START")) $this.WriteLog("Auto - START")
if ($this.PMSRunning()) { 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.") $this.OutputWarn("Unable to run automatic sequence. PMS is running. Please stop PlexMediaServer.")
return $false return
} }
# Create temporary backup directory # Create temporary backup directory
@@ -329,113 +282,97 @@ class DBRepair {
New-Item -Path $DBTemp -ItemType "directory" -ErrorVariable tempDirError *>$null New-Item -Path $DBTemp -ItemType "directory" -ErrorVariable tempDirError *>$null
if ($TempDirError) { if ($TempDirError) {
$this.ExitDBMaintenance("Unable to create temporary database directory", $false) $this.ExitDBMaintenance("Unable to create temporary database directory", $false)
return $false return
} }
} }
$this.Output("Exporting Main DB") $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)" $MainDBSQL = Join-Path $DBTemp -ChildPath "library.sql_$($this.TimeStamp)"
if (!$this.FileExists($MainDBPath)) { if (!$this.FileExists($MainDB)) {
$this.ExitDBMaintenance("Could not find $($this.MainDB) in database directory", $false) $this.ExitDBMaintenance("Could not find $MainDBName in database directory", $false)
return $false return
} }
if (!$this.ExportPlexDB($MainDBPath, $MainDBSQL)) { return $false } if (!$this.RunSQLCommand("""$MainDB"" .dump | Set-Content ""$MainDBSQL"" -Encoding utf8", "Failed to export main database")) { return }
$this.Output("Exporting Blobs DB") $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)" $BlobsDBSQL = Join-Path $DBTemp -ChildPath "blobs.sql_$($this.Timestamp)"
if (!$this.FileExists($BlobsDBPath)) { if (!$this.FileExists($BlobsDB)) {
$this.ExitDBMaintenance("Could not find $($this.BlobsDB) in database directory", $false) $this.ExitDBMaintenance("Could not find $BlobsDBName in database directory", $false)
return $false return
} }
if (!$this.ExportPlexDB($BlobsDBPath, $BlobsDBSQL)) { return $false } if (!$this.RunSQLCommand("""$BlobsDB"" .dump | Set-Content ""$BlobsDBSQL"" -Encoding utf8", "Failed to export blobs database")) { return }
$this.Output("Successfully exported the main and blobs databases. Proceeding to import into new database.") $this.Output("Successfully exported the main and blobs databases. Proceeding to import into new database.")
$this.WriteLog("Repair - Export databases - PASS") $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.") $this.Output("Importing Main DB.")
$MainDBImport = Join-Path $this.PlexDBDir -ChildPath "$($this.MainDB)_$($this.Timestamp)" $MainDBImport = Join-Path $this.PlexDBDir -ChildPath "${MainDBName}_$($this.Timestamp)"
if (!$this.ImportPlexDB($MainDBSQL, $MainDBImport)) { return $false } if (!$this.ImportPlexDB($MainDBSQL, $MainDBImport)) { return }
$this.Output("Importing Blobs DB.") $this.Output("Creating Blobs DB")
$BlobsDBImport = Join-Path $this.PlexDBDir -ChildPath "$($this.BlobsDB)_$($this.Timestamp)" $BlobsDBImport = Join-Path $this.PlexDBDir -ChildPath "${BlobsDBName}_$($this.Timestamp)"
if (!$this.ImportPlexDB($BlobsDBSQL, $BlobsDBImport)) { return $false } if (!$this.ImportPlexDB($BlobsDBSQL, $BlobsDBImport)) { return }
$this.Output("Successfully imported databases.") $this.Output("Successfully imported databases.")
$this.WriteLog("Repair - Import - PASS") $this.WriteLog("Repair - Import - PASS")
$this.Output("Verifying databases integrity after importing.") $this.Output("Verifying databases integrity after importing.")
if (!$this.IntegrityCheck($MainDBImport, "Main")) { return $false } $VerifyResult = ""
if (!$this.GetSQLCommandResult("""$MainDBImport"" ""PRAGMA integrity_check(1)""", "Failed to verify main DB", [ref]$VerifyResult)) { return }
$this.Output("Main DB verification check is: $VerifyResult")
if ($VerifyResult -ne "ok") {
$this.ExitDBMaintenance("Main DB verification failed: $VerifyResult", $false)
return
}
$this.Output("Verification complete. PMS main database is OK.") $this.Output("Verification complete. PMS main database is OK.")
$this.WriteLog("Repair - Verify main database - PASS") $this.WriteLog("Repair - Verify main database - PASS")
if (!$this.IntegrityCheck($BlobsDBImport, "Blobs")) { return $false } if (!$this.GetSQLCommandResult("""$BlobsDBImport"" ""PRAGMA integrity_check(1)""", "Failed to verify main DB", [ref]$VerifyResult)) { return }
if ($VerifyResult -ne "ok") {
$this.ExitDBMaintenance("Blobs DB verification failed: $VerifyResult", $false)
return
}
$this.Output("Verification complete. PMS blobs database is OK.") $this.Output("Verification complete. PMS blobs database is OK.")
$this.WriteLog("Repair - Verify blobs database - PASS") $this.WriteLog("Repair - Verify blobs database - PASS")
if (!$this.CheckPMS("import")) { return $false }
# Import complete, now reindex # Import complete, now reindex
$this.WriteOutputLog("Reindexing Main DB") $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") $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("Reindexing complete.")
$this.WriteOutputLog("Moving current DBs to DBTMP and making new databases active") $this.WriteOutputLog("Moving current DBs to DBTMP and making new databases active")
if (!$this.CheckPMS("new database copy")) { return $false }
try { $MoveError = $null
$this.MoveDatabase($MainDBPath, (Join-Path $DBTemp -ChildPath "$($this.MainDB)_$($this.Timestamp)"), "move Main DB to DBTMP") Move-Item -Path $MainDB -Destination (Join-Path $DBTemp -ChildPath "${MainDBName}_$($this.TimeStamp)") -ErrorVariable moveError *>$null
$this.MoveDatabase($MainDBImport, $MainDBPath, "replace Main DB with rebuilt DB") if ($MoveError) { $this.ExitDBMaintenance("Unable to move Main DB to DBTMP: $MoveError", $false); return }
Move-Item -Path $MainDBImport -Destination $MainDB -ErrorVariable moveError *>$null
$this.MoveDatabase($BlobsDBPath, (Join-Path $DBTemp -ChildPath "$($this.BlobsDB)_$($this.Timestamp)"), "move Blobs DB to DBTMP") if ($MoveError) { $this.ExitDBMaintenance("Unable to replace Main DB with rebuilt DB: $MoveError", $false); return }
$this.MoveDatabase($BlobsDBImport, $BlobsDBPath, "replace Blobs DB with rebuilt DB")
} catch { Move-Item -Path $BlobsDB -Destination (Join-Path $DBTemp -ChildPath "${BlobsDBName}_$($this.TimeStamp)") -ErrorVariable moveError *>$null
$Error.Clear() if ($MoveError) { $this.ExitDBMaintenance("Unable to move Blobs DB to DBTMP: $MoveError", $false) }
return $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) $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) # Attempts to prune PhotoTranscoder images that are older than the specified date cutoff (30 days by default)
[void] PrunePhotoTranscoderCache() { [void] PrunePhotoTranscoderCache() {
$this.WriteLog($this.StageLog("START")) $this.WriteLog("Prune - START")
if ($this.PMSRunning()) { if ($this.PMSRunning()) {
$this.OutputWarn("Unable to prune Phototranscoder cache. PMS is running.") $this.OutputWarn("Unable to prune Phototranscoder cache. PMS is running.")
$this.WriteLog($this.StageLog("FAIL - PMS running")) $this.WriteLog("Prune - FAIL - PMS running")
return return
} }
@@ -449,7 +386,7 @@ class DBRepair {
if ($Prunable -eq 0) { if ($Prunable -eq 0) {
$this.Output("No files found to prune.") $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 return
} }
@@ -462,13 +399,13 @@ class DBRepair {
$Pruned = $PruneResult.PrunableFiles $Pruned = $PruneResult.PrunableFiles
$Total = $PruneResult.TotalFiles $Total = $PruneResult.TotalFiles
$Saved = $PruneResult.SpaceSavings $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.") $this.Output("Pruning completed.")
} else { } 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. # Traverses PhotoTranscoder cache to find and delete files older than the specified max age.
@@ -541,16 +478,6 @@ class DBRepair {
$this.WriteLog("============================================================") $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 ### ### File Helpers ###
# Check whether the given directory exists (and is a directory) # Check whether the given directory exists (and is a directory)
@@ -573,7 +500,7 @@ class DBRepair {
### Setup Helpers ### ### Setup Helpers ###
# Retrieve Plex's data directory, exiting the script on failure # Retrieve Plex's data directory, exiting the script on falure
[string] GetAppDataDir() { [string] GetAppDataDir() {
$PMSRegistry = $this.GetHKCU() $PMSRegistry = $this.GetHKCU()
$PlexAppData = $PMSRegistry.LocalAppDataPath $PlexAppData = $PMSRegistry.LocalAppDataPath
@@ -600,7 +527,7 @@ class DBRepair {
try { try {
return (Get-ItemProperty -path 'HKCU:\Software\Plex, Inc.\Plex Media Server' -EA Stop) return (Get-ItemProperty -path 'HKCU:\Software\Plex, Inc.\Plex Media Server' -EA Stop)
} catch { } catch {
Write-Warning "Could not find Plex registry settings (HKCU\Software\Plex, Inc.\Plex Media Server). Are you sure Plex is installed on this machine?" Write-Warn "Could not find Plex registry settings (HKCU\Software\Plex, Inc.\Plex Media Server). Are you sure Plex is installed on this machine?"
exit exit
} }
} }
@@ -688,18 +615,14 @@ class DBRepair {
[void] ExitDBMaintenance([string] $Message, [boolean] $Success) { [void] ExitDBMaintenance([string] $Message, [boolean] $Success) {
if ($Success) { if ($Success) {
$this.Output("Automatic Check,Repair,Index succeeded.") $this.Output("Automatic Check,Repair,Index succeeded.")
$this.WriteLog($this.StageLog("PASS")) $this.WriteLog("Auto - PASS")
} else { } else {
$this.OutputWarn("Database maintenance failed - $Message") $this.OutputWarn("Automatic maintenance failed - $Message")
$this.WriteLog($this.StageLog("$Message, cannot continue.")) $this.WriteLog("Auto - $Message, cannot continue.")
$this.WriteLog($this.StageLog("FAIL")) $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. # Run an SQL command.
# ErrorMessage is the message to output/write to the log on failure # ErrorMessage is the message to output/write to the log on failure
[bool] RunSQLCommand([string] $Command, [string] $ErrorMessage) { [bool] RunSQLCommand([string] $Command, [string] $ErrorMessage) {
@@ -708,7 +631,7 @@ class DBRepair {
# Run an SQL command and retrieve the output of said command # Run an SQL command and retrieve the output of said command
# ErrorMessage is the message to output/write to the log on failure # ErrorMessage is the message to output/write to the log on failure
[bool] GetSQLCommandResult([string] $Command, [string] $ErrorMessage, [ref] $Output) { [bool] GetSQLCommandResult([string] $Command, [string] $ErrorMessage, [ref]$Output) {
return $this.RunSQLCommandCore($Command, $ErrorMessage, $Output) return $this.RunSQLCommandCore($Command, $ErrorMessage, $Output)
} }
@@ -716,10 +639,8 @@ class DBRepair {
[bool] RunSQLCommandCore([string] $Command, [string] $ErrorMessage, [ref] $Output) { [bool] RunSQLCommandCore([string] $Command, [string] $ErrorMessage, [ref] $Output) {
$SqlError = $null $SqlError = $null
$SqlResult = $null $SqlResult = $null
$ExitCode = 0
try { try {
Invoke-Expression "& ""$($this.PlexSQL)"" $Command" -ev sqlError -OutVariable sqlResult -EA Stop *>$null Invoke-Expression "& ""$($this.PlexSQL)"" $Command" -ev sqlError -OutVariable sqlResult -EA Stop *>$null
$ExitCode = $LASTEXITCODE
} catch { } catch {
$Err = $Error -join "`n" $Err = $Error -join "`n"
$this.ExitDBMaintenance("Failed to run command '$Command': '$Err'", $false) $this.ExitDBMaintenance("Failed to run command '$Command': '$Err'", $false)
@@ -727,20 +648,15 @@ class DBRepair {
return $false return $false
} }
if ($SqlError -or $ExitCode) { if ($SqlError) {
$Err = $SqlError -join "`n" $Err = $SqlError -join "`n"
if (!$Err) { $Err = "Process exited with error code $ExitCode" }
$Msg = $ErrorMessage $Msg = $ErrorMessage
if (!$Msg) { if (!$Msg) {
$Msg = "Plex SQLite operation failed" $Msg = "Plex SQLite operation failed"
} }
if ($this.Options.IgnoreErrors -and $this.Options.CanIgnore) { $this.ExitDBMaintenance("${msg}: $Err", $false)
$this.OutputWarn("Ignoring database errors - ${Msg}: $Err") return $false
} else {
$this.ExitDBMaintenance("${Msg}: $Err", $false)
return $false
}
} }
if ($null -ne $Output.Value) { if ($null -ne $Output.Value) {
@@ -752,36 +668,19 @@ class DBRepair {
# Import an exported .sql file into a new database # Import an exported .sql file into a new database
[bool] ImportPlexDB($Source, $Destination) { [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')")
}
$ImportError = $null $ImportError = $null
$ExitCode = 0
$Err = $null
try { try {
# Use Start-Process, since PowerShell doesn't have '<', and alternatives ("Get-Content X | SQLite.exe OutDB") are subpar at best when dealing with large files like these database exports. # Use Start-Process, since PowerShell doesn't have '<', and alternatives ("Get-Content X | SQLite.exe OutDB") are subpar at best when dealing with large files like these database exports.
$process = Start-Process $this.PlexSQL -ArgumentList @("""$Destination""") -RedirectStandardInput $Source -NoNewWindow -Wait -PassThru -EA Stop -ErrorVariable ImportError Start-Process $this.PlexSQL -ArgumentList @("""$Destination""") -RedirectStandardInput $Source -NoNewWindow -Wait -EA Stop -ErrorVariable importError
$ExitCode = $process.ExitCode
} catch { } catch {
$Err = $Error -join "`n" $Err = $Error -join "`n"
$this.ExitDBMaintenance("Failed to import Plex database (importing '$Source' into '$Destination): $Err", $false)
$Error.Clear() $Error.Clear()
return $false
} }
if ($ImportError) { if ($ImportError) {
$Err = $ImportError -join "`n" $Err = $ImportError -join "`n"
} elseif ($ExitCode) {
if ($this.Options.IgnoreErrors) {
$this.OutputWarn("Ignoring errors found during import")
} else {
$Err = "Process exited with error code $ExitCode (constraint error?)"
}
}
if ($Err) {
$this.ExitDBMaintenance("Failed to import Plex database (importing '$Source' into '$Destination'): $Err", $false) $this.ExitDBMaintenance("Failed to import Plex database (importing '$Source' into '$Destination'): $Err", $false)
return $false return $false
} }
@@ -789,22 +688,6 @@ class DBRepair {
return $true return $true
} }
[bool] IntegrityCheck([string] $Database, [string] $DbName) {
$this.Options.CanIgnore = $false
$VerifyResult = ""
$result = $this.GetSQLCommandResult("""$Database"" ""PRAGMA integrity_check(1)""", "Failed to verify $dbName DB", [ref]$VerifyResult)
if ($result) {
$this.Output("$DbName DB verification check is: $VerifyResult")
if ($VerifyResult -ne "ok") {
$this.ExitDBMaintenance("$DbName DB verification failed: $VerifyResult", $false)
$result = $false
}
}
$this.Options.CanIgnore = $true
return $result
}
# Clear out the temp database directory. If $Confirm is $true, asks the user before doing so. # Clear out the temp database directory. If $Confirm is $true, asks the user before doing so.
[void] CleanDBTemp([bool] $Confirm) { [void] CleanDBTemp([bool] $Confirm) {
if ($Confirm -and !$this.GetYesNo("Ok to remove temporary databases/workfiles for this session")) { if ($Confirm -and !$this.GetYesNo("Ok to remove temporary databases/workfiles for this session")) {
@@ -832,7 +715,7 @@ class DBRepair {
# Return whether PMS is running # Return whether PMS is running
[bool] PMSRunning() { [bool] PMSRunning() {
return $null -ne $this.GetPMS() return !!$this.GetPMS()
} }
# Retrieve the PMS process, if running # Retrieve the PMS process, if running
@@ -856,19 +739,15 @@ class DBRepair {
} }
# Contains miscellaneous options/state over the course of a session. # 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] $Scripted # Whether we're running in scripted or interactive mode
[bool] $ShowMenu # Whether to show the menu after each command executes [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 [int32] $CacheAge # The date cutoff for pruning PhotoTranscoder cached images
DBRepairOptions() { PlexDBRepairOptions() {
$this.CacheAge = 30 $this.CacheAge = 30
$this.ShowMenu = $true $this.ShowMenu = $true
$this.Scripted = $false $this.Scripted = $false
$this.IgnoreErrors = $false
$this.CanIgnore = $true
} }
} }
@@ -893,12 +772,4 @@ class CleanCacheResult {
} }
} }
# Ensure the console can handle utf-8, as the export process pipes utf-8 data from the console to our temporary sql file. [void]([PlexDBRepair]::new($args))
$InputEncodingSave = [console]::InputEncoding
$OutputEncodingSave = [console]::OutputEncoding
[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
[void]([DBRepair]::new($args, $DBRepairVersion))
[console]::OutputEncoding = $OutputEncodingSave
[console]::InputEncoding = $InputEncodingSave

BIN
DBRepair-Windows.zip Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,7 @@
Copyright (c) 2025, ChuckPa. Copyright (c) 2022, ChuckPa.
This software is the intellectual property 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.
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.
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. 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.

324
README.md
View File

@@ -1,9 +1,9 @@
# DBRepair (for Plex Media Server) # PlexDBRepair
[![GitHub issues](https://img.shields.io/github/issues/ChuckPa/DBRepair.svg?style=flat)](https://github.com/ChuckPa/DBRepair/issues) [![GitHub issues](https://img.shields.io/github/issues/ChuckPa/PlexDBRepair.svg?style=flat)](https://github.com/ChuckPa/PlexDBRepair/issues)
[![Release](https://img.shields.io/github/release/ChuckPa/DBRepair.svg?style=flat)](https://github.com/ChuckPa/DBRepair/releases/latest) [![Release](https://img.shields.io/github/release/ChuckPa/PlexDBRepair.svg?style=flat)](https://github.com/ChuckPa/PlexDBRepair/releases/latest)
[![Download latest release](https://img.shields.io/github/downloads/ChuckPa/DBRepair/latest/total.svg)](https://github.com/ChuckPa/DBRepair/releases/latest) [![Download latest release](https://img.shields.io/github/downloads/ChuckPa/PlexDBRepair/latest/total.svg)](https://github.com/ChuckPa/PlexDBRepair/releases/latest)
[![Download total](https://img.shields.io/github/downloads/ChuckPa/DBRepair/total.svg)](https://github.com/ChuckPa/DBRepair/releases) [![Download total](https://img.shields.io/github/downloads/ChuckPa/PlexDBRepair/total.svg)](https://github.com/ChuckPa/PlexDBRepair/releases)
[![master](https://img.shields.io/badge/master-stable-green.svg?maxAge=2592000)]('') [![master](https://img.shields.io/badge/master-stable-green.svg?maxAge=2592000)]('')
![Maintenance](https://img.shields.io/badge/Maintained-Yes-green.svg) ![Maintenance](https://img.shields.io/badge/Maintained-Yes-green.svg)
@@ -31,12 +31,10 @@ 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. AUTO(matic) - Automatically check, repair/optimize, and reindex the databases in one step.
CHEC(k) - Check the main and blob databases integrity CHEC(k) - Check the main and blob databases integrity
DEFL(ate) - Deflate a bloated PMS database (faulty statistics data)
EXIT - Exit the utility EXIT - Exit the utility
IGNOre/HONOr - Ignore/Honor constraint errors when IMPORTing additional data into DB. IGNOre/HONOr - Ignore/Honor constraint errors when IMPORTing additional data into DB.
IMPO(rt) - Import viewstate / watch history from another database IMPO(rt) - Import viewstate / watch history from another database
PRUN(e) - Prune (remove) old image files from transcoder cache diretory PRUN(e) - Prune (remove) old image files from transcoder cache diretory
PURG(e) - Purge (delete) all temporary files left behind by PMS & the transcoder from the temp directory
REIN(dex) - Rebuild the database indexes REIN(dex) - Rebuild the database indexes
REPL(ace) - Replace the existing databases with a PMS-generated backup REPL(ace) - Replace the existing databases with a PMS-generated backup
SHOW - Show the log file SHOW - Show the log file
@@ -52,8 +50,8 @@ If sufficient privleges exist (root), and supported by the environment, the opti
For clarity, each command's name is 'quoted'. 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 Version v1.03.00
Select Select
@@ -62,7 +60,7 @@ If sufficient privleges exist (root), and supported by the environment, the opti
3 - 'check' - Perform integrity check of database. 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database without optimizing. 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases. 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database indexes. 6 - 'reindex' - Rebuild database database indexes.
7 - 'start' - Start PMS 7 - 'start' - Start PMS
8 - 'import' - Import watch history from another database independent of Plex. (risky). 8 - 'import' - Import watch history from another database independent of Plex. (risky).
@@ -72,13 +70,11 @@ If sufficient privleges exist (root), and supported by the environment, the opti
12 - 'undo' - Undo last successful command. 12 - 'undo' - Undo last successful command.
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache. 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. 42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates. 88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files. 99 - 'quit' - Quit immediately. Keep all temporary files.
99 'exit' - Exit with cleanup options. 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : Enter command # -or- command name (4 char min) :
@@ -94,24 +90,15 @@ Enter command # -or- command name (4 char min) :
- BINHEX - BINHEX
- HOTIO - HOTIO
- Podman (libgpod) - Podman (libgpod)
4. FreeBSD (14+) 4. Linux workstation & server
5. Linux workstation & server 5. MacOS
6. MacOS 6. Netgear (OS5 Linux-based systems)
7. Netgear (OS5 Linux-based systems) 7. QNAP (QTS & QuTS)
8. QNAP (QTS & QuTS) 8. Synology (DSM 6 & DSM 7)
9. Synology (DSM 6 & DSM 7) 9. Western Digital (OS5)
10. Western Digital (OS5)
``` ```
# Installation # Installation
### Downloading
Download DBRepair.sh (if you want just the script)
# This overwrites any existing version. Remove "-O DBRepair.sh" to not overwrite.
```
wget -O DBRepair.sh https://github.com/ChuckPa/PlexDBRepair/releases/latest/download/DBRepair.sh
```
### Moving the downloaded DBRepair.sh
Where to place the utility varies from host to host. Where to place the utility varies from host to host.
Please use this table as a reference. Please use this table as a reference.
@@ -123,11 +110,10 @@ Enter command # -or- command name (4 char min) :
-------------------+---------------------+------------------------------------------ -------------------+---------------------+------------------------------------------
Apple | Downloads | ~/Downloads Apple | Downloads | ~/Downloads
Arch Linux | N/A | Anywhere Arch Linux | N/A | Anywhere
ASUSTOR | Plex | /volume1/Plex ASUSTOR | Public | /volume1/Public
Binhex | N/A | Container root (adjacent /config) Binhex | N/A | Container root (adjacent /config)
Docker (Plex,LSIO) | N/A | Container root (adjacent /config) Docker (Plex,LSIO) | N/A | Container root (adjacent /config)
Hotio | 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) Kubernetes | N/A | Container root (adjacent /config)
Linux (wkstn/svr) | N/A | Anywhere Linux (wkstn/svr) | N/A | Anywhere
MacOS | N/A | Anywhere MacOS | N/A | Anywhere
@@ -140,16 +126,13 @@ Enter command # -or- command name (4 char min) :
``` ```
Plex,inc and LSIO docker images are included in "Docker" platform category independent of the actual host. Plex,inc and LSIO docker images are included in "Docker" platform category independent of the actual host.
Additional hosts and docker images can easily be supported in almost all cases with appropriate path
information. Please contact me as needed.
### General installation and usage instructions ### 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 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. -- 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. 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) 5. Open a command line session (usually Terminal or SSH)
@@ -168,8 +151,8 @@ Enter command # -or- command name (4 char min) :
cd /volume1/Plex # use /volume1/PlexMediaServer on DSM 7 cd /volume1/Plex # use /volume1/PlexMediaServer on DSM 7
sudo bash sudo bash
tar xf DBRepair-x.y.z.tar.gz tar xf PlexDBRepair-x.y.z.tar.gz
cd DBRepair-x.y.z cd PlexDBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
@@ -180,8 +163,8 @@ Enter command # -or- command name (4 char min) :
sudo docker exec -it plex /bin/bash sudo docker exec -it plex /bin/bash
# extract from downloaded version file name then cd into directory # extract from downloaded version file name then cd into directory
tar xf DBRepair-x.y.z.tar.gz tar xf PlexDBRepair-x.y.z.tar.gz
cd DBRepair-x.y.z cd PlexDBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
``` ```
@@ -189,8 +172,8 @@ Enter command # -or- command name (4 char min) :
``` ```
sudo bash sudo bash
cd /path/to/DBRepair.tar cd /path/to/DBRepair.tar
tar xf DBRepair-x.y.z.tar.gz tar xf PlexDBRepair-x.y.z.tar.gz
cd DBRepair-x.y.z cd PlexDBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh stop auto start exit ./DBRepair.sh stop auto start exit
``` ```
@@ -199,8 +182,8 @@ Enter command # -or- command name (4 char min) :
``` ```
osascript -e 'quit app "Plex Media Server"' osascript -e 'quit app "Plex Media Server"'
cd ~/Downloads cd ~/Downloads
tar xf DBRepair-x.y.z.tar.gz tar xvf PlexDBRepai PlexDBRepair-x.y.z.tar.gz
cd DBRepair-x.y.z cd PlexDBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
@@ -232,22 +215,23 @@ These examples
C. Database is malformed - No Backups C. Database is malformed - No Backups
1. (3) Check - Confirm either main or blobs database is damaged 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 3. (6) Reindex - Generate new indexes so PMS doesn't need to at startup
4. (99) Exit 4. (99) Exit
D. Database sizes excessively large/bloated when compared to amount of media indexed (item count) C. Database sizes excessively large 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. 1. (3) Check - Make certain both databases are fully intact (repair if needed)
2. (2) Auto - Perform automated check, repair, and reindex of the deflated database 2. (4) Vacuum - Instruct SQLite to rebuild its tables and recover unused space.
3. (6) Reindex - Rebuild Indexes.
4. (99) Exit 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 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. 2. (5) Repair - You are not really repairing. You are rebuilding the DB in perfect sorted order.
3. (6) Reindex - Rebuild Indexes. 3. (6) Reindex - Rebuild Indexes.
4. (99) Exit 4. (99) Exit
F. Undo E. Undo
Undo is a special case where you need the utility to backup ONE step. 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 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. than you were before. In this case, UNDO then Repair. Undo can only undo the single most-recent action.
@@ -277,29 +261,18 @@ Attention:
-- This is for when DB operations keep getting worse and you don't know what to do. -- 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. "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 "Exit" is the preferred method to leave.
"98" or "Quit" - Get out now without deleting the temp databases (Usually used only during unexpected failures)
"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. Also please be aware the script understands interactive versus scripted mode.
## Command line options
To avoid confusion and making the menu complicated, a few command line options have been added.
To use DBRepair when the container / host cannot be identified, --sqlite and --databases allow you
to specify the pathnames from whichever context (namespace) DBRepair will be running in.
--sqlite Specify the path to "Plex SQLite" (diretory or full path)
--databases Specify the path to the directory which contains the PMS databases.
Both must be used together.
When operating with these options, DBRepair will indicate it's in Manual configuration mode.
You may still use other command line commands (batch mode) or use it normally in interactive mode.
## Scripting support ## Scripting support
@@ -338,7 +311,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 Version v1.03.01
Select Select
@@ -348,7 +321,7 @@ Select
3 - 'check' - Perform integrity check of database. 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database without optimizing. 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases. 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database indexes. 6 - 'reindex' - Rebuild database database indexes.
7 - 'start' - Start PMS 7 - 'start' - Start PMS
8 - 'import' - Import watch history from another database independent of Plex. (risky). 8 - 'import' - Import watch history from another database independent of Plex. (risky).
@@ -357,14 +330,12 @@ Select
11 - 'status' - Report status of PMS (run-state and databases). 11 - 'status' - Report status of PMS (run-state and databases).
12 - 'undo' - Undo last successful command. 12 - 'undo' - Undo last successful command.
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS. 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors. 42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates. 88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files. 99 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options. 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : 1 Enter command # -or- command name (4 char min) : 1
@@ -378,7 +349,7 @@ Select
3 - 'check' - Perform integrity check of database. 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database without optimizing. 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases. 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database indexes. 6 - 'reindex' - Rebuild database database indexes.
7 - 'start' - Start PMS 7 - 'start' - Start PMS
8 - 'import' - Import watch history from another database independent of Plex. (risky). 8 - 'import' - Import watch history from another database independent of Plex. (risky).
@@ -387,14 +358,12 @@ Select
11 - 'status' - Report status of PMS (run-state and databases). 11 - 'status' - Report status of PMS (run-state and databases).
12 - 'undo' - Undo last successful command. 12 - 'undo' - Undo last successful command.
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS. 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors. 42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates. 88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files. 99 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options. 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : auto Enter command # -or- command name (4 char min) : auto
@@ -434,7 +403,7 @@ Select
3 - 'check' - Perform integrity check of database. 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database without optimizing. 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases. 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database indexes. 6 - 'reindex' - Rebuild database database indexes.
7 - 'start' - Start PMS 7 - 'start' - Start PMS
8 - 'import' - Import watch history from another database independent of Plex. (risky). 8 - 'import' - Import watch history from another database independent of Plex. (risky).
@@ -443,14 +412,12 @@ Select
11 - 'status' - Report status of PMS (run-state and databases). 11 - 'status' - Report status of PMS (run-state and databases).
12 - 'undo' - Undo last successful command. 12 - 'undo' - Undo last successful command.
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS. 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors. 42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates. 88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files. 99 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options. 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : start Enter command # -or- command name (4 char min) : start
@@ -464,7 +431,7 @@ Select
3 - 'check' - Perform integrity check of database. 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database without optimizing. 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases. 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database indexes. 6 - 'reindex' - Rebuild database database indexes.
7 - 'start' - Start PMS 7 - 'start' - Start PMS
8 - 'import' - Import watch history from another database independent of Plex. (risky). 8 - 'import' - Import watch history from another database independent of Plex. (risky).
@@ -473,14 +440,12 @@ Select
11 - 'status' - Report status of PMS (run-state and databases). 11 - 'status' - Report status of PMS (run-state and databases).
12 - 'undo' - Undo last successful command. 12 - 'undo' - Undo last successful command.
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS. 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors. 42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates. 88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files. 99 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options. 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : stat Enter command # -or- command name (4 char min) : stat
@@ -497,7 +462,7 @@ Select
3 - 'check' - Perform integrity check of database. 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database without optimizing. 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases. 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database indexes. 6 - 'reindex' - Rebuild database database indexes.
7 - 'start' - Start PMS 7 - 'start' - Start PMS
8 - 'import' - Import watch history from another database independent of Plex. (risky). 8 - 'import' - Import watch history from another database independent of Plex. (risky).
@@ -506,14 +471,12 @@ Select
11 - 'status' - Report status of PMS (run-state and databases). 11 - 'status' - Report status of PMS (run-state and databases).
12 - 'undo' - Undo last successful command. 12 - 'undo' - Undo last successful command.
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS. 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors. 42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates. 88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files. 99 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options. 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : exit Enter command # -or- command name (4 char min) : exit
@@ -531,7 +494,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 Version v1.03.01
@@ -655,13 +618,6 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases#
Checks the integrity of the Plex main and blobs 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 ### Exit
Exits the utility and removes all temporary database files created during processing. Exits the utility and removes all temporary database files created during processing.
@@ -839,77 +795,55 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases#
1. Remove the environment variable. 1. Remove the environment variable.
2. Run DBRepair again using "automatic". Your databases will revert to the host OS's default. 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 # 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) Plex Media Server Database Repair Utility (Ubuntu 22.04.3 LTS)
Version v1.12.00 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. [2024-01-14 17.25.35] Automatic Check,Repair,Index started.
[2025-10-21 16.54.00] [2024-01-14 17.25.35]
[2025-10-21 16.54.00] Checking the PMS databases [2024-01-14 17.25.35] Checking the PMS databases
[2025-10-21 16.54.19] Check complete. PMS main database is OK. [2024-01-14 17.25.48] Check complete. PMS main database is OK.
[2025-10-21 16.54.21] Check complete. PMS blobs database is OK. [2024-01-14 17.25.48] Check complete. PMS blobs database is OK.
[2025-10-21 16.54.21] [2024-01-14 17.25.48]
[2025-10-21 16.54.21] Backup current databases with '-BACKUP-2025-10-21_16.54.21' timestamp. [2024-01-14 17.25.48] Exporting current databases using timestamp: 2024-01-14_17.25.35
[2025-10-21 16.56.29] Starting Deflate (Part 1 of 2 - Repair database table) [2024-01-14 17.25.48] Exporting Main DB
[2025-10-21 16.56.29] Estimated completion is approx 6 minutes but is CPU & I/O speed dependent [2024-01-14 17.25.59] Exporting Blobs DB
[2025-10-21 16.56.29] [2024-01-14 17.26.00] Successfully exported the main and blobs databases. Proceeding to import into new databases.
[2025-10-21 16.56.30] PMS main database successfully repaired. [2024-01-14 17.26.00] Importing Main DB.
[2025-10-21 16.56.30] Starting Deflate (Part 2 of 2 - Reduce size) [2024-01-14 17.26.00] Setting Plex SQLite page size (65536)
[2025-10-21 16.56.35] PMS main database size reduced. [2024-01-14 17.26.29] Importing Blobs DB.
[2025-10-21 16.56.35] Verifying PMS main database. [2024-01-14 17.26.29] Setting Plex SQLite page size (65536)
[2025-10-21 16.56.50] Verification complete. PMS main database is OK. [2024-01-14 17.26.30] Successfully imported databases.
[2025-10-21 16.56.50] PMS main database reduced from 31586 MB to 206 MB [2024-01-14 17.26.30] Verifying databases integrity after importing.
[2025-10-21 16.56.51] Saving current main database with '-BLOATED-2025-10-21_16.54.21' [2024-01-14 17.27.43] Verification complete. PMS main database is OK.
[2025-10-21 16.56.51] Making deflated database active [2024-01-14 17.27.43] Verification complete. PMS blobs database is OK.
[2025-10-21 16.56.51] PMS main database deflate completed. [2024-01-14 17.27.43] Saving current databases with '-BACKUP-2024-01-14_17.25.35'
[2025-10-21 16.56.51] Deflate successful. [2024-01-14 17.27.43] Making repaired databases active
[2025-10-21 16.56.51] Recommend running Auto next to complete optimization of new database. [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. [2024-01-14 17.28.08] Starting PMS.
[2025-10-21 16.56.51] [2024-01-14 17.28.08] Started PMS
[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
# #
``` ```
@@ -959,8 +893,8 @@ 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 Version v1.06.00
PlexSQLite = '/var/lib/docker/btrfs/subvolumes/4bb78fb70589d4d2ba56754f4d6bc0edd4cdaa8eab7986943767e09a66cefd19/usr/lib/plexmediaserver//Plex SQLite' PlexSQLite = '/var/lib/docker/btrfs/subvolumes/4bb78fb70589d4d2ba56754f4d6bc0edd4cdaa8eab7986943767e09a66cefd19/usr/lib/plexmediaserver//Plex SQLite'
Databases = '/mnt/user/appdata/PlexMediaServer/Library/Application Support/Plex Media Server/Plug-in Support/Databases/' Databases = '/mnt/user/appdata/PlexMediaServer/Library/Application Support/Plex Media Server/Plug-in Support/Databases/'
@@ -972,7 +906,7 @@ Select
3 - 'check' - Perform integrity check of database. 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database without optimizing. 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases. 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database indexes. 6 - 'reindex' - Rebuild database database indexes.
7 - 'start' - (Not available. Start manually) 7 - 'start' - (Not available. Start manually)
8 - 'import' - Import watch history from another database independent of Plex. (risky). 8 - 'import' - Import watch history from another database independent of Plex. (risky).
@@ -981,16 +915,12 @@ Select
11 - 'status' - Report status of PMS (run-state and databases). 11 - 'status' - Report status of PMS (run-state and databases).
12 - 'undo' - Undo last successful command. 12 - 'undo' - Undo last successful command.
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache older than specific age. 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
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. 42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates. 88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files. 99 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options. 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : Enter command # -or- command name (4 char min) :
``` ```
@@ -1019,11 +949,11 @@ Enter command # -or- command name (4 char min) :
# This script grants the given syno username (your username) # This script grants the given syno username (your username)
# the ability to elevate to 'root' privilege for use with DBRepair.sh # the ability to elevate to 'root' privilege for use with DBRepair.sh
# #
# Set your desired Syno username here (no spaces in the username) # Set your desired Syno username here (no spaces)
MyUsername="chuck" MyUsername=chuck
# Confirm username exists # Confirm username exists
if [ "$(id "$MyUsername")" = "" ]; then if [ "$(id $MyUsername)" = "" ]; then
echo ERROR: No such user \'$MyUsername\' echo ERROR: No such user \'$MyUsername\'
exit 1 exit 1
fi fi
@@ -1059,4 +989,34 @@ sudo ./DBRepair.sh stop auto start exit
# Special Considerations - Windows # Special Considerations - Windows
Windows support is available via DBRepair-Windows.ps1 and DBRepair-Windows.bat. See [README-Windows](Windows/README-Windows.md) for details. Windows development is currently not on-par with DBRepair.sh, with only a limited number
of commands available. Additionally, the script (DBRepair-Windows.ps1) might fail to run
if your machine's ExecutionPolicy blocks execution of PowerShell scripts, which is the
default. There are several ways to potentially get around this:
1. From an administrator PowerShell prompt, run `Set-ExecutionPolicy RemoteSigned`, then
run the script from a normal PowerShell prompt.
2. Explicitly set the `ExecutionPolicy` when running the script, e.g.:
```powershell
powershell -ExecutionPolicy Bypass ".\DBRepair-Windows.ps1 stop auto start"
```
Note that this method may not work if your machine is managed with Group Policy, which
can block manual `ExecutionPolicy` overrides.
3. Similar to 2, but make it a batch script (e.g. `DBRepair.bat`) that lives alongside
the powershell script:
```batch
@echo off
powershell -ExecutionPolicy Bypass -Command ".\DBRepair-Windows.ps1 %*"
```
Then run that script directly:
```batch
.\DBRepair.bat stop auto start
```
Also note that the PowerShell script cannot be run directly from a Command Prompt window.
If you are running this from Command Prompt, you must launch it via PowerShell:
```cmd
powershell .\DBRepair-Windows.ps1 [args]
```

View File

@@ -1,125 +1,14 @@
# DBRepair # PlexDBRepair
[![GitHub issues](https://img.shields.io/github/issues/ChuckPa/DBRepair.svg?style=flat)](https://github.com/ChuckPa/DBRepair/issues) [![GitHub issues](https://img.shields.io/github/issues/ChuckPa/PlexDBRepair.svg?style=flat)](https://github.com/ChuckPa/PlexDBRepair/issues)
[![Release](https://img.shields.io/github/release/ChuckPa/DBRepair.svg?style=flat)](https://github.com/ChuckPa/DBRepair/releases/latest) [![Release](https://img.shields.io/github/release/ChuckPa/PlexDBRepair.svg?style=flat)](https://github.com/ChuckPa/PlexDBRepair/releases/latest)
[![Download latest release](https://img.shields.io/github/downloads/ChuckPa/DBRepair/latest/total.svg)](https://github.com/ChuckPa/DBRepair/releases/latest) [![Download latest release](https://img.shields.io/github/downloads/ChuckPa/PlexDBRepair/latest/total.svg)](https://github.com/ChuckPa/PlexDBRepair/releases/latest)
[![Download total](https://img.shields.io/github/downloads/ChuckPa/DBRepair/total.svg)](https://github.com/ChuckPa/DBRepair/releases) [![Download total](https://img.shields.io/github/downloads/ChuckPa/PlexDBRepair/total.svg)](https://github.com/ChuckPa/PlexDBRepair/releases)
[![master](https://img.shields.io/badge/master-stable-green.svg?maxAge=2592000)]('') [![master](https://img.shields.io/badge/master-stable-green.svg?maxAge=2592000)]('')
![Maintenance](https://img.shields.io/badge/Maintained-Yes-green.svg) ![Maintenance](https://img.shields.io/badge/Maintained-Yes-green.svg)
# Release Info: # Release Info:
v1.13.02
1. Autoincrement - Adjust statistics_bandwidth table per Plex engineering suggestion.
v1.13.01
1. Tag sort order - Github tags are not guaranteed to be numeric or in most-recent order.
This update sorts version tags numerically and in reverse order to accommodate github shortcoming.
v1.13.00
1. Binhex containers - Add support for updated 'supervisord' start/stop control.
Maintain support for legacy 'supervisor' start/stop control.
This will be removed in the next release
Update your container before updating DBRepair.
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)
v1.10.02
1. Refactor UPDATE - QNAP BusyBox no longer support POSIX grep. Refactored.
v1.10.01
1. Minor cleanup - Cleanup purge/prune handling after merging commands into one.
v1.10.00
1. Refactor REPLACE - Processing of DB Replace was awkward.
List of available databases will now be printed in a menu
After selecting the desired DB, the candidate will be checked.
(Selection may be by list item # or date printed)
If valid (DB and Blobs) replacement will proceed normally.
v1.09.00
1. Purge command - Add 'purge' command to clean up all temporary transcoder and image files.
(usually found in /tmp)
v1.08.00
1. Linuxserver.io - Add support for new start/stop path.
Silently support both previous and new path start/stop mechanisms.
v1.07.00
1. Mac start/stop - DBRepair now supports start/stop from the menu.
Default configuration is for MacOS to tell you what it's doing (Haptic). Set to 0 for silence.
2. Code cleanup - Minor code cleanup / dead code removal.
v1.06.02 v1.06.02
1. Bug fix - Fixed incorrect error handling when command line arguments not valid in manual configuration mode. 1. Bug fix - Fixed incorrect error handling when command line arguments not valid in manual configuration mode.
Fixed incorrect reporting of what was wrong in manual configuration mode. Fixed incorrect reporting of what was wrong in manual configuration mode.
@@ -335,7 +224,7 @@ These type changes can only be performed by PMS.
For clarity, each command's name is 'quoted'. 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 Version v1.0.0
Select Select
@@ -400,10 +289,10 @@ These type changes can only be performed by PMS.
### General installation and usage instructions ### 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 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. -- 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. 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) 5. Open a command line session (usually Terminal or SSH)
@@ -420,8 +309,8 @@ These type changes can only be performed by PMS.
cd /volume1/Plex cd /volume1/Plex
sudo bash sudo bash
tar xf DBRepair-x.y.z.tar.gz tar xf PlexDBRepair-x.y.z.tar.gz
cd DBRepair-x.y.z cd PlexDBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
@@ -433,8 +322,8 @@ These type changes can only be performed by PMS.
sudo docker exec -it plex /bin/bash sudo docker exec -it plex /bin/bash
# extract from downloaded version file name then cd into directory # extract from downloaded version file name then cd into directory
tar xf DBRepair-1.0.0.tar.gz tar xf PlexDBRepair-1.0.0.tar.gz
cd DBRepair-1.0.0 cd PlexDBRepair-1.0.0
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
``` ```
@@ -442,8 +331,8 @@ These type changes can only be performed by PMS.
``` ```
sudo bash sudo bash
cd /path/to/DBRepair.tar cd /path/to/DBRepair.tar
tar xf DBRepair-1.0.0.tar.gz tar xf PlexDBRepair-1.0.0.tar.gz
cd DBRepair-1.0.0 cd PlexDBRepair-1.0.0
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh stop auto start exit ./DBRepair.sh stop auto start exit
``` ```
@@ -452,8 +341,8 @@ These type changes can only be performed by PMS.
``` ```
osascript -e 'quit app "Plex Media Server"' osascript -e 'quit app "Plex Media Server"'
cd ~/Downloads cd ~/Downloads
tar xvf PlexDBRepai DBRepair-1.0.0.tar.gz tar xvf PlexDBRepai PlexDBRepair-1.0.0.tar.gz
cd PlexDBRepai DBRepair-1.0.0 cd PlexDBRepai PlexDBRepair-1.0.0
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
@@ -558,7 +447,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 Version v1.0.0
@@ -711,7 +600,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 Version v1.0.0
@@ -905,4 +794,4 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases#
Instructs SQLite to remove the empty/deleted records and gaps from the databases. Instructs SQLite to remove the empty/deleted records and gaps from the databases.
This is most beneficial after deleting whole library sections. This is most beneficial after deleting whole library sections.
### ###

Binary file not shown.

View File

@@ -1,76 +0,0 @@
# DBRepair-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
[Plex data directory](https://support.plex.tv/articles/202915258-where-is-the-plex-media-server-data-directory-located/).
## DBRepair-Windows.ps1 vs. DBRepair-Windows.bat
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
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.
## Functions provided
The Windows utility aims to provide a similar interface to DBRepair.sh as outlined in the main
[README file](README.md), but currently only offers a subset of its functionality. For a full
description of the features below, consult that main README file.
The following commands (or their number) are currently supported on Windows.
```
AUTO(matic)
EXIT
PRUN(e)
STAR(t)
STOP
```
Run `.\DBRepair-Windows.ps1 -Help` for more complete documentation.
# Installation and usage instructions
DBRepair-Windows can be downloaded to any location. However, the PowerShell script might require
some prerequisite work in order to run as expected. By default, PowerShell scripts are blocked on
Windows machines, so in order to run DBRepair-Windows.ps1, you may need to do one of the following:
1. From an administrator PowerShell prompt, run `Set-ExecutionPolicy RemoteSigned`, then run the
script from a normal PowerShell prompt. If PowerShell still will not run the script, you can do
one of the following:
* In Windows Explorer, right-click DBRepair-Windows.ps1, select Properties, and check 'Unblock'
at the bottom of the dialog.
* In PowerShell, run `Unblock-File <path\to\DBRepair-Windows.ps1>`
* Run `Set-ExecutionPolicy Unrestricted` - this may result in an "are you sure" prompt before
running the script. `Set-ExecutionPolicy Bypass` will get around this, but is not recommended,
as it allows _any_ downloaded script to run without notification, not just DBRepair.
2. Explicitly set the `ExecutionPolicy` when running the script, e.g.:
```powershell
powershell -ExecutionPolicy Bypass ".\DBRepair-Windows.ps1 stop auto start"
```
Note that this method may not work if your machine is managed with Group Policy, which
can block manual `ExecutionPolicy` overrides.
3. Similar to 2, but make it a batch script (e.g. `DBRepair.bat`) that lives alongside
the powershell script:
```batch
@echo off
powershell -ExecutionPolicy Bypass -Command ".\DBRepair-Windows.ps1 %*"
```
Then run that script directly:
```batch
.\DBRepair.bat stop auto start
```
Also note that the PowerShell script cannot be run directly from a Command Prompt window.
If you are running this from Command Prompt, you must launch it via PowerShell:
```cmd
powershell .\DBRepair-Windows.ps1 [args]
```

View File

@@ -1,33 +0,0 @@
# DBRepair-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.
v1.00.00
- Initial Windows PowerShell script release, aiming to provide a similar experience as DBRepair.sh, with command-name-based input.
- Initial command support:
- AUTO(matic)
- EXIT
- PRUN(e)
- STAR(t)
- STOP