139 Commits

Author SHA1 Message Date
Chuck
d6bf75db6d Merge pull request #261 from ChuckPa/chuckpa/autoincrement
Deflate - Minor adjustment per Plex engineering.
2025-12-04 12:06:08 -05:00
ChuckPa
0701adf77a Deflate - Minor adjustment per Plex engineering. 2025-12-04 11:56:48 -05:00
Chuck
15b2dbabb3 Update README.md 2025-12-03 16:19:35 -05:00
Chuck
cbd02cc6b6 Merge pull request #259 from ChuckPa/chuckpa/fix-tag-sorting
Fix github tag sorting.   Ensure tags are both Numeric and Reverse sorted so newest version number listed first.
2025-11-14 19:42:45 -05:00
ChuckPa
43d636b371 Add Numeric sorting to tag retrieval
Ensures highest version number is first listed
2025-11-14 19:40:17 -05:00
Chuck
85c88a59f3 Merge pull request #256 from ChuckPa/chuckpa/binhex-multi-config
Binhex:  supervisord.conf update
2025-11-09 16:12:46 -05:00
ChuckPa
f2060a0ede Binhex: supervisord.conf update
.
2025-11-09 16:04:26 -05:00
Chuck
abc552fb12 Merge pull request #253 from ChuckPa/chuckpa/readme
Minor Update & Correct documentation for v1.12.00
2025-10-21 17:33:14 -04:00
ChuckPa
aa76cbfefd Update & Correct documentation for v1.12 2025-10-21 17:26:46 -04:00
Chuck
d79b5e2b9d Merge pull request #252 from ChuckPa/chuckpa/dodeflate
v1.12.00 - Add  Deflate command

Reconstruct bandwidth statistics table  row  by row instead of previous bulk copy of non-null values
Regenerate new IDs during reconstruction for new indexes and reindex
2025-10-20 22:28:24 -04:00
ChuckPa
3bfb510ef7 Documentation correction
ASUSTOR - Incorrect location
2025-10-20 22:12:45 -04:00
ChuckPa
247338278b Add Deflate command
Deflate
- Create new bandwidth_statistics table with proper schema.
- Transfer only valid data from existing bandwidth statistics into new.
- Drop old table.
- Vacuum into new database.
Merge Prune & Purge as one proper command
Update ASUSTOR documentation error.

Finalize Deflate integration & reporting.

Update Release Notes
2025-10-20 19:23:22 -04:00
Chuck
dea8a805ce Merge pull request #239 from ChuckPa/chuckpa/Hotio-Cache-Dir
HotIO -  Path to Cache dir incorrect
2025-07-31 20:20:46 -04:00
ChuckPa
6d8bafbf99 HotIO - Path to Cache dir incorrect
Fixes path (working around silly symlink)
2025-07-31 20:18:21 -04:00
Chuck
e2acd24593 Merge pull request #232 from ChuckPa/chuckpa/restart-path
Correct path issue with restart
2025-07-07 20:23:33 -04:00
ChuckPa
24b746db1b Correct path issue with restart 2025-07-06 19:29:25 -04:00
Chuck
32d5f8f737 Merge pull request #228 from ChuckPa/chuckpa/Freebsd-releases
Add support for FreeBSD (14+)
2025-06-26 00:03:35 -04:00
ChuckPa
06c0f810dd Add support for FreeBSD (14+)
Thanks @cdf-eagles
2025-06-25 20:39:07 -04:00
Chuck
ac6058dd48 Merge pull request #226 from cdf-eagles/fix-freebsd-startstop
Fixed bug for FreeBSD Plex service start/stop commands
2025-06-25 18:37:55 -04:00
Christopher Fernando
019fd197f8 Fixed bug for FreeBSD Plex service start/stop commands 2025-06-25 14:07:00 -05:00
Chuck
ebf170b1eb Merge pull request #225 from cdf-eagles/freebsd-compat
FreeBSD 14+ Compatibility Added.
2025-06-25 12:07:54 -04:00
Christopher Fernando
38cd4ded5c FreeBSD 14+ Compatibility Added.
See closed PR "Freebsd compat #224" for discussion.
Updated version.
Uses FreeBSD Ports (pkg command) to determine which plexmediaserver package is installed and sets paths.
2025-06-25 10:58:43 -05:00
Chuck
44f722166d Merge pull request #222 from ChuckPa/chuckpa/unitialized
Correct missing variable initialization
2025-06-22 16:06:59 -04:00
ChuckPa
2264ee89be Correct missing variable initialization
Restart after update had missing default value.
2025-06-22 16:03:17 -04:00
Chuck
93886de20f Merge pull request #215 from danrahn/master
Add 98=quit/99=exit to PowerShell script
2025-06-05 21:59:42 -04:00
danrahn
a3ba41b668 Copy DBRepair.sh's new 98=quit and 99=exit
Also remove the temporary deflate code and other minor refactoring.
2025-06-05 18:44:54 -07:00
Chuck
f96032e9c4 Merge pull request #218 from ChuckPa/chuckpa/menu
v1.11.05 - Cleanup menu

Thanks @kimpenhaus
2025-06-05 13:38:43 -04:00
ChuckPa
ea78ea663e v1.11.05 - Cleanup menu 2025-06-05 13:30:24 -04:00
Chuck
f2a821c170 Merge pull request #216 from ChuckPa/chuckpa/relauch
v1.11.04

1.  Add Binhex start/stop support
2.  Correct 98/99 menu options
3.  Remove Deflate
2025-06-04 10:14:05 -04:00
ChuckPa
baf8398085 v1.11.04
1.  Add  Start/Stop support for Binhex containers
1.  Restart after update (optional)
2.  Remove DEFLATE (PMS 1.41.8)
2025-06-03 12:39:29 -04:00
Chuck
65f4e5d33d 911 - Deflate 2025-05-31 23:12:59 -04:00
Chuck
4872b82815 Merge pull request #211 from ChuckPa/chuckpa/add-log
v1.11.03 -Add summary logfile messages
2025-05-30 23:25:49 -04:00
ChuckPa
859f2bdbe1 Add Log entries to Deflate 2025-05-30 23:25:04 -04:00
Chuck
0e1797a4c0 Merge pull request #210 from ChuckPa/chuckpa/add-log
v1.11.03 -Add summary logfile messages
2025-05-30 23:21:38 -04:00
ChuckPa
cf54baa5c4 v1.11.03 -Add summary logfile messages
v1.11.03
1.  Add DEFLATE command to provide fast database cleanup while Plex engineering fixes the root problems.
2.  Handle Databases not on same storage as AppSuppDir
3.  Calculate SpaceNeeded based on $DBDIR
4.  Fix menu items
5.  Fix reporting of SpaceNeeded when unable to process.
6.  Add summary logging for DEFLATE actions in case disk full.
2025-05-30 23:19:34 -04:00
Chuck
b431e49455 Merge pull request #208 from ChuckPa/chuckpa/plex-bloat
Provide temporary DB bloat deflate capability for huge databases.

Documentation in the Release Notes
2025-05-30 19:31:42 -04:00
ChuckPa
c5c1f7b683 v1.11.02
1.  Handle Databases not on same storage as AppSuppDir
2.  Calculate SpaceNeeded based on $DBDIR
3.  Fix menu items

4.  Fix reporting of SpaceNeeded when unable to process.

v1.11.02

Add DEFLATE command to provide fast database cleanup while Plex engineering fixes the root problems.
2025-05-30 19:22:34 -04:00
Chuck
8c5f7606a7 Merge pull request #202 from danrahn/master
Add statistics_bandwidth Cleanup to Windows Scripts
2025-05-24 19:17:45 -04:00
danrahn
3bb22f56cd Bump version 2025-05-24 14:34:44 -07:00
danrahn
481814ed2c Add statistics_bandwidth cleanup to Windows scripts 2025-05-24 10:34:41 -07:00
Chuck
d6f4dbf263 Merge pull request #201 from danrahn/master
Update Windows scripts to reflect name change
2025-05-24 10:39:30 -04:00
danrahn
1c5c4b6fbc Update Windows scripts to reflect name change 2025-05-23 19:51:46 -07:00
ChuckPa
98c5274d86 Update Repo name URL and reissue 2025-05-23 21:17:40 -04:00
ChuckPa
1c1ed5a8c1 Comply with Plex, inc. Trademark Policy
Comply with Plex,inc. Trademark Policy
2025-05-23 19:55:51 -04:00
Chuck
be74c6f85e Merge pull request #199 from ChuckPa/chuckpa/final-tags
Refactor version tags
2025-05-23 01:37:15 -04:00
ChuckPa
865da1cd3c Refactor version tags 2025-05-23 01:36:00 -04:00
Chuck
ca489c6c3f Merge pull request #198 from ChuckPa/chuckpa/final-tags
Refactor version tags
2025-05-23 01:30:10 -04:00
ChuckPa
75481e41d3 Refactor version tags 2025-05-23 01:26:33 -04:00
Chuck
3262ec7f7a Cleanup update tag handling. Inform users of DB cleanup tasks.
Correct version tag handling (remove junk)
2025-05-22 19:40:14 -04:00
ChuckPa
8aed201782 Correct version tag handling (remove junk)
Users would see multiple versions' tag info.  This is undesirable.
2025-05-22 19:38:05 -04:00
Chuck
21196a3cc3 Merge pull request #196 from ChuckPa/chuckpa/may-cleanup
v1.10.05
2025-05-20 20:26:59 -04:00
ChuckPa
a34511a219 May 2025 cleanup
Minor DB Cleanup extras.
2025-05-20 20:19:14 -04:00
Chuck
e2a3d1d04b Merge pull request #194 from danrahn/master
[Windows] Check PMS state in more places
2025-04-30 20:06:45 -04:00
danrahn
82f1575293 [Windows] Check PMS state in more places
While it probably won't address #184 since the batch script works without issue,
but I was unable to replicate this on my system, so this is at least an
intermediate step. Also do some refactoring around the export process, and don't
remove temp files in scripted mode if the last operation failed.
2025-04-26 10:53:17 -07:00
Chuck
19b9b5bf6f Update README.md 2025-04-01 19:16:46 -04:00
Chuck
dfebe80fa9 Merge pull request #191 from ChuckPa/chuckpa/handle-null-LC_ALL
Set LC_ALL=C when null
2025-03-18 21:54:25 -04:00
ChuckPa
2fcd006ed4 Set LC_ALL=C when null
MacOS fails regular expressions when null (as of Sequoia)
2025-03-18 21:44:11 -04:00
Chuck
d505486e95 Merge pull request #188 from danrahn/capture_constraint_errors
[Windows] Add Honor/Ignore options and ensure all import errors are captured
2025-02-24 01:59:26 -05:00
danrahn
ed72348a76 [Windows] Ensure all import errors are captured 2025-02-23 15:20:10 -08:00
Chuck
eae8c5a6da Merge pull request #186 from setoy/master
Changed Write-Warn to be Write-Warning
2025-02-06 01:54:54 -05:00
setoy
4df5421699 Changed Write-Warn to be Write-Warning 2025-02-05 14:12:37 +01:00
Chuck
738dc8d7a0 Merge pull request #182 from ChuckPa/chuckpa/fix-busybox-posix
Change 'Update' to use non-POSIX techniques
2025-01-03 19:07:02 -05:00
ChuckPa
48f7ff7f36 Change Update to use non-POSIX techniques
QNAP BusyBox 'grep' no longer supports POSIX.
Refactor to alternative method
2025-01-03 19:03:01 -05:00
Chuck
804c9014d1 Merge pull request #180 from ChuckPa/chuckpa/cleanup-purge
Minor cleanup from 1.10 release
2025-01-02 18:33:37 -05:00
ChuckPa
984b4ff861 Minor cleanup from 1.10 release 2025-01-02 15:13:16 -05:00
Chuck
6aff3e4231 Update README.md 2024-12-31 00:52:35 -05:00
Chuck
46c4b1ddcc Update README.md 2024-12-30 11:54:16 -05:00
Chuck
1737631454 Merge pull request #178 from ChuckPa/chuckpa/Add-Purge
add purge
2024-12-29 00:57:57 -05:00
ChuckPa
fe6c8d3ab6 Add Prune
Delete all images and temporary transcoder files/dirs in "/tmp".
2024-11-14 16:44:00 -05:00
ChuckPa
f11d8de6be Fix: Forgot 'fi' on line 664 2024-09-04 20:02:20 -04:00
ChuckPa
f4b987900a LSIO Start/Stop - updated path support
LSIO has multiple svc-plex pathnames.
This change adds support for /run/service/svc-plex.
2024-08-28 14:40:11 -04:00
ChuckPa
16d1807705 Update README.md 2024-07-21 20:53:43 -04:00
Chuck
c74c6c601c Update README.md 2024-06-24 17:37:53 -04:00
Chuck
013f55bd96 Update README.md 2024-06-24 17:35:54 -04:00
Chuck
79f0153a96 Update README.md
Remove duplicate in 'databases databases' descriptive clauses.
2024-06-24 17:33:37 -04:00
Chuck
c0000079d7 Merge pull request #164 from markhoney/patch-1
Update DBRepair.sh, fix typo
2024-06-24 17:29:42 -04:00
Mark Honeychurch
f869520ef8 Update DBRepair.sh, fix typo
Removed duplicated "database" in instructions
2024-06-23 21:46:38 +12:00
ChuckPa
91562060d1 v1.07.00
1.  Add MacOS start/stop functionality from menu.
2.  Cleanup & dead code removal
2024-06-14 13:20:37 -04:00
Chuck
4f5b5abdc8 Merge pull request #161 from 2bits/master
Support Mac Start Stop
2024-06-14 13:08:09 -04:00
2bits
b029ccebbb Support Mac Start Stop
Use osascript to Start and Stop PMS on Apple Mac.
2024-06-13 19:49:13 -07:00
Chuck
9c1008cf52 Merge pull request #158 from danrahn/master
[Windows] Ensure PowerShell uses UTF-8 Encoding
2024-06-02 18:29:19 -04:00
danrahn
630d5b3b6e [Windows] Ensure PowerShell uses UTF-8 Encoding 2024-06-02 11:44:20 -07:00
ChuckPa
1a75cc9ede Initial Test Release - v1.00.00 of Windows suite 2024-05-12 10:13:22 -04:00
Chuck
f2ec7d2ea9 Merge pull request #154 from danrahn/master
Interactive Windows Script via PowerShell
2024-05-12 10:07:42 -04:00
danrahn
361889230d Adjust Windows version 2024-05-11 20:13:56 -07:00
danrahn
f3175713a9 Add Windows README and ReleaseNotes
Also fix Help command that broke after some last-minute refactoring, and tweak
interactive EOF handling.
2024-05-11 20:10:18 -07:00
danrahn
c9a9a1eb81 Move everything to PowerShell on Windows
Port existing batch script behavior over to PowerShell, and switch over to a
command-based pattern like DBRepair.sh - that is, allow the user to pass in a
list of commands to be run automatically, or, if no commands are provided,
interactively allow the user to choose what to do.
2024-05-11 15:24:35 -07:00
Chuck
ec9edaf304 Merge pull request #152 from ChuckPa/chuckpa/plexsqlite-dir-path
v1.06.02
2024-05-11 03:43:05 -04:00
Chuck
2e92ba88de Update README.md 2024-05-11 03:30:10 -04:00
Chuck
57055172e0 Update README.md 2024-05-11 03:29:42 -04:00
ChuckPa
029020ebc5 v1.06.02 bug fix
Manual configuration mode error handling and reporting.
2024-05-11 02:37:37 -04:00
Chuck
93c7b0fbe2 Update README.md 2024-05-10 21:31:39 -04:00
ChuckPa
32c30e6826 v1.06.01 - Support directory or full path with '--sqlite' option. 2024-05-10 18:04:12 -04:00
ChuckPa
907f233a06 Manual Configuration: How to use with Docker 2024-05-10 13:30:16 -04:00
ChuckPa
d0084c96fb Manual config support
See Release notes about --sqlite and --databases options.
2024-05-05 01:22:32 -04:00
Chuck
ec7e04dc35 Merge pull request #147 from ChuckPa/chuckpa/manual-config
Allow running DBRepair in non-standard/unknown locations
2024-05-05 00:58:00 -04:00
ChuckPa
1a3228e648 Windows: Make path discovery better
DBRepair (Win)  now understands mixed mode (32 bit on 64 bit OS)
2024-05-05 00:51:52 -04:00
ChuckPa
852fdfc0d5 Manual mode - Initial commit 2024-05-01 02:02:32 -04:00
ChuckPa
ee8556d0f9 Update README.md 2024-04-23 22:04:52 -04:00
ChuckPa
d8d2283c01 HOTIO path locator fixes
Contributed path changes for HOTIO
Version bump
2024-03-26 14:42:33 -04:00
Chuck
43ba32afa4 Merge pull request #139 from causefx/patch-3
fix: add new path for update hotio image
2024-03-13 06:59:49 -07:00
causefx
4d880bf788 fix: add new path for update hotio image 2024-03-11 16:18:55 -07:00
Chuck
d98dfa68bf Merge pull request #138 from ChuckPa/chuckpa/macos-cache-dir
Change Transcoder Cache dir to variable.
2024-03-07 21:43:22 -08:00
ChuckPa
c8162a487f Change Transcoder Cache dir to variable.
Structure differences on MacOS.
Update documentation
2024-03-08 00:35:02 -05:00
Chuck
89ea800bdb Update README.md
Clarify grouping of Plex,inc and LSIO images as "Docker" platform.

Hosts using these,  such as Unraid, are identified as "Docker".
2024-02-10 14:51:04 -05:00
Chuck
3ef48d099a Merge pull request #129 from ChuckPa/chuckpa/add-kubernetes-support
Add Kubernetes (and TrueNAS) container support
2024-02-09 15:25:20 -08:00
ChuckPa
26a8bf3e49 Add Kubernetes (and TrueNAS) container support 2024-02-09 01:54:49 -05:00
Chuck
1ea8b86aea Merge pull request #126 from ChuckPa/chuckpa/add-snap
v1.04.00 -  Add SNAP support
2024-01-30 17:01:13 -08:00
ChuckPa
d96f091823 v1.04.00 - Add SNAP support
Adds support for SNAP packaging  (/snap, /var/snap)
2024-01-30 19:57:29 -05:00
Chuck
e02e5bc398 Merge pull request #124 from ChuckPa/chuckpa/pagesize-constraint-check
Correct case where PAGESIZE != 2^n where n={10,11,12,13,14,15,16}
2024-01-17 18:25:53 -08:00
ChuckPa
6ebb342973 Correct case where PAGESIZE != 2^n where n={10,11,12,13,14,15,16}
1.  Correct PAGESIZE allowed values
2.  Improved performance of prune
3.  Cosmetic output cleanup
4.  Improve error messaging and handling
5.  Update documentation
2024-01-17 21:15:56 -05:00
Chuck
a489a7f9e6 Merge pull request #123 from ChuckPa/chuckpa/add-cache-cleaning
Add 'purge' & Environment variable support.
2024-01-16 21:49:11 -08:00
ChuckPa
2a8a8e242b Add 'purge' & Environment variable support.
PlexDBRepair - release v01.03.00

1.  Purge command  ('piurge') - Remove old image files from Transcode cache
2.  Environment variables support to tailor operation
    - DBREPAIR_CACHEAGE -  Set max age of files to retain
    - DBREPAIR_PAGESIZE    -  Set Plex SQLite database page_size
2024-01-17 00:33:07 -05:00
ChuckPa
8863beeab2 Update Release Notes & README.md
Logging - Add missing logging record when making active
One logging record was missing.

Add DSM 7 Task Scheduler usage documentation
2024-01-12 16:47:57 -05:00
Chuck
d6d6c47928 Merge pull request #116 from ChuckPa/chuckpa/ignore-option-control
New:  Add menu option to ignore/honor duplicates / constraint errors
2023-11-25 21:50:09 -08:00
ChuckPa
38749aef78 New: Add menu option to ignore/honor duplicates / constraint errors
update code.
bump to version 1.02.00 (new feature)
update release notes.
update readme
2023-11-26 00:43:39 -05:00
Chuck
6c7157cb5f Merge pull request #114 from ChuckPa/chuckpa/missing-ignore-errors-check
Fix unable to repair DB when UNIQUE constraint errors occur
2023-11-25 16:51:54 -08:00
ChuckPa
fa760e3ddf Update version to 1.01.04 after patch
update version to 1.01.04 after patch
2023-11-25 19:39:05 -05:00
ChuckPa
80fb3a751c Fix unable to repair DB when UNIQUE constraint errors occur
Not all DBs were repairable.  This fix addresses UNIQUE constraint failures.
2023-11-25 19:36:57 -05:00
Chuck
00bb897a92 Merge pull request #113 from ChuckPa/chuckpa/missing-ignore-errors-check
Fix unable to repair DB when UNIQUE constraint errors occur
2023-11-25 16:27:44 -08:00
ChuckPa
fcf132f9e1 Fix unable to repair DB when UNIQUE constraint errors occur
Not all DBs were repairable.  This fix addresses UNIQUE constraint failures.
2023-11-25 19:25:21 -05:00
ChuckPa
4f21080862 Update DBRepair-Windows.zip after fixing Path discovery 2023-11-11 15:02:06 -05:00
Chuck
66ad17da60 Merge pull request #110 from ChuckPa/chuckpa/cleanup-version
Cleanup version output
2023-11-10 12:47:09 -08:00
ChuckPa
4dcb686ab1 Cleanup version output
Update Release Notes
2023-11-10 15:40:26 -05:00
Chuck
c5a4a88f82 Merge pull request #109 from ChuckPa/chuckp/rewrite-update
Correct confirmation when not scripted.
2023-11-10 12:17:40 -08:00
ChuckPa
f6008d76b7 Correct confirmation when not scripted.
Fixes:  https://github.com/ChuckPa/PlexDBRepair/issues/108
2023-11-10 15:13:43 -05:00
ChuckPa
ee335a69a5 Update ReleaseNotes
Release notes
2023-10-16 20:32:51 -04:00
Chuck
2958fb5c26 Merge pull request #105 from ChuckPa/chuckpa/UpdateDBRepair
v1.01.00 -  Add self-update capability
2023-10-16 16:42:04 -07:00
ChuckPa
8cbbc2b0b2 v1.01.00 - Add self-update capability
And update documentation
2023-10-16 19:16:48 -04:00
Chuck
2d7e46dd6d Merge pull request #102 from causefx/causefx-patch-update-feature
Add update feature to DBRepair.sh
2023-10-13 18:45:46 -07:00
causefx
db1edd13a4 Add update feature to script 2023-10-13 08:35:32 -07:00
Chuck
47bd6e7c56 Merge pull request #101 from psitem/master
Plex path discovery on Windows
2023-10-08 14:11:36 -07:00
psitem
beeaa88315 Plex path discovery
Discover Plex paths.
Correct mkdir statement to md.
2023-10-08 09:37:17 -04:00
ChuckPa
4d8fa8058c Update version and generate new release 2023-09-23 14:44:32 -04:00
Chuck
2c863f41a1 Merge pull request #96 from causefx/patch-1
Fix HOTIO with backwards compatibility
2023-09-23 11:24:09 -07:00
causefx
8924a304d1 fix first if statement 2023-09-18 20:37:07 -07:00
causefx
94abffcb86 Update DBRepair.sh 2023-09-17 17:50:23 -07:00
Chuck
36288ae365 Merge pull request #95 from 007revad/master
Update README.md
2023-09-13 14:32:29 -04:00
Dave Russell
ce439e0258 Update README.md
Fixed typos
2023-09-12 12:08:58 +10:00
11 changed files with 2942 additions and 447 deletions

View File

@@ -10,25 +10,34 @@ 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. Prior to opening a pull request, 1. Create an issue in the DBRepair repo against the current release
- Be certain to REBASE prior to opening the PR - Describe the deficiency to be addressed in sufficient detail
2. Complete your work in your branch
- Be certain to REBASE prior to starting work.
3. Prior to opening a pull request,
- Squash multiple commits into a single commit. - Squash multiple commits into a single commit.
- Clean up the commit message after squashing. - Clean up the commit message after squashing.
- Use force-push if needed to unify all changes. - Use force-push if needed to unify all changes so there is one hash to reference.
2. Open the pull request against the 'contribute' branch. 4. Open the pull request against the master branch
3. 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,
- 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://ChuckPa/PlexDBRepair/issues/12 (if we were fixing issue 12) eg: Fixes: https://github.com/ChuckPa/DBRepair/issues/12 (if we were fixing issue 12)
- Adding the above text+http tag 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.
-- In the event of unforseen issues, reverting the changes will be trivial and allow easier rework.
5. Be certain to request review with your pull request. 6. Be certain to request review with your pull request.
6. Upon completion of review and testing, contributions will be merged into master. 7. Upon completion of review and testing, contributions will be merged into master.
When the PR is approved and merged, Github will automatically mark the issue as closed and solved. When the PR is approved and merged, Github will automatically mark the issue as closed and fixed.
8. The fix will be included in the next release or immediately in a new release if so warranted.
### Policy ### Policy
@@ -36,5 +45,5 @@ To contribute to the project, please follow the following instructions:
While questions, suggestions, enhancement requests, and bug fixes are welcome and almost always implemented, While questions, suggestions, enhancement requests, and bug fixes are welcome and almost always implemented,
it's not possible to accept PRs without an accompanying issue documention which justifies the change. it's not possible to accept PRs without an accompanying issue documention which justifies the change.
Thanks,
Chuck Chuck

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,9 @@
Copyright (c) 2022, ChuckPa. Copyright (c) 2025, 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. This software is the intellectual property of ChuckPa
and used in conjunction with Plex Media Server (which is Copyright & Trademark of Plex, Inc.)
It may not be copied, modified, or redistributed in any way without expressly written permission of ChuckPa.
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.

662
README.md
View File

@@ -1,16 +1,12 @@
# PlexDBRepair # DBRepair (for Plex Media Server)
[![GitHub issues](https://img.shields.io/github/issues/ChuckPa/PlexDBRepair.svg?style=flat)](https://github.com/ChuckPa/PlexDBRepair/issues) [![GitHub issues](https://img.shields.io/github/issues/ChuckPa/DBRepair.svg?style=flat)](https://github.com/ChuckPa/DBRepair/issues)
[![Release](https://img.shields.io/github/release/ChuckPa/PlexDBRepair.svg?style=flat)](https://github.com/ChuckPa/PlexDBRepair/releases/latest) [![Release](https://img.shields.io/github/release/ChuckPa/DBRepair.svg?style=flat)](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 latest release](https://img.shields.io/github/downloads/ChuckPa/DBRepair/latest/total.svg)](https://github.com/ChuckPa/DBRepair/releases/latest)
[![Download total](https://img.shields.io/github/downloads/ChuckPa/PlexDBRepair/total.svg)](https://github.com/ChuckPa/PlexDBRepair/releases) [![Download total](https://img.shields.io/github/downloads/ChuckPa/DBRepair/total.svg)](https://github.com/ChuckPa/DBRepair/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)
# Introduction
DBRepair provides database repair and maintenance for the most common Plex Media Server database problems.
It is a simple menu-driven utility with a command line backend.
DBRepair is run from a command line (terminal or ssh/putty session) which has sufficient privilege to read/write the databases (minimum). DBRepair is run from a command line (terminal or ssh/putty session) which has sufficient privilege to read/write the databases (minimum).
If sufficient privleges exist (root), and supported by the environment, the options to start and stop PMS are presented as well. If sufficient privleges exist (root), and supported by the environment, the options to start and stop PMS are presented as well.
@@ -22,6 +18,9 @@ If sufficient privleges exist (root), and supported by the environment, the opti
2. Database is malformed / damaged / corrupted 2. Database is malformed / damaged / corrupted
3. Database has bloated from media addition or changes 3. Database has bloated from media addition or changes
4. Damaged indexes damaged 4. Damaged indexes damaged
5. Importing data from other databases (watch history)
6. Cleaning up operational temp files which PMS has forgotten to clean up
## Functions provided ## Functions provided
@@ -32,8 +31,12 @@ 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.
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
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
@@ -49,27 +52,35 @@ 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'.
``` ```
Plex Media Server Database Repair Utility (_host_configuration_name_) Database Repair Utility for Plex Media Server (_host_configuration_name_)
Version v1.0 Version v1.09.00
Select Select
1 - 'stop' PMS (if available) 1 - 'stop' - Stop PMS.
2 - 'automatic' database check, repair/optimize, and reindex in one step. 2 - 'automatic' - Check, Repair/Optimize, and Reindex Database in one step.
3 - 'check' database 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' database 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' / 'optimize' database 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' database 6 - 'reindex' - Rebuild database indexes.
7 - 'start' PMS (if available) 7 - 'start' - Start PMS
8 - 'import' viewstate (Watch history) from another PMS database
9 - 'replace' current database with newest usable backup copy (interactive)
10 - 'show' logfile
11 - 'status' of PMS (Stop/Run and databases)
12 - 'undo' - Undo last successful command
99 - exit 8 - 'import' - Import watch history from another database independent of Plex. (risky).
9 - 'replace' - Replace current databases with newest usable backup copy (interactive).
10 - 'show' - Show logfile.
11 - 'status' - Report status of PMS (run-state and databases).
12 - 'undo' - Undo last successful command.
Enter command # -or- command name (4 char min) : 21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache.
22 - 'purge' - Purge (delete) all temporary files left behind by PMS & the transcoder.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files.
99 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) :
@@ -83,14 +94,24 @@ If sufficient privleges exist (root), and supported by the environment, the opti
- BINHEX - BINHEX
- HOTIO - HOTIO
- Podman (libgpod) - Podman (libgpod)
4. Linux workstation & server 4. FreeBSD (14+)
5. Netgear (OS5 Linux-based systems) 5. Linux workstation & server
6. QNAP (QTS & QuTS) 6. MacOS
7. Synology (DSM 6 & DSM 7) 7. Netgear (OS5 Linux-based systems)
8. Western Digital (OS5) 8. QNAP (QTS & QuTS)
9. Synology (DSM 6 & DSM 7)
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.
@@ -102,24 +123,33 @@ If sufficient privleges exist (root), and supported by the environment, the opti
-------------------+---------------------+------------------------------------------ -------------------+---------------------+------------------------------------------
Apple | Downloads | ~/Downloads Apple | Downloads | ~/Downloads
Arch Linux | N/A | Anywhere Arch Linux | N/A | Anywhere
ASUSTOR | Public | /volume1/Public ASUSTOR | Plex | /volume1/Plex
binhex | N/A | Container root (adjacent /config) Binhex | N/A | Container root (adjacent /config)
Docker | 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)
Linux (wkstn/svr) | N/A | Anywhere Linux (wkstn/svr) | N/A | Anywhere
MacOS | N/A | Anywhere
Netgear (ReadyNAS) | "your_choice" | "/data/your_choice" Netgear (ReadyNAS) | "your_choice" | "/data/your_choice"
QNAP (QTS/QuTS) | Public | /share/Public QNAP (QTS/QuTS) | Public | /share/Public
SNAP | N/A | Anywhere
Synology (DSM 6) | Plex | /volume1/Plex (change volume as required) Synology (DSM 6) | Plex | /volume1/Plex (change volume as required)
Synology (DSM 7) | PlexMediaServer | /volume1/PlexMediaServer (change volume as required) Synology (DSM 7) | PlexMediaServer | /volume1/PlexMediaServer (change volume as required)
Western Digital | Public | /mnt/HD/HD_a2/Public (Does not support 'MyCloudHome' series) Western Digital | Public | /mnt/HD/HD_a2/Public (Does not support 'MyCloudHome' series)
``` ```
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/PlexDBRepair/releases/latest 1. Open your browser to https://github.com/ChuckPa/DBRepair/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 'PlexDBRepair-X.Y.Z.tar.gz' 3. Knowing the file name will always be of the form 'DBRepair-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)
@@ -131,13 +161,15 @@ If sufficient privleges exist (root), and supported by the environment, the opti
### (In the examples below, substitute "x.y.z" with the actual version you download/use)
### EXAMPLE: To install & launch on Synology DSM 6 / DSM 7 ### EXAMPLE: To install & launch on Synology DSM 6 / DSM 7
cd /volume1/Plex # use /volume1/PlexMediaServer on DSM 7 cd /volume1/Plex # use /volume1/PlexMediaServer on DSM 7
sudo bash sudo bash
tar xf PlexDBRepair-x.y.z.tar.gz tar xf DBRepair-x.y.z.tar.gz
cd PlexDBRepair-x.y.z cd DBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
@@ -148,8 +180,8 @@ If sufficient privleges exist (root), and supported by the environment, the opti
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 PlexDBRepair-1.0.0.tar.gz tar xf DBRepair-x.y.z.tar.gz
cd PlexDBRepair-1.0.0 cd DBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
``` ```
@@ -157,8 +189,8 @@ If sufficient privleges exist (root), and supported by the environment, the opti
``` ```
sudo bash sudo bash
cd /path/to/DBRepair.tar cd /path/to/DBRepair.tar
tar xf PlexDBRepair-1.0.0.tar.gz tar xf DBRepair-x.y.z.tar.gz
cd PlexDBRepair-1.0.0 cd DBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh stop auto start exit ./DBRepair.sh stop auto start exit
``` ```
@@ -167,8 +199,8 @@ If sufficient privleges exist (root), and supported by the environment, the opti
``` ```
osascript -e 'quit app "Plex Media Server"' osascript -e 'quit app "Plex Media Server"'
cd ~/Downloads cd ~/Downloads
tar xvf PlexDBRepai PlexDBRepair-1.0.0.tar.gz tar xf DBRepair-x.y.z.tar.gz
cd PlexDBRepair-1.0.0 cd DBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
@@ -200,23 +232,22 @@ 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 - Salavage as much as possible from the databases and rebuild them into a usable database. 2. (5) Repair - Salvage 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
C. Database sizes excessively large when compared to amount of media indexed (item count) D. Database sizes excessively large/bloated when compared to amount of media indexed (item count)
1. (3) Check - Make certain both databases are fully intact (repair if needed) 1. (23) Deflate - Correct the known problem with a database table and recover the wasted space.
2. (4) Vacuum - Instruct SQLite to rebuild its tables and recover unused space. 2. (2) Auto - Perform automated check, repair, and reindex of the deflated database
3. (6) Reindex - Rebuild Indexes.
4. (99) Exit 4. (99) Exit
D. User interface has become 'sluggish' as more media was added E. 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
E. Undo F. 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.
@@ -224,7 +255,7 @@ These examples
Special considerations: Special considerations:
1. As stated above, this utilty requires PMS to be stopped in order to do what it does. 1. As stated above, this utility requires PMS to be stopped in order to do what it does.
2. - This utility CAN sit at the menu prompt with PMS running. 2. - This utility CAN sit at the menu prompt with PMS running.
- You did a few things and want to check BEFORE exiting the utility - You did a few things and want to check BEFORE exiting the utility
- If you don't like how it worked out, - If you don't like how it worked out,
@@ -246,18 +277,29 @@ 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.
"99" was originally going to be "Quit immediately save all files" but development feedback Community feedback has resulted in:
resulted in this configuration
"Exit" is the preferred method to leave. "99" or "Exit" - Preferred way to exit and cleanup temp databases
"98" or "Quit" - Get out now without deleting the temp databases (Usually used only during unexpected failures)
"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
@@ -274,6 +316,8 @@ Attention:
This executes: Stop PMS, Automatic (Check, Repair, Reindex), Start PMS, and Exit commands This executes: Stop PMS, Automatic (Check, Repair, Reindex), Start PMS, and Exit commands
Beginning with v1.06.00, the 'exit' command is optional when scripted.
## Exiting ## Exiting
@@ -294,50 +338,63 @@ bash-4.4# ./DBRepair.sh
Plex Media Server Database Repair Utility (Synology (DSM 7)) Database Repair Utility for Plex Media Server (Ubuntu 20.04.6 LTS)
Version v1.0.0 Version v1.03.01
Select Select
1 - 'stop' - Stop PMS 1 - 'stop' - Stop PMS.
2 - 'automatic' - database check, repair/optimize, and reindex in one step. 2 - 'automatic' - Check, Repair/Optimize, and Reindex Database in one step.
3 - 'check' - Perform integrity check of database 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database database indexes 6 - 'reindex' - Rebuild 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).
9 - 'replace' - Replace current databases with newest usable backup copy (interactive) 9 - 'replace' - Replace current databases with newest usable backup copy (interactive).
10 - 'show' - Show logfile 10 - 'show' - Show logfile.
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.
99 - exit 21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors.
Enter command # -or- command name (4 char min) : 1 88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : 1
Stopping PMS. Stopping PMS.
Stopped PMS. Stopped PMS.
Select Select
1 - 'stop' - Stop PMS 1 - 'stop' - Stop PMS.
2 - 'automatic' - database check, repair/optimize, and reindex in one step. 2 - 'automatic' - Check, Repair/Optimize, and Reindex Database in one step.
3 - 'check' - Perform integrity check of database 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database database indexes 6 - 'reindex' - Rebuild 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).
9 - 'replace' - Replace current databases with newest usable backup copy (interactive) 9 - 'replace' - Replace current databases with newest usable backup copy (interactive).
10 - 'show' - Show logfile 10 - 'show' - Show logfile.
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.
99 - exit 21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : auto Enter command # -or- command name (4 char min) : auto
@@ -372,19 +429,28 @@ Automatic Check,Repair/optimize,Index successful.
Select Select
1 - 'stop' PMS 1 - 'stop' - Stop PMS.
2 - 'automatic' database check, repair/optimize, and reindex in one step. 2 - 'automatic' - Check, Repair/Optimize, and Reindex Database in one step.
3 - 'check' database 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' database 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' / 'optimize' database 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' database 6 - 'reindex' - Rebuild database indexes.
7 - 'start' PMS 7 - 'start' - Start PMS
8 - 'import' viewstate (Watch history) from another PMS database
9 - 'replace' current database with newest usable backup copy (interactive) 8 - 'import' - Import watch history from another database independent of Plex. (risky).
10 - 'show' logfile 9 - 'replace' - Replace current databases with newest usable backup copy (interactive).
11 - 'status' of PMS (Stop/Run and databases) 10 - 'show' - Show logfile.
12 - 'undo' - Undo last successful command 11 - 'status' - Report status of PMS (run-state and databases).
99 - exit 12 - 'undo' - Undo last successful command.
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : start Enter command # -or- command name (4 char min) : start
@@ -393,19 +459,28 @@ Started PMS
Select Select
1 - 'stop' PMS 1 - 'stop' - Stop PMS.
2 - 'automatic' database check, repair/optimize, and reindex in one step. 2 - 'automatic' - Check, Repair/Optimize, and Reindex Database in one step.
3 - 'check' database 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' database 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' / 'optimize' database 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' database 6 - 'reindex' - Rebuild database indexes.
7 - 'start' PMS 7 - 'start' - Start PMS
8 - 'import' viewstate (Watch history) from another PMS database
9 - 'replace' current database with newest usable backup copy (interactive) 8 - 'import' - Import watch history from another database independent of Plex. (risky).
10 - 'show' logfile 9 - 'replace' - Replace current databases with newest usable backup copy (interactive).
11 - 'status' of PMS (Stop/Run and databases) 10 - 'show' - Show logfile.
12 - 'undo' - Undo last successful command 11 - 'status' - Report status of PMS (run-state and databases).
99 - exit 12 - 'undo' - Undo last successful command.
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : stat Enter command # -or- command name (4 char min) : stat
@@ -417,19 +492,28 @@ Status report: Sat Feb 25 04:38:50 PM EST 2023
Select Select
1 - 'stop' PMS 1 - 'stop' - Stop PMS.
2 - 'automatic' database check, repair/optimize, and reindex in one step. 2 - 'automatic' - Check, Repair/Optimize, and Reindex Database in one step.
3 - 'check' database 3 - 'check' - Perform integrity check of database.
4 - 'vacuum' database 4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' / 'optimize' database 5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' database 6 - 'reindex' - Rebuild database indexes.
7 - 'start' PMS 7 - 'start' - Start PMS
8 - 'import' viewstate (Watch history) from another PMS database
9 - 'replace' current database with newest usable backup copy (interactive) 8 - 'import' - Import watch history from another database independent of Plex. (risky).
10 - 'show' logfile 9 - 'replace' - Replace current databases with newest usable backup copy (interactive).
11 - 'status' of PMS (Stop/Run and databases) 10 - 'show' - Show logfile.
12 - 'undo' - Undo last successful command 11 - 'status' - Report status of PMS (run-state and databases).
99 - exit 12 - 'undo' - Undo last successful command.
21 - 'prune' - Remove old image files (jpeg,jpg,png) from PhotoTranscoder cache & all temp files left by PMS.
22 - 'purge' - Remove unused temp files.
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) : exit Enter command # -or- command name (4 char min) : exit
@@ -447,8 +531,8 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# ./DBRepair.sh
Plex Media Server Database Repair Utility (Ubuntu 20.04.5 LTS) Database Repair Utility for Plex Media Server (Ubuntu 20.04.5 LTS)
Version v1.0.0 Version v1.03.01
[2023-03-05 18.53.49] Stopping PMS. [2023-03-05 18.53.49] Stopping PMS.
@@ -571,16 +655,43 @@ 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.
To save all intermediate databases, use the 'Quit' command. To save all intermediate databases, use the 'Quit' command.
### Ignore / Honor
Toggle the state (ON/OFF) of the IGNORE flag. When ON, Duplicates and UNIQUE constraint errors will be ignored.
Caution is advised as other errors will be ignored during initial processing.
In ALL cases, DBRepair will never allow a bad database to be created.
### Import ### Import
Imports (raw) watch history from another PMS database without ability to check validity Imports (raw) watch history from another PMS database without ability to check validity
( This can have side effects of "negative watch count" being displayed. Caution is advised. ) ( This can have side effects of "negative watch count" being displayed. Caution is advised. )
### Prune (Remove)
Checks the PhotoTransoder cache directory for JPG, JPEG, and PNG files older than 30 days and removes them.
Under normal operation, PMS manages this automatically.
Under certain conditions, PMS will fail to prune them (which is run during Scheduled Maintenance)
This command allows you to manually remove what PMS would do normally during that Scheduled Maintenance.
#### Warning: Initial pruning might take longer than expected.
Execution time, using a Synology DS418 as benchmark, is approximately 100,000 image files per 2 minutes.
For now, Both forms "Prune" and "Remove" are accepted.
### Reindex ### Reindex
@@ -589,7 +700,7 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases#
### Repair ### Repair
Extracts/recovers all the usable data fron the existing databases into text (SQL ascii) form. Extracts/recovers all the usable data from the existing databases into text (SQL ascii) form.
Repair then creates new SQLite-valid databases from the extracted/recovered data. Repair then creates new SQLite-valid databases from the extracted/recovered data.
The side effect of this process is a fully defragmented database (optimal for Plex use). The side effect of this process is a fully defragmented database (optimal for Plex use).
@@ -644,6 +755,10 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases#
After DB tasks are completed, and you've exited the container, restart it normally through After DB tasks are completed, and you've exited the container, restart it normally through
your normal 'docker start' mechanism. your normal 'docker start' mechanism.
If your container (Image) supports start/stop , it will be shown in the menu for you to use.
If not, you'll need to disable health checks before safely running this tool.
### Undo ### Undo
Undo allows you to "Undo" the last Import, Repair, Replace, or Vacuum command. Undo allows you to "Undo" the last Import, Repair, Replace, or Vacuum command.
@@ -655,4 +770,293 @@ 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.
### For most users, the "automatic" command is the best method. It will regenerate the SQLite indexes
as part of the process.
# Environment Variables
DBRepair now supports the use of environment variables to allow customization of some operations.
#### WARNING: Use of these variables may adverse impact PMS operation or performance. USE WITH CAUTION.
## DBREPAIR_CACHEAGE - Specify the maximum age for PhotoTrancoder Cache images to be retained
Default DBREPAIR_CACHEAGE is set at 30 days.
You may override this by setting DBREPAIR_CACHEAGE=N, where N is the number of days worth of cache image
you wish to retain.
When using interactively, DBRepair will prompt you to confirm OK to remove and show you the cache age
Example: export DBREPAIR_CACHEAGE=20
```
Enter command # -or- command name (4 char min) : remove
Counting how many files are more than 20 days old.
OK to prune 4497 files? (Y/N) ?
```
## DBREPAIR_PAGESIZE - Allows setting the Plex SQLite 'page_size'.
Normal Linux (ext4, xfs) filesystems do not need this customization because the filesystem block size = 4096.
ZFS users sometimes need to customize their datasets to improve I/O performance (HDDs vs SSDs).
This capability allows them to compensate for some of those losses.
If present, sets the Plex SQLite 'page_size' for both Main and Blobs databases.
If not present, the default page size for the host OS is used (typically 4096 to match the OS page size).
When in use, you will see the message: "Setting Plex SQLite page size ($DbPageSize)"
This will be shown on the console output and reported in the logfile.
### Constraints:
1. Must be a power of 2, with 1024 (2^10) as the Plex default. (per SQLite 3.12.0 documentation).
Any invalid value provided will be rounded up to the next integral value (1024, 2048, 4096 ... 65536)
This may or may not be the value you intended. Caution is advised.
2. May not exceed 65536 (per SQLite 3.12.0 documentation).
Any value exceeding 65536 will be truncated to 65536.
### Validation
If the value of DBREPAIR_PAGESIZE is not compliant with requirements, a new value will be selected.
Typing errors will be rounded up (e.g 65535 vs 65536) to the next multiple of 1024 before validation
is performed.
If the value is invalid, an error will be printed and recorded in the logfile. The next higher power
of two will be selected.
If the value is too large, it will be reduced to the SQLite maximum of 65536.
### Management
If you attempt to optimize your database but find the resultant performance is not to your liking,
you may try another value and run "automatic" again.
If you ultimately decide to run with the default values (4096),
1. Remove the environment variable.
2. Run DBRepair again using "automatic". Your databases will revert to the host OS's default.
### Usage: (QNAP example shown)
```
# export DBREPAIR_PAGESIZE=65534
# ./DBRepair.sh stop deflate auto start exit
Database Repair Utility for Plex Media Server (QNAP)
Version v1.12.00
[2025-10-21 16.54.00] PMS already stopped.
[2025-10-21 16.54.00] Check and Deflate started.
[2025-10-21 16.54.00]
[2025-10-21 16.54.00] Checking the PMS databases
[2025-10-21 16.54.19] Check complete. PMS main database is OK.
[2025-10-21 16.54.21] Check complete. PMS blobs database is OK.
[2025-10-21 16.54.21]
[2025-10-21 16.54.21] Backup current databases with '-BACKUP-2025-10-21_16.54.21' timestamp.
[2025-10-21 16.56.29] Starting Deflate (Part 1 of 2 - Repair database table)
[2025-10-21 16.56.29] Estimated completion is approx 6 minutes but is CPU & I/O speed dependent
[2025-10-21 16.56.29]
[2025-10-21 16.56.30] PMS main database successfully repaired.
[2025-10-21 16.56.30] Starting Deflate (Part 2 of 2 - Reduce size)
[2025-10-21 16.56.35] PMS main database size reduced.
[2025-10-21 16.56.35] Verifying PMS main database.
[2025-10-21 16.56.50] Verification complete. PMS main database is OK.
[2025-10-21 16.56.50] PMS main database reduced from 31586 MB to 206 MB
[2025-10-21 16.56.51] Saving current main database with '-BLOATED-2025-10-21_16.54.21'
[2025-10-21 16.56.51] Making deflated database active
[2025-10-21 16.56.51] PMS main database deflate completed.
[2025-10-21 16.56.51] Deflate successful.
[2025-10-21 16.56.51] Recommend running Auto next to complete optimization of new database.
[2025-10-21 16.56.51] Automatic Check,Repair,Index started.
[2025-10-21 16.56.51]
[2025-10-21 16.56.51] Checking the PMS databases
[2025-10-21 16.57.04] Check complete. PMS main database is OK.
[2025-10-21 16.57.05] Check complete. PMS blobs database is OK.
[2025-10-21 16.57.05]
[2025-10-21 16.57.05] Exporting current databases using timestamp: 2025-10-21_16.56.51
[2025-10-21 16.57.05] Exporting Main DB
[2025-10-21 16.57.24] Exporting Blobs DB
[2025-10-21 16.59.18] Successfully exported the main and blobs databases.
[2025-10-21 16.59.18] Start importing into new databases.
[2025-10-21 16.59.18] Importing Main DB.
[2025-10-21 16.59.18] Setting Plex SQLite page size (65536)
[2025-10-21 17.00.19] Importing Blobs DB.
[2025-10-21 17.00.19] Setting Plex SQLite page size (65536)
[2025-10-21 17.00.32] Successfully imported databases.
[2025-10-21 17.00.32] Verifying databases integrity after importing.
[2025-10-21 17.01.59] Verification complete. PMS main database is OK.
[2025-10-21 17.02.01] Verification complete. PMS blobs database is OK.
[2025-10-21 17.02.01] Saving current databases with '-BACKUP-2025-10-21_16.56.51'
[2025-10-21 17.02.01] Making repaired databases active
[2025-10-21 17.02.01] Repair complete. Please check your library settings and contents for completeness.
[2025-10-21 17.02.01] Recommend: Scan Files and Refresh all metadata for each library section.
[2025-10-21 17.02.01]
[2025-10-21 17.02.01] Backing up of databases
[2025-10-21 17.02.01] Backup current databases with '-BACKUP-2025-10-21_17.02.01' timestamp.
[2025-10-21 17.02.02] Reindexing main database
[2025-10-21 17.02.13] Reindexing main database successful.
[2025-10-21 17.02.13] Reindexing blobs database
[2025-10-21 17.02.14] Reindexing blobs database successful.
[2025-10-21 17.02.14] Reindex complete.
[2025-10-21 17.02.14] Automatic Check, Repair/optimize, & Index successful.
[2025-10-21 17.02.14] Starting PMS.
[2025-10-21 17.02.14] Started PMS
#
```
# Special considerations - MANUAL CONFIGURATION
Manual configuration is enabled by supplying two command line arguments.
These must precede all other options or commands on the command line.
--sqlite "Directory containing Plex SQLite" (OR) --sqlite "/path/to/Plex SQLite"
Scripted Example:
DBRepair.sh --sqlite /usr/lib/plexmediaserver --databases "/real/host/directory/...../Databases" auto prune
-or-
DBRepair.sh --sqlite "/tmp/plex/Plex SQLite" --databases "/real/host/directory/...../Databases" auto prune
Interactive Example:
DBRepair.sh --sqlite /usr/lib/plexmediaserver --databases /real/host/directory/...../Databases
## Manual Configuration -- Example of using with docker.
1. I find the SQLite executable
```
root@Jasper:/mnt/disk1/appdata# find /var/lib/docker -name \*SQLite\*
/var/lib/docker/btrfs/subvolumes/4bb78fb70589d4d2ba56754f4d6bc0edd4cdaa8eab7986943767e09a66cefd19/usr/lib/plexmediaserver/Plex SQLite
/var/lib/docker/btrfs/subvolumes/eae4fef243ca71fbf190957256705fdc493863ee1f08222a7df0b5004cc8afb6-init/usr/lib/plexmediaserver/Plex SQLite
/var/lib/docker/btrfs/subvolumes/eae4fef243ca71fbf190957256705fdc493863ee1f08222a7df0b5004cc8afb6/usr/lib/plexmediaserver/Plex SQLite
root@Jasper:/mnt/disk1/appdata#
```
2. I get to where my container is
```
root@Jasper:~# cd /mnt/user
root@Jasper:/mnt/user# ls
Media/ appdata/ domains/ isos/ plex/ system/
root@Jasper:/mnt/user# cd appdata
root@Jasper:/mnt/user/appdata# ls
PlexMediaServer/
root@Jasper:/mnt/user/appdata# cd PlexMediaServer/
```
3. Invoke DBRepair.sh with both --sqlite and --databases command line options specified (both are required when either is used)
```
root@Jasper:/mnt/user/appdata/PlexMediaServer# /tmp/DBRepair.sh --databases /mnt/user/appdata/PlexMediaServer/Library/Application\ Support/Plex\ Media\ Server/Plug-in\ Support/Databases/ --sqlite /var/lib/docker/btrfs/subvolumes/4bb78fb70589d4d2ba56754f4d6bc0edd4cdaa8eab7986943767e09a66cefd19/usr/lib/plexmediaserver/
Database Repair Utility for Plex Media Server (User Defined)
Version v1.09.00
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/'
Select
1 - 'stop' - (Not available. Stop manually.)
2 - 'automatic' - Check, Repair/Optimize, and Reindex Database in one step.
3 - 'check' - Perform integrity check of database.
4 - 'vacuum' - Remove empty space from database without optimizing.
5 - 'repair' - Repair/Optimize databases.
6 - 'reindex' - Rebuild database indexes.
7 - 'start' - (Not available. Start manually)
8 - 'import' - Import watch history from another database independent of Plex. (risky).
9 - 'replace' - Replace current databases with newest usable backup copy (interactive).
10 - 'show' - Show logfile.
11 - 'status' - Report status of PMS (run-state and databases).
12 - 'undo' - Undo last successful command.
21 - 'prune' - Prune (remove) old image files (jpeg,jpg,png) from PhotoTranscoder cache older than specific age.
22 - 'purge' - Purge (remove) all temporary files left by PMS & Transcoder in Temp Dir.'
23 - 'deflate' - Deflate a bloated PMS main database.
42 - 'ignore' - Ignore duplicate/constraint errors.
88 - 'update' - Check for updates.
98 - 'quit' - Quit immediately. Keep all temporary files.
99 - 'exit' - Exit with cleanup options.
Enter command # -or- command name (4 char min) :
```
# Special considerations - Synology DSM 7
Using DBRepair on Synology DSM 7 systems with Task Scheduler requires special handling.
DSM 7 has additional security (app-armor). Care must be taken to not violate this.
One exception must be implemented. Care must be used to implement.
### DSM 7 - Step 1 - Designate a DSM username which will run DBRepair
- Creating a to-task username with a complex password is best practice
- Create a Scheduled task, user-script:
- Runs as root
- Emails you the result
- Is not scheduled
- Is disabled in the Task Scheduler task list
Contents of the user-script are:
```
#!/bin/bash
#
# This script grants the given syno username (your username)
# the ability to elevate to 'root' privilege for use with DBRepair.sh
#
# Set your desired Syno username here (no spaces in the username)
MyUsername="chuck"
# Confirm username exists
if [ "$(id "$MyUsername")" = "" ]; then
echo ERROR: No such user \'$MyUsername\'
exit 1
fi
# Remove old record
sed -i s/^${MyUsername}.\*$// /etc/sudoers
# Add myself to sudoers
echo "$MyUsername" 'ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
```
### DSM 7 - Step 2 - Run DBRepair as the designated username
With the security now set, DBRepair can be invoked from Task Scheduler.
Download and place DBRepair.sh in the desired location (PlexMediaServer shared folder ok)
Make certain it's executable.
Create Scheduled Task - User-Script to run DBRepair
- Runs as the selected username
- Emails you the result
- Runs on the schedule you desire (Weekly after PMS scheduled tasks completed is optimal)
```
#!/bin/bash
# Go to the PlexMediaServer shared folder
cd /var/packages/PlexMediaServer/shares/PlexMediaServer
# Run classic Stop PMS, Automatic optimization/repair, Start PMS, and exit sequence
sudo ./DBRepair.sh stop auto start exit
```
# Special Considerations - Windows
Windows support is available via DBRepair-Windows.ps1 and DBRepair-Windows.bat. See [README-Windows](Windows/README-Windows.md) for details.

View File

@@ -1,13 +1,233 @@
# PlexDBRepair # DBRepair
[![GitHub issues](https://img.shields.io/github/issues/ChuckPa/PlexDBRepair.svg?style=flat)](https://github.com/ChuckPa/PlexDBRepair/issues) [![GitHub issues](https://img.shields.io/github/issues/ChuckPa/DBRepair.svg?style=flat)](https://github.com/ChuckPa/DBRepair/issues)
[![Release](https://img.shields.io/github/release/ChuckPa/PlexDBRepair.svg?style=flat)](https://github.com/ChuckPa/PlexDBRepair/releases/latest) [![Release](https://img.shields.io/github/release/ChuckPa/DBRepair.svg?style=flat)](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 latest release](https://img.shields.io/github/downloads/ChuckPa/DBRepair/latest/total.svg)](https://github.com/ChuckPa/DBRepair/releases/latest)
[![Download total](https://img.shields.io/github/downloads/ChuckPa/PlexDBRepair/total.svg)](https://github.com/ChuckPa/PlexDBRepair/releases) [![Download total](https://img.shields.io/github/downloads/ChuckPa/DBRepair/total.svg)](https://github.com/ChuckPa/DBRepair/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
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.
v1.06.01
1. Manual SQLite path - You many now also specify the full path to "Plex SQLite". ( example: "/tmp/downloads/Plex SQLite")
DBRepair.sh will automatically figure out which form to use (path or directory)
--sqlite "/real/host/path/to/plexmediaserver/Directory"
--sqlite "/real/host/path/to/plexmediaserver/directory/Plex SQLite"
v1.06.00
1. Manual configuration - You may now run DBRepair from outside container environments.
This provides a method for running DBRepair when container healthcheck prevents it.
The directories to both:
a. Where Plex SQLite can be found: ( --sqlite "/real/host/path/to/plexmediaserver/Directory" )
b. Where the databases can be found: ( --databases "/real/host/path/to/Plugin Support/Databases" )
If used, these options MUST precede all other command line options
WARNING: The host MUST provide all standard commands AND support "stat -c" option. Bash commands will NOT autoconfigure.
2. "Exit" when scripted: The previously annoyance which required "exit" to be specified on the command line (scripted) has been fixed.
"exit" is no longer required in this use.
"exit" or "quit" is still required in interactive use.
3. Windows: DBRepair-Windows now supports 32 bit PMS on 64 bit Windows base systems. (Mixed mode operation)
v1.05.02
1. HOTIO image paths HOTIO images have again changed PMS executable location. This update
adds support for the lastest location.
v1.05.01
1. MacOS - Transcoder cache directory uses different location than default Plex.
Make "CacheDir" variable.
2. PPM files - Prune old PPM files just as other image files are pruned.
v1.05.00
1. Kubernetes support - Add support for Kubernetes (and also TrueNAS) containers.
v1.04.00
1. SNAP support - Add support for Plex Media Server SNAP package.
v1.03.00
1. New command: Purge - Removes old image files from the Trancoder cache.
These are normally removed during scheduled maintenance.
If scheduled maintenance doesn't complete all tasks, they won't get removed
and will build up.
This command allows you to remove them.
The default age is 30 days. Files older than 30 days will be purged.
2. Introduces Environment variable support (customizing) DBRepair operation.
- DBREPAIR_PAGESIZE: DBREPAIR_PAGESIZE=N (where N is a multiple of 1024, less equal 65536)
This sets the Plex SQLite database page_size during optimization operations.
It's most beneficial on ZFS filesystems to allow tuning to the Dataset size.
- DBREPAIR_CACHEAGE: DBREPAIR_CACHEAGE=N (where N is the max age, in Days) to retain when purging
older image files in the Cache/PhotoTranscoder directory.
This variable allows you to set the purge age (greater than "N" days).
v1.02.01
- Minor fix to logging. One line of output at the console was not present in the logfile
(this is important when diagnosing after connection-loss scenarios and DBRepair.sh was interrupted)
- Added documentation in README.md for using DBRepair with Synology DSM 7 Task Scheduler.
(Maintains app-armor compliance)
v1.02.00
- Provide menu option to ignore/honor "Duplicate" and "UNIQUE Constraint" errors during DB Repair,
and when importing data from other databases.
This is equivalent to the '-i' command line option but now can be used interactively.
- Fixed. ConfirmYesNo would print error message when it shouldn't.
- Fixed. Erroneous echo of your reply when responding to yes/no questions.
v1.01.04
- Missing IgnoreErrors (-i / -f) test when reimporting damaged DB with certain errors prevented repair
in all cases.
v1.01.02
- Correct updating when scripted versus interactive.
v1.01.00
- Adds ability to self download and install latest version of DBRepair.sh
- Slightly changes numbering style to accommodate future updates with new update capability.
- Thanks to @causefx for his contributions to this release
v1.0.13
- Improve HOTIO support. Allow both older and newer directory structure
v1.0.12 v1.0.12
@@ -115,7 +335,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'.
Plex Media Server Database Repair Utility (_host_configuration_name_) Database Repair Utility for Plex Media Server (_host_configuration_name_)
Version v1.0.0 Version v1.0.0
Select Select
@@ -180,10 +400,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/PlexDBRepair/releases/latest 1. Open your browser to https://github.com/ChuckPa/DBRepair/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 'PlexDBRepair-X.Y.Z.tar.gz' 3. Knowing the file name will always be of the form 'DBRepair-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)
@@ -200,8 +420,8 @@ These type changes can only be performed by PMS.
cd /volume1/Plex cd /volume1/Plex
sudo bash sudo bash
tar xf PlexDBRepair-x.y.z.tar.gz tar xf DBRepair-x.y.z.tar.gz
cd PlexDBRepair-x.y.z cd DBRepair-x.y.z
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
@@ -213,8 +433,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 PlexDBRepair-1.0.0.tar.gz tar xf DBRepair-1.0.0.tar.gz
cd PlexDBRepair-1.0.0 cd DBRepair-1.0.0
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
``` ```
@@ -222,8 +442,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 PlexDBRepair-1.0.0.tar.gz tar xf DBRepair-1.0.0.tar.gz
cd PlexDBRepair-1.0.0 cd DBRepair-1.0.0
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh stop auto start exit ./DBRepair.sh stop auto start exit
``` ```
@@ -232,8 +452,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 PlexDBRepair-1.0.0.tar.gz tar xvf PlexDBRepai DBRepair-1.0.0.tar.gz
cd PlexDBRepai PlexDBRepair-1.0.0 cd PlexDBRepai DBRepair-1.0.0
chmod +x DBRepair.sh chmod +x DBRepair.sh
./DBRepair.sh ./DBRepair.sh
@@ -338,7 +558,7 @@ bash-4.4# ./DBRepair.sh
Plex Media Server Database Repair Utility (Synology (DSM 7)) Database Repair Utility for Plex Media Server (Synology (DSM 7))
Version v1.0.0 Version v1.0.0
@@ -491,7 +711,7 @@ root@lizum:/sata/plex/Plex Media Server/Plug-in Support/Databases# ./DBRepair.sh
Plex Media Server Database Repair Utility (Ubuntu 20.04.5 LTS) Database Repair Utility for Plex Media Server (Ubuntu 20.04.5 LTS)
Version v1.0.0 Version v1.0.0

View File

@@ -1,14 +1,21 @@
@echo off @echo off
REM PlexDBRepair.bat - Database maintenance / rebuild tool for Windows. REM DBRepair.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.
REM REM
REM -- WARNNING -- WARNING -- WARNING REM -- WARNNING -- WARNING -- WARNING
REM REM
REM 1. This is stable working software but not "Released" software. Development will continue. REM This is stable working software but not "Released" software. Development will continue.
REM 2. You must ensure variable PlexData points to your databases. (there is no automatic detection at this time)
REM setlocal enabledelayedexpansion
echo.
echo NOTE: This script is being replaced with the PowerShell script DBRepair-Windows.ps1,
echo which aims to better emulate DBRepair.sh (more options, interactive mode, etc).
echo Consider moving over to the new script.
echo.
REM ### Create Timestamp REM ### Create Timestamp
set Hour=%time:~0,2% set Hour=%time:~0,2%
set Min=%time:~3,2% set Min=%time:~3,2%
@@ -20,33 +27,79 @@ set Hour=%Hour: =%
REM ## Set TimeStamp ## REM ## Set TimeStamp ##
set TimeStamp=%Hour%-%Min%-%Sec% set TimeStamp=%Hour%-%Min%-%Sec%
REM These assume PMS is in the default location REM Find PMS database location
set "PlexData=%LOCALAPPDATA%\Plex Media Server\Plug-in Support\Databases" for /F "tokens=2* skip=2" %%a in ('REG.EXE QUERY "HKCU\Software\Plex, Inc.\Plex Media Server" /v "LocalAppDataPath" 2^> nul') do set "PlexData=%%b\Plex Media Server\Plug-in Support\Databases"
set "PlexSQL=%PROGRAMFILES%\Plex\Plex Media Server\Plex SQLite" if not exist "%PlexData%" (
if exist "%LOCALAPPDATA%\Plex Media Server\Plug-in Support\Databases" (
set "PlexData=%LOCALAPPDATA%\Plex Media Server\Plug-in Support\Databases"
) else (
echo Could not determine Plex database path.
echo Normally %LOCALAPPDATA%\Plex Media Server\Plug-in Support\Databases
echo.
goto :EOF
)
)
REM Find PMS installation location.
for /F "tokens=2* skip=2" %%a in ('REG.EXE QUERY "HKCU\Software\Plex, Inc.\Plex Media Server" /v "InstallFolder" 2^> nul') do set "PlexSQL=%%b\Plex SQLite.exe"
if not exist "%PlexSQL%" (
REM InstallFolder might be set under HKLM, not HKCU
for /F "tokens=2* skip=2" %%a in ('REG.EXE QUERY "HKLM\Software\Plex, Inc.\Plex Media Server" /v "InstallFolder" 2^> nul') do set "PlexSQL=%%b\Plex SQLite.exe"
)
REM If InstallFolder wasn't set, or the resulting file doesn't exist, iterate through the
REM PROGRAMFILES variables looking for it. If we still can't find it, ask the user to provide it.
if not exist "%PlexSQL%" (
if exist "%PROGRAMFILES%\Plex\Plex Media Server\Plex SQLite.exe" (
set "PlexSQL=%PROGRAMFILES%\Plex\Plex Media Server\Plex SQLite.exe"
) else (
if exist "%PROGRAMFILES(X86)%\Plex\Plex Media Server\Plex SQLite.exe" (
echo NOTE: 32-bit version of PMS detected on a 64-bit version of Windows. Updating to the 64-bit release of PMS is recommended.
set "PlexSQL=%PROGRAMFILES(X86)%\Plex\Plex Media Server\Plex SQLite.exe"
) else (
echo Could not determine SQLite path. Please provide it below
echo Normally %PROGRAMFILES%\Plex\Plex Media Server\Plex SQLite.exe
echo.
REM Last ditch effort, ask the user for the full path to Plex SQLite.exe
set /p "PlexSQL=Path to Plex SQLite.exe: "
if not exist "!PlexSQL!" (
echo "!PlexSQL!" could not be found. Cannot continue.
goto :EOF
)
)
)
)
REM Set temporary file locations
set "DBtmp=%PlexData%\dbtmp" set "DBtmp=%PlexData%\dbtmp"
set "TmpFile=%DBtmp%\results.tmp" 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%\PlexDBRepair.log" echo %time% -- ====== Session begins. (%date%) ====== >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Plex is running. Please stop Plex Media Server and try again. >> "%PlexData%\DBRepair.log"
exit /B 1 exit /B 1
) )
cd "%PlexData%" cd "%PlexData%"
mkdir "%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%\PlexDBRepair.log" echo %time% -- Exporting Main DB >> "%PlexData%\DBRepair.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.
@@ -54,7 +107,7 @@ if not %ERRORLEVEL%==0 (
) )
echo %time% -- Exporting Blobs DB echo %time% -- Exporting Blobs DB
echo %time% -- Exporting Blobs DB >> "%PlexData%\PlexDBRepair.log" echo %time% -- Exporting Blobs DB >> "%PlexData%\DBRepair.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.
@@ -62,75 +115,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%\PlexDBRepair.log" echo %time% -- Exporting Complete. >> "%PlexData%\DBRepair.log"
echo %time% -- Creating Main DB echo %time% -- Creating Main DB
echo %time% -- Creating Main DB >> "%PlexData%\PlexDBRepair.log" echo %time% -- Creating Main DB >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- ERROR: Cannot create Main DB. Aborting. >> "%PlexData%\DBRepair.log"
exit /b 3 exit /b 3
) )
echo %time% -- Verifying Main DB echo %time% -- Verifying Main DB
echo %time% -- Verifying Main DB >> "%PlexData%\PlexDBRepair.log" echo %time% -- Verifying Main DB >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Main DB verification check is: %Result% >> "%PlexData%\DBRepair.log"
if not "%Result%" == "ok" ( if not "%Result%" == "ok" (
echo %time% -- ERROR: Main DB verificaion failed. Exiting. echo %time% -- ERROR: Main DB verification failed. Exiting.
echo %time% -- ERROR: Main DB verificaion failed. Exiting. >> "%PlexData%\PlexDBRepair.log" echo %time% -- ERROR: Main DB verification failed. Exiting. >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Main DB verification successful. >> "%PlexData%\DBRepair.log"
echo %time% -- Creating Blobs DB echo %time% -- Creating Blobs DB
echo %time% -- Creating Blobs DB >> "%PlexData%\PlexDBRepair.log" echo %time% -- Creating Blobs DB >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- ERROR: Cannot create Blobs DB. Aborting. >> "%PlexData%\DBRepair.log"
exit /b 5 exit /b 5
) )
echo %time% -- Verifying Blobs DB echo %time% -- Verifying Blobs DB
echo %time% -- Verifying Blobs DB >> "%PlexData%\PlexDBRepair.log" echo %time% -- Verifying Blobs DB >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Blobs DB verification check is: %Result% >> "%PlexData%\DBRepair.log"
if not "%Result%" == "ok" ( if not "%Result%" == "ok" (
echo %time% -- ERROR: Blobs DB verificaion failed. Exiting. echo %time% -- ERROR: Blobs DB verification failed. Exiting.
echo %time% -- ERROR: Blobs DB verificaion failed. Exiting. >> "%PlexData%\PlexDBRepair.log" echo %time% -- ERROR: Blobs DB verification failed. Exiting. >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Blobs DB verification successful. >> "%PlexData%\DBRepair.log"
echo %time% -- Import and verification complete. echo %time% -- Import and verification complete.
echo %time% -- Import and verification complete. >> "%PlexData%\PlexDBRepair.log" echo %time% -- Import and verification complete. >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Reindexing Main DB >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Reindexing Blobs DB >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Reindexing complete. >> "%PlexData%\DBRepair.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%\PlexDBRepair.log" echo %time% -- Moving current DBs to DBTMP and making new databases active >> "%PlexData%\DBRepair.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"
@@ -139,9 +192,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%\PlexDBRepair.log" echo %time% -- Database repair/rebuild/reindex completed. >> "%PlexData%\DBRepair.log"
echo %time% -- ====== Session completed. ====== echo %time% -- ====== Session completed. ======
echo %time% -- ====== Session completed. ====== >> "%PlexData%\PlexDBRepair.log" echo %time% -- ====== Session completed. ====== >> "%PlexData%\DBRepair.log"
exit /b exit /b
@@ -152,5 +205,5 @@ REM Output - Write text to the console and the log file
:Output :Output
echo %time% %~1 echo %time% %~1
echo %time% %~1 >> "%PlexData%\PlexDBRepair.log" echo %time% %~1 >> "%PlexData%\DBRepair.log"
exit /B exit /B

View File

@@ -0,0 +1,904 @@
#########################################################################
# Database check and repair utility script for Plex Media Server #
# #
#########################################################################
$DBRepairVersion = 'v1.01.02'
class DBRepair {
[DBRepairOptions] $Options
[string] $PlexDBDir # Path to Plex's Databases directory
[string] $PlexCache # Path to the PhotoTranscoder directory
[string] $PlexSQL # Path to 'Plex SQLite.exe'
[string] $Timestamp # Timestamp used for temporary database files
[string] $LogFile # Path of our log file
[string] $Version # Current script version
[string] $Stage # Current stage of the script (e.g. "Auto", "Prune", etc.)
[bool] $IsError # Whether we're currently in an error state
[string] $MainDB = "com.plexapp.plugins.library.db"
[string] $BlobsDB = "com.plexapp.plugins.library.blobs.db"
DBRepair($Arguments, $Version) {
$this.Options = [DBRepairOptions]::new()
$this.Version = $Version
$this.IsError = $false
$Commands = $this.PreprocessArgs($Arguments)
if ($null -eq $Commands) {
return
}
if (!$this.Init()) {
Write-Host "Unable to initialize script, cannot continue."
return
}
$this.PrintHeader($true)
$this.MainLoop($Commands)
}
[void] PrintHeader([boolean] $WriteToLog) {
$OS = [System.Environment]::OSVersion.Version
if ($WriteToLog) {
$this.WriteLog("============================================================")
$this.WriteLog("Session start: Host is Windows $($OS.Major) (Build $($OS.Build))")
}
Write-Host "`n"
Write-Host " Database Repair Utility for Plex Media Server (Windows $($OS.Major), Build $($OS.Build))"
Write-Host " Version $($this.Version) "
Write-Host
}
[void] PrintHelp() {
# -Help doesn't write to the log, since our log file path isn't set.
$this.PrintHeader($false)
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 "provide them directly to the script, e.g. '.\DBRepair-Windows.ps1 Stop Prune Start Exit'"
Write-Host
$this.PrintOptions("Main Options")
Write-Host
Write-Host "Extra Options - These can only be specified once (last one wins)"
Write-Host
Write-Host " -CacheAge [int] - The date cutoff for pruned images. Defaults to pruning images over 30"
Write-Host " days old."
Write-Host
}
[void] PrintMenu() {
$this.PrintOptions("Select")
}
[void] PrintOptions([string]$Header) {
# NOTE: While Windows only supports a subset of DBRepair.sh's features, keep the command
# numbers the same as we attempt to reach feature parity
Write-Host
Write-Host $Header
Write-Host
Write-Host " 1 - 'stop' - Stop PMS."
Write-Host " 2 - 'automatic' - Check, Repair/Optimize, and Reindex Database in one step."
Write-Host
Write-Host " 7 - 'start' - Start PMS"
Write-Host
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 " 98 - 'quit' - Quit immediately. Keep all temporary files."
Write-Host " 99 'exit' - Exit with cleanup options."
Write-Host
Write-Host " 'menu x' - Show this menu in interactive mode, where x is on/off/yes/no"
}
# Do initial parsing of arguments that aren't part of the loop, returning
# the list of arguments that _should_ be processed in the loop.
#
# E.g. given "Stop Prune CacheAge 20 Start", this function will set the CacheAge
# to 20, and return "Stop Prune Start"
[System.Collections.ArrayList] PreprocessArgs([string[]] $Arguments) {
$FinalArgs = [System.Collections.ArrayList]::new()
for ($i = 0; $i -lt $Arguments.Count; ++$i) {
switch -Regex ($Arguments[$i]) {
'^-?(H(elp)?|\?)$' {
if ($Arguments.Count -gt 1) {
Write-Warning "Found -Help, ignoring extra arguments"
}
$this.PrintHelp()
return $null
}
'^-?CacheAge$' {
if ($i -eq $Arguments.Count - 1) {
Write-Warning "Found -CacheAge argument, but no value. Using default of 30 days"
Break
}
++$i
$Age = $Arguments[$i]
if (!($Age -match "^\d+$")) {
Write-Warning "Invalid -CacheAge value '$Age'. Using default of 30 days"
Break
}
$this.Options.CacheAge = [int]$Age
}
Default { $FinalArgs.Add($_) }
}
}
return $FinalArgs
}
# Setup variables required for this utility to work.
[bool] Init() {
$this.Timestamp = Get-Date -Format HH-mm-ss
$AppData = $this.GetAppDataDir()
$Success = $this.GetPlexDBDir($AppData) -and $this.GetPlexSQL() -and $this.GetPhotoTranscoderDir($AppData)
if ($Success) {
$this.LogFile = Join-Path $this.PlexDBDir -ChildPath "DBRepair.log"
}
return $Success
}
# Core routine that loops over all provided commands and executes them in order.
[void] MainLoop([System.Collections.ArrayList] $Arguments) {
$this.Options.Scripted = $Arguments.Count -ne 0
$i = 0
$Argc = $Arguments.Count
$NullInput = 0
$EOFExit = $false
while ($true) {
$Choice = $null
if ($this.Options.Scripted) {
if ($i -eq $Argc) {
$Choice = "exit"
} else {
$Choice = $Arguments[$i++]
}
} else {
if ($this.Options.ShowMenu) {
$this.PrintMenu()
}
Write-Host
$Choice = Read-Host "Enter command # -or- command name (4 char min)"
if ($Choice -eq "") {
++$NullInput
if ($NullInput -eq 5) {
$this.Output("Unexpected EOF / End of command line options. Exiting. Keeping temp files. ")
$Choice = "exit"
$EOFExit = $true
} else {
if ($NullInput -eq 4) {
Write-Warning "Next empty command exits as EOF. "
}
continue
}
} else {
$NullInput = 0
}
}
# Update timestamp
$this.Timestamp = Get-Date -Format 'yyyy-MM-dd_HH.mm.ss'
switch -Regex ($Choice) {
"^(1|stop)$" { $this.DoStop() }
"^(2|autom?a?t?i?c?)$" {
$this.SetStage("Auto")
$this.IsError = !$this.RunAutomaticDatabaseMaintenance()
}
"^(7|start?)$" { $this.StartPMS() }
"^(21|(prune?|remov?e?))$" {
$this.SetStage("Prune")
$this.PrunePhotoTranscoderCache()
}
"^(42|ignor?e?|honor?)$" {
if (($this.Options.IgnoreErrors -and ($Choice[0] -eq 'i')) -or (!$this.Options.IgnoreErrors -and ($Choice[0] -eq 'h'))) {
Write-Host "Honor/Ignore setting unchanged."
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.WriteEnd()
return
}
"^(99|exit)$" {
if ($EOFExit) {
$this.Output("Unexpected exit command. Keeping all temporary work files.")
$this.WriteLog("EOFExit - Retain temp files.")
return
}
# If our last DB operation failed, we don't want to automatically delete
# temporary files when in scripted mode.
if ($this.IsError -and $this.Options.Scripted) {
$this.Output("Exiting with errors. Keeping all temporary work files.")
$this.WriteLog("Exit - Retain temp files.")
return
}
$this.CleanDBTemp(!$this.Options.Scripted)
$this.WriteEnd()
return
}
"^menu\b" {
$Match = $Choice -match "^menu\s+(on|off|yes|no)"
if (!$Match) {
$this.OutputWarn("Invalid 'menu' format. Expected 'menu on/off/yes/no', got '$Choice'")
Break
}
$TurnOn = ($Matches.1 -eq 'on') -or ($Matches.1 -eq 'yes');
$this.Options.ShowMenu = $TurnOn
if (!$TurnOn) {
Write-Host "Menu off: Reenable with 'menu on' command"
}
}
Default {
$this.OutputWarn("Unknown Command: '$Choice'")
$this.WriteLog("Unknown command: '$Choice'")
}
}
}
}
# Attempt to stop Plex Media Server if it's running
[void] DoStop() {
$this.WriteLog("Stop - START")
$PMS = $this.GetPMS()
if ($null -eq $PMS) {
$this.Output("PMS already stopped.")
return
}
$this.Output("Stopping PMS.")
# Plex doesn't respond to CloseMainWindow because it doesn't have a window,
# and Stop-Process does a forced exit of the process, so use taskkill to ask
# PMS to close nicely, and bail if that doesn't work.
$ErrorText = $null
Invoke-Expression "taskkill /im ""Plex Media Server.exe""" 2>$null -ErrorVariable ErrorText
if ($ErrorText) {
$this.WriteOutputLogWarn("Failed to send terminate signal to PMS, please stop manually.")
$this.WriteOutputLogWarn($ErrorText -join "`n")
return
}
$PMS.WaitForExit(30000) *>$null # Wait at most 30 seconds for PMS to close. If it still hasn't by then, bail.
if ($PMS.HasExited) {
$this.WriteLog("Stop - PASS")
$this.Output("Stopped PMS.")
return
}
$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
[void] StartPMS() {
$this.WriteLog("Start - START")
if ($this.PMSRunning()) {
$this.Output("Start not needed. PMS is running.")
$this.WriteLog("Start - PASS - PMS is already running")
return
}
$PMS = Join-Path (Split-Path -Parent $this.PlexSQL) -ChildPath "Plex Media Server.exe"
try {
Start-Process $PMS -EA Stop
$this.Output("Started PMS")
$this.WriteLog("Start - PASS")
} catch {
$Err = $Error -join "`n"
$this.OutputWarn("Could not start PMS: $Err")
$Error.Clear()
}
}
# All-in-one database utility - Repair/Check/Reindex
[bool] RunAutomaticDatabaseMaintenance() {
$this.Output("Automatic Check,Repair,Index started.")
$this.WriteLog($this.StageLog("START"))
if ($this.PMSRunning()) {
$this.WriteLog($this.StageLog("FAIL - PMS running"))
$this.OutputWarn("Unable to run automatic sequence. PMS is running. Please stop PlexMediaServer.")
return $false
}
# Create temporary backup directory
$DBTemp = Join-Path $this.PlexDBDir -ChildPath "dbtmp"
if (!$this.DirExists($DBTemp)) {
$TempDirError = $null
New-Item -Path $DBTemp -ItemType "directory" -ErrorVariable tempDirError *>$null
if ($TempDirError) {
$this.ExitDBMaintenance("Unable to create temporary database directory", $false)
return $false
}
}
$this.Output("Exporting Main DB")
$MainDBPath = Join-Path $this.PlexDBDir -ChildPath $this.MainDB
$MainDBSQL = Join-Path $DBTemp -ChildPath "library.sql_$($this.TimeStamp)"
if (!$this.FileExists($MainDBPath)) {
$this.ExitDBMaintenance("Could not find $($this.MainDB) in database directory", $false)
return $false
}
if (!$this.ExportPlexDB($MainDBPath, $MainDBSQL)) { return $false }
$this.Output("Exporting Blobs DB")
$BlobsDBPath = Join-Path $this.PlexDBDir -ChildPath $this.BlobsDB
$BlobsDBSQL = Join-Path $DBTemp -ChildPath "blobs.sql_$($this.Timestamp)"
if (!$this.FileExists($BlobsDBPath)) {
$this.ExitDBMaintenance("Could not find $($this.BlobsDB) in database directory", $false)
return $false
}
if (!$this.ExportPlexDB($BlobsDBPath, $BlobsDBSQL)) { return $false }
$this.Output("Successfully exported the main and blobs databases. Proceeding to import into new database.")
$this.WriteLog("Repair - Export databases - PASS")
# Make sure Plex hasn't been started while we were exporting
if (!$this.CheckPMS("export")) { return $false }
$this.Output("Importing Main DB.")
$MainDBImport = Join-Path $this.PlexDBDir -ChildPath "$($this.MainDB)_$($this.Timestamp)"
if (!$this.ImportPlexDB($MainDBSQL, $MainDBImport)) { return $false }
$this.Output("Importing Blobs DB.")
$BlobsDBImport = Join-Path $this.PlexDBDir -ChildPath "$($this.BlobsDB)_$($this.Timestamp)"
if (!$this.ImportPlexDB($BlobsDBSQL, $BlobsDBImport)) { return $false }
$this.Output("Successfully imported databases.")
$this.WriteLog("Repair - Import - PASS")
$this.Output("Verifying databases integrity after importing.")
if (!$this.IntegrityCheck($MainDBImport, "Main")) { return $false }
$this.Output("Verification complete. PMS main database is OK.")
$this.WriteLog("Repair - Verify main database - PASS")
if (!$this.IntegrityCheck($BlobsDBImport, "Blobs")) { return $false }
$this.Output("Verification complete. PMS blobs database is OK.")
$this.WriteLog("Repair - Verify blobs database - PASS")
if (!$this.CheckPMS("import")) { return $false }
# Import complete, now reindex
$this.WriteOutputLog("Reindexing Main DB")
if (!$this.RunSQLCommand("""$MainDBImport"" ""REINDEX;""", "Failed to reindex Main DB")) { return $false }
$this.WriteOutputLog("Reindexing Blobs DB")
if (!$this.RunSQLCommand("""$BlobsDBImport"" ""REINDEX;""", "Failed to reindex Blobs DB")) { return $false }
$this.WriteOutputLog("Reindexing complete.")
$this.WriteOutputLog("Moving current DBs to DBTMP and making new databases active")
if (!$this.CheckPMS("new database copy")) { return $false }
try {
$this.MoveDatabase($MainDBPath, (Join-Path $DBTemp -ChildPath "$($this.MainDB)_$($this.Timestamp)"), "move Main DB to DBTMP")
$this.MoveDatabase($MainDBImport, $MainDBPath, "replace Main DB with rebuilt DB")
$this.MoveDatabase($BlobsDBPath, (Join-Path $DBTemp -ChildPath "$($this.BlobsDB)_$($this.Timestamp)"), "move Blobs DB to DBTMP")
$this.MoveDatabase($BlobsDBImport, $BlobsDBPath, "replace Blobs DB with rebuilt DB")
} catch {
$Error.Clear()
return $false
}
$this.ExitDBMaintenance("Database repair/rebuild/reindex completed.", $true)
return $true
}
# Return whether we can continue DB repair (i.e. whether PMS is running) at the given stage in the process.
[bool] CheckPMS([string] $SubStage) {
if ($this.PMSRunning()) {
$SubMessage = if ($SubStage) { "during $SubStage" } else { "" }
$this.WriteLog($this.StageLog("FAIL - PMS running $SubMessage"))
$this.OutputWarn("Unable to run $($this.Stage.TrimEnd()). PMS is running. Please stop PlexMediaServer.")
return $false
}
return $true
}
# Try to move the source file to the destination. If it fails, attempt to find
# open file handles (requires handle.exe on PATH) and throw.
[void] MoveDatabase([string] $Source, [string] $Destination, [string] $FriendlyString) {
$MoveError = $null
Move-Item -Path $Source -Destination $Destination -ErrorVariable MoveError *>$null
if ($MoveError) {
$this.ExitDBMaintenance("Unable to $($FriendlyString): $MoveError", $false)
throw "Unable to move database"
}
}
# Attempts to prune PhotoTranscoder images that are older than the specified date cutoff (30 days by default)
[void] PrunePhotoTranscoderCache() {
$this.WriteLog($this.StageLog("START"))
if ($this.PMSRunning()) {
$this.OutputWarn("Unable to prune Phototranscoder cache. PMS is running.")
$this.WriteLog($this.StageLog("FAIL - PMS running"))
return
}
$Cutoff = $this.Options.CacheAge
$ShouldPrune = $this.Options.Scripted
if (!$ShouldPrune) {
$this.Output("Counting how many files are more than $Cutoff days old")
$CacheResult = $this.CheckPhotoTranscoderCache($true)
$Prunable = $CacheResult.PrunableFiles
$SpaceSaved = $CacheResult.SpaceSavings
if ($Prunable -eq 0) {
$this.Output("No files found to prune.")
$this.WriteLog($this.StageLog("PASS (no files found to prune)"))
return
}
$ShouldPrune = $this.GetYesNo("OK to prune $Prunable files ($SpaceSaved)")
}
if ($ShouldPrune) {
$this.Output("Pruning started.")
$PruneResult = $this.CheckPhotoTranscoderCache($false)
$Pruned = $PruneResult.PrunableFiles
$Total = $PruneResult.TotalFiles
$Saved = $PruneResult.SpaceSavings
$this.WriteOutputLog($this.StageLog("Removed $Pruned files over $Cutoff days old ($Saved), out of $Total total files"))
$this.Output("Pruning completed.")
} else {
$this.WriteOutputLog($this.StageLog("Prune cancelled by user"))
}
$this.WriteLog($this.StageLog("PASS"))
}
# Traverses PhotoTranscoder cache to find and delete files older than the specified max age.
# If $DryRun is $true, don't remove items, just gather statistics.
[CleanCacheResult] CheckPhotoTranscoderCache([bool] $DryRun) {
$Cutoff = (Get-Date).AddDays(-$this.Options.CacheAge);
$AllFiles = 0;
$OldFiles = 0;
$FreedBytes = 0;
Get-ChildItem -Path $this.PlexCache -Recurse -File |
Where-Object { $_.extension -in '.jpg','.jpeg','.png','.ppm' } |
ForEach-Object {
$AllFiles++;
if ($_.LastWriteTime -lt $Cutoff) {
$OldFiles++;
$FreedBytes += $_.Length;
if (!$DryRun) {
Remove-Item $_.FullName;
}
}
};
return [CleanCacheResult]::new($AllFiles, $OldFiles, $FreedBytes)
}
### Helpers ###
### Logging Helpers ###
[string] Now() { return Get-Date -Format 'yyyy-MM-dd HH.mm.ss' }
# Write the given text to the console
[void] Output([string] $Text) {
if ($this.Options.Scripted) {
Write-Host "$($this.Now()) $Text"
} else {
Write-Host $Text
}
}
# Write the given text as a warning in the console
[void] OutputWarn([string] $Text) {
if ($this.Options.Scripted) {
Write-Warning "$($this.Now()) $Text"
} else {
Write-Warning $Text
}
}
# Write the given text to the log file
[void] WriteLog([string] $Text) {
Add-Content -Path $this.LogFile -Value "$($this.Now()) -- $($Text)"
}
# Write the given text to the log file and console
[void] WriteOutputLog([string] $Text) {
$this.WriteLog($Text)
$this.Output($Text)
}
# Write the given text to the log file and as warning text in the console
[void] WriteOutputLogWarn([string] $Text) {
$this.WriteLog($Text)
$this.OutputWarn($Text)
}
# Write out the end of the session
[void] WriteEnd() {
$this.WriteLog("Session end. $(Get-Date)")
$this.WriteLog("============================================================")
}
# Set the current stage (with the right amount of padding)
[void] SetStage([string] $Stage) {
$this.Stage = $Stage + (" " * [math]::Max(0, 8 - $Stage.Length))
}
# Prepend the current stage to the given text
[string] StageLog([string] $text) {
return "$($this.Stage) - $text"
}
### File Helpers ###
# Check whether the given directory exists (and is a directory)
[bool] DirExists([string] $Dir) {
if ($Dir) {
return Test-Path $Dir -PathType Container
}
return $false
}
# Check whether the given file exists (and is a file)
[bool] FileExists([string] $File) {
if ($File) {
return Test-Path $File -PathType Leaf
}
return $false
}
### Setup Helpers ###
# Retrieve Plex's data directory, exiting the script on failure
[string] GetAppDataDir() {
$PMSRegistry = $this.GetHKCU()
$PlexAppData = $PMSRegistry.LocalAppDataPath
if ($PlexAppData) {
$PlexAppData = Join-Path -Path $PlexAppData -ChildPath "Plex Media Server"
}
if ($this.DirExists($PlexAppData)) {
return $PlexAppData
}
$PlexAppData = "$env:LOCALAPPDATA\Plex Media Server"
if ($this.DirExists($PlexAppData)) {
return $PlexAppData
}
Write-Host "Could not determine Plex data directory, cannot continue"
Write-Host "Normally $env:LOCALAPPDATA\Plex Media Server"
exit
}
# Retrieve PMS settings under HKEY_CURRENT_USER, exiting the script on failure
[PSCustomObject] GetHKCU() {
try {
return (Get-ItemProperty -path 'HKCU:\Software\Plex, Inc.\Plex Media Server' -EA Stop)
} 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?"
exit
}
}
# Set the Plex database directory, returning whether we found the directory
[bool] GetPlexDBDir([string] $AppData) {
$DBDir = Join-Path -Path $AppData -ChildPath "Plug-in Support\Databases"
if ($this.DirExists($DBDir)) {
$this.PlexDBDir = $DBDir;
return $true;
}
Write-Host "Could not find Databases folder, cannot continue."
Write-Host "Normally $DBDir"
return $false
}
# Set the path to Plex's PhotoTranscoder cache, returning whether we found the directory.
[bool] GetPhotoTranscoderDir([string] $AppData) {
$CacheDir = Join-Path -Path $AppData -ChildPath "Cache\PhotoTranscoder"
if ($this.DirExists($CacheDir)) {
$this.PlexCache = $CacheDir
return $true
}
Write-Host "Could not find PhotoTranscoder path, cannot prune."
Write-Host "Normally $CacheDir"
return $false
}
# Find the path to Plex SQLite.exe, falling back to user input if necessary.
[bool] GetPlexSQL() {
$PMSRegistry = $this.GetHKCU()
$InstallDir = $PMSRegistry.InstallFolder
if (!$InstallDir) {
# Install location might also be in HKLM
$InstallDir = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Plex, Inc.\Plex Media Server' -EA Ignore).InstallFolder
if (!$InstallDir) {
# Final registry attempt - WOW6432Node
$InstallDir = (Get-ItemProperty -path 'HKLM:\SOFTWARE\WOW6432Node\Plex, Inc.\Plex Media Server' -EA Ignore).InstallFolder
}
}
$SQL = if ($InstallDir) { Join-Path -Path $InstallDir -ChildPath "Plex SQLite.exe" } else { $null }
if ($this.FileExists($SQL)) {
$this.PlexSQL = $SQL
return $true
}
# Still couldn't find install directory. Try standard PROGRAMFILES variables
$SQL = "$env:PROGRAMFILES\Plex\Plex Media Server\Plex SQ Lite.exe"
if ($this.FileExists($SQL)) {
$this.PlexSQL = $SQL
return $true
}
if (${env:PROGRAMFILES(X86)}) {
$SQL = "${env:PROGRAMFILES(X86)}\Plex Plex Media Server\Plex SQLite.exe"
if ($this.FileExists($SQL)) {
Write-Host "Note: 32-bit version of PMS detected on a 64-bit version of Windows. Using the 64-bit release of PMS is recommended."
$this.PlexSQL = $SQL
return $true
}
}
Write-Host "Could not determine Plex SQLite location. Please provide it below"
Write-Host "Normally $env:PORGRAMFILES\Plex\Plex Media Server\Plex SQLite.exe"
$First = $true
while (!$this.FileExists($SQL)) {
if (!$First) {
Write-Host "ERROR: '$SQL' could not be found"
}
$First = $false
$SQL = Read-Host -Prompt "Path to Plex SQLite.exe (Ctrl+C to cancel): "
}
$this.PlexSQL = $SQL
return $true
}
### Database Helpers ###
# Writes to output/log when we're done with database maintenance (on success or failure)
[void] ExitDBMaintenance([string] $Message, [boolean] $Success) {
if ($Success) {
$this.Output("Automatic Check,Repair,Index succeeded.")
$this.WriteLog($this.StageLog("PASS"))
} else {
$this.OutputWarn("Database maintenance failed - $Message")
$this.WriteLog($this.StageLog("$Message, cannot continue."))
$this.WriteLog($this.StageLog("FAIL"))
}
}
[bool] ExportPlexDB([string] $Source, [string] $Destination) {
return $this.RunSQLCommand("""$Source"" "".output '$Destination'"" .dump", "Failed to export '$Source' to '$Destination'")
}
# Run an SQL command.
# ErrorMessage is the message to output/write to the log on failure
[bool] RunSQLCommand([string] $Command, [string] $ErrorMessage) {
return $this.RunSQLCommandCore($Command, $ErrorMessage, $null)
}
# Run an SQL command and retrieve the output of said command
# ErrorMessage is the message to output/write to the log on failure
[bool] GetSQLCommandResult([string] $Command, [string] $ErrorMessage, [ref] $Output) {
return $this.RunSQLCommandCore($Command, $ErrorMessage, $Output)
}
# Run a 'Plex SQLite' command
[bool] RunSQLCommandCore([string] $Command, [string] $ErrorMessage, [ref] $Output) {
$SqlError = $null
$SqlResult = $null
$ExitCode = 0
try {
Invoke-Expression "& ""$($this.PlexSQL)"" $Command" -ev sqlError -OutVariable sqlResult -EA Stop *>$null
$ExitCode = $LASTEXITCODE
} catch {
$Err = $Error -join "`n"
$this.ExitDBMaintenance("Failed to run command '$Command': '$Err'", $false)
$Error.Clear()
return $false
}
if ($SqlError -or $ExitCode) {
$Err = $SqlError -join "`n"
if (!$Err) { $Err = "Process exited with error code $ExitCode" }
$Msg = $ErrorMessage
if (!$Msg) {
$Msg = "Plex SQLite operation failed"
}
if ($this.Options.IgnoreErrors -and $this.Options.CanIgnore) {
$this.OutputWarn("Ignoring database errors - ${Msg}: $Err")
} else {
$this.ExitDBMaintenance("${Msg}: $Err", $false)
return $false
}
}
if ($null -ne $Output.Value) {
$Output.Value = $SqlResult
}
return $true
}
# Import an exported .sql file into a new database
[bool] ImportPlexDB($Source, $Destination) {
# SQLite's .read can't handle files larger than 2GB on versions <3.45.0 (https://sqlite.org/forum/forumpost/9af57ba66fbb5349),
# and Plex SQLite is currently on 3.39.4 (as of PMS 1.41.6).
# If the source is smaller than 2GB we can .read it directly, otherwise do things in a more roundabout way.
if ($this.FileExists($Source) -and (Get-Item $Source).Length -lt 2GB) {
return $this.RunSQLCommand("""$Destination"" "".read '$Source'""", "Failed to import Plex database (importing '$Source' into '$Destination')")
}
$ImportError = $null
$ExitCode = 0
$Err = $null
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.
$process = Start-Process $this.PlexSQL -ArgumentList @("""$Destination""") -RedirectStandardInput $Source -NoNewWindow -Wait -PassThru -EA Stop -ErrorVariable ImportError
$ExitCode = $process.ExitCode
} catch {
$Err = $Error -join "`n"
$Error.Clear()
}
if ($ImportError) {
$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)
return $false
}
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.
[void] CleanDBTemp([bool] $Confirm) {
if ($Confirm -and !$this.GetYesNo("Ok to remove temporary databases/workfiles for this session")) {
$this.Output("Retaining all temporary work files.")
$this.WriteLog("Exit - Retain temp files.")
return
}
$DBTemp = Join-Path $this.PlexDBDir -ChildPath "dbtmp"
if ($this.DirExists($DBTemp)) {
try {
Remove-Item $DBTemp -Recurse -Force -EA Stop
$this.Output("Deleted all temporary work files.")
$this.WriteLog("Exit - Deleted temp files.")
} catch {
$Err = $Error -join "`n"
$this.OutputWarn("Failed to remove temporary directory: $Err")
$this.WriteLog("Exit - Failed to remove temporary files: $Err")
$Error.Clear()
}
}
}
### Miscellaneous Helpers ###
# Return whether PMS is running
[bool] PMSRunning() {
return $null -ne $this.GetPMS()
}
# Retrieve the PMS process, if running
[System.Diagnostics.Process] GetPMS() {
return Get-Process -EA Ignore -Name "Plex Media Server"
}
# Ask the user a yes or no question, continuing to prompt them until
# their input starts with either a 'Y' or 'N'
[bool] GetYesNo([string] $Prompt) {
$Response = (Read-Host "$Prompt [Y/N]? ").ToLower()
$Ch = $Response.Substring(0, [Math]::Min($Response.Length, 1))
while (($Ch -ne "y") -and ($Ch -ne "n")) {
Write-Host "Invalid input, please enter [Y]es or [N]o"
$Response = (Read-Host "$Prompt [Y/N]? ").ToLower()
$Ch = $Response.Substring(0, [Math]::Min($Response.Length, 1))
}
return $Ch -eq "y"
}
}
# Contains miscellaneous options/state over the course of a session.
class DBRepairOptions {
[bool] $Scripted # Whether we're running in scripted or interactive mode
[bool] $ShowMenu # Whether to show the menu after each command executes
[bool] $IgnoreErrors # Whether to honor or ignore constraint errors on import
[bool] $CanIgnore # Some errors can't be ignored (e.g. integrity_check)
[int32] $CacheAge # The date cutoff for pruning PhotoTranscoder cached images
DBRepairOptions() {
$this.CacheAge = 30
$this.ShowMenu = $true
$this.Scripted = $false
$this.IgnoreErrors = $false
$this.CanIgnore = $true
}
}
# Contains relevant data about a PhotoTranscoder `prune` attempt
class CleanCacheResult {
[int32] $TotalFiles # Total number of PhotoTranscoder files
[int32] $PrunableFiles # Total number of files that are older than the cutoff
[string] $SpaceSavings # Friendly string of (potential) space savings
CleanCacheResult([int32] $TotalFiles, [int32] $PrunableFiles, [int32] $PrunableBytes) {
$this.TotalFiles = $TotalFiles
$this.PrunableFiles = $PrunableFiles
$this.SpaceSavings = "$($PrunableBytes) bytes"
if ($PrunableBytes -gt 1GB) {
$this.SpaceSavings = "$([math]::round($PrunableBytes / 1GB, 2)) GiB";
} elseif ($PrunableBytes -gt 1MB) {
$this.SpaceSavings = "$([math]::round($PrunableBytes / 1MB, 2)) MiB";
} elseif ($PrunableBytes -gt 1KB) {
$this.SpaceSavings = "$([math]::round($PrunableBytes / 1KB, 2)) KiB";
}
}
}
# Ensure the console can handle utf-8, as the export process pipes utf-8 data from the console to our temporary sql file.
$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

Binary file not shown.

76
Windows/README-Windows.md Normal file
View File

@@ -0,0 +1,76 @@
# 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

@@ -0,0 +1,33 @@
# 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