DBRepair development

Sorry about that.

  1. The code itself is updated to v.1.16.00
    (both /Applications and /Users/<name>/Applications supported.

  2. I changed everything but the 'Version =" string in the file itself.
    (Doooh! )

  3. v1.16.00 updated an reissued.

Thanks for letting me know.
C.

On related topic:

I’m doing a lot of work on the new code (as time/health permits)

It can check my DBs in seconds. It is I/O speed limited for the most part.

Here, this is a quick sample of where I’m at (and you can see my debugging info)

chuck@tirol dbrepair % 
chuck@tirol dbrepair % build/pc-darwin-arm64-release/bin/DBRepair check config exit
SYSTEM: macOS,(MacOS)
ENGINE: SQLite v3.53.0
STEEL:  ICU Headers LINKED
[Smoke Test Complete]
Binary Architecture: 64-bit




      Database Repair Utility for Plex Media Server  (MacOS)
                       Version 0.1999.01

[2026-06-27 13.04.46]  
[2026-06-27 13.04.46] Checking the PMS databases...
[2026-06-27 13.04.46]   FTS shadow table missing: 'fts4_metadata_titles_content' in /Users/chuck/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db
[2026-06-27 13.04.46] Check complete. PMS main database is damaged.
[2026-06-27 13.04.46]   FTS shadow table missing: 'fts4_metadata_titles_content' in /Users/chuck/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.blobs.db
[2026-06-27 13.04.46] Check complete. PMS blobs database is damaged.
[2026-06-27 13.04.46] 
[2026-06-27 13.04.46] 
[2026-06-27 13.04.46] NOTE: FTS indexes are damaged but main database structure is OK.
[2026-06-27 13.04.46]       Use 'reindex' (option 6) or 'automatic' (option 2) to rebuild.
[2026-06-27 13.04.46]  
[2026-06-27 13.04.46] 
--- [ DBRepair: Host Configuration Dump ] ---

[2026-06-27 13.04.46]   Version:            [0.1999.01]
[2026-06-27 13.04.46]   Host Type:          [MacOS]
[2026-06-27 13.04.46]   Distro Name:        [macOS]
[2026-06-27 13.04.46]   Time Stamp:         [2026-06-27_13.04.46]
[2026-06-27 13.04.46]   Last User:          [None]
[2026-06-27 13.04.46]   Last Run:           [Never]
[2026-06-27 13.04.46] 
[2026-06-27 13.04.46]   Manual Config:      No
[2026-06-27 13.04.46]   Root Required:      No
[2026-06-27 13.04.46]   Scripted Mode:      Yes
[2026-06-27 13.04.46]   Ignore Errors:      No
[2026-06-27 13.04.46]   Checked DB:         Yes
[2026-06-27 13.04.46]   Damaged:            Yes
[2026-06-27 13.04.46]   Main Damaged:       No
[2026-06-27 13.04.46]   Blobs Damaged:      No
[2026-06-27 13.04.46]   Checked FTS:        No
[2026-06-27 13.04.46]   FTS Damaged:        Yes
[2026-06-27 13.04.46]   Remove Duplicates:  No
[2026-06-27 13.04.46]   Fail Status:        No
[2026-06-27 13.04.46] 
[2026-06-27 13.04.46]   Owner UID/GID:      501:20
[2026-06-27 13.04.46]   Default Perms:      0644
[2026-06-27 13.04.46]   Stat Format:        [-f]
[2026-06-27 13.04.46]   Stat Bytes:         [%z]
[2026-06-27 13.04.46]   Stat Perms:         [%Lp]
[2026-06-27 13.04.46] 
[2026-06-27 13.04.46]   Package Dir:        [/Users/chuck/Applications/Plex Media Server.app]
[2026-06-27 13.04.46]   SQLite Version:     [3.53.0]
[2026-06-27 13.04.46]   App Support Dir:    [/Users/chuck/Library/Application Support]
[2026-06-27 13.04.46]   Database Dir:       [/Users/chuck/Library/Application Support/Plex Media Server/Plug-in Support/Databases]
[2026-06-27 13.04.46]   Database Temp Dir:  [/Users/chuck/Library/Application Support/Plex Media Server/Plug-in Support/Databases/dbtmp]
[2026-06-27 13.04.46]   Main DB Path:       [/Users/chuck/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db]
[2026-06-27 13.04.46]   Blobs DB Path:      [/Users/chuck/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.blobs.db]
[2026-06-27 13.04.46]   Cache Dir:          [/Users/chuck/Library/Caches/PlexMediaServer/PhotoTranscoder]
[2026-06-27 13.04.46]   Log File:           [/Users/chuck/Library/Application Support/Plex Media Server/Plug-in Support/Databases/DBRepair.log]
[2026-06-27 13.04.46]   Pid File:           []
[2026-06-27 13.04.46]   Temp Dir (Local):   [/tmp]
[2026-06-27 13.04.46]   System Temp:        [/tmp]
[2026-06-27 13.04.46] 
[2026-06-27 13.04.46]   Script Name:        []
[2026-06-27 13.04.46]   Script Path:        []
[2026-06-27 13.04.46]   Working Dir:        []
[2026-06-27 13.04.46] 
[2026-06-27 13.04.46]   Pidof Utility:      [pgrep]
[2026-06-27 13.04.46]   FTS Query:          [SELECT name FROM sqlite_master WHERE sql LIKE '%FTS%';]
[2026-06-27 13.04.46]   Have Start/Stop:    (Yes)
[2026-06-27 13.04.46]   Start Command:      [TMPDIR=/tmp osascript -e 'tell app "Plex Media Server" to launch']
[2026-06-27 13.04.46]   Stop Command:       [TMPDIR=/tmp osascript -e 'tell app "Plex Media Server" to quit']
[2026-06-27 13.04.46] ------------------------------------------------------
[2026-06-27 13.04.46] 
[2026-06-27 13.04.46]  
[2026-06-27 13.04.46] Deleting temporary work files.
chuck@tirol dbrepair %

Chuck, Windows? :grinning_face:

I do two things with Windows:

  1. Wash
  2. Break

:rofl:

It’s coming. First is to get the program running. This is a full cold rewrite.

Right now I have: MacOS (Intel and Armv8), Linux (Intel, Armv7, Armv8)

The code is written, and CLANG is (I think) ready to build for Windows.
I don’t have any Windows machines to test with .
I will get there.

That’s the spirit, Chuck. :+1:

Least I could do!

Watching the re-write with interest, thank you for all your efforts, it is appreciated!

Edit - raw DBRepair.sh script is now “correct” 1.16.00, but copy inside source.zip still says 1.15.00 as version …

:rofl:

  1. Open occasionally for fresh air?
  2. Run as a VM to check that it’s still as horrible as you remember it?

:rofl:

@StephenH

  1. WHY? That lets the dirt in? :scream: lol
  2. No need for a VM. I have known for a long time it’ll never change. :smiling_face_with_horns:

ALL:

I’m working on the FTS code today.

Below is both the config dump and updated CheckDB + FTSCheck code w/ output.

I know this is verbose and am willing to hide most of it behind a ‘-v’ (verbose) option flag.

I am sharing here to get everyone’s input because implementing Verbose, while a small change, touches every module in DBRepair.

I’m using a 1GB DB for development testing.

chuck@tirol src % time ../build/pc-darwin-arm64-release/bin/DBRepair --databases /Volumes/Samsung850/databases/ config check config quit
[2026-07-02 19.01.49] SYSTEM: macOS,(User Defined)
[2026-07-02 19.01.49] ENGINE: SQLite v3.53.0
[2026-07-02 19.01.49] STEEL:  ICU Headers LINKED
[2026-07-02 19.01.49] [Smoke Test Complete]
[2026-07-02 19.01.49] Binary Architecture: 64-bit

[2026-07-02 19.01.49] 


[2026-07-02 19.01.49]       Database Repair Utility for Plex Media Server  (User Defined)
[2026-07-02 19.01.49]                        Version 2.0.0

[2026-07-02 19.01.49]       SQLite     = '3.53.0'
[2026-07-02 19.01.49]       Databases  = '/Volumes/Samsung850/databases'
[2026-07-02 19.01.49]  
[2026-07-02 19.01.49] 
--- [ DBRepair: Host Configuration Dump ] ---

[2026-07-02 19.01.49]   Version:            [2.0.0]
[2026-07-02 19.01.49]   Host Type:          [User Defined]
[2026-07-02 19.01.49]   Distro Name:        [macOS]
[2026-07-02 19.01.49]   Time Stamp:         [2026-07-02_19.01.49]
[2026-07-02 19.01.49]   Last User:          [None]
[2026-07-02 19.01.49]   Last Run:           [Never]
[2026-07-02 19.01.49] 
[2026-07-02 19.01.49]   Manual Config:      Yes
[2026-07-02 19.01.49]   Root Required:      No
[2026-07-02 19.01.49]   Scripted Mode:      Yes
[2026-07-02 19.01.49]   Ignore Errors:      No
[2026-07-02 19.01.49]   Checked DB:         No
[2026-07-02 19.01.49]   Damaged:            No
[2026-07-02 19.01.49]   Main Damaged:       No
[2026-07-02 19.01.49]   Blobs Damaged:      No
[2026-07-02 19.01.49]   Checked FTS:        No
[2026-07-02 19.01.49]   FTS Damaged:        No
[2026-07-02 19.01.49]   Remove Duplicates:  No
[2026-07-02 19.01.49]   Fail Status:        No
[2026-07-02 19.01.49] 
[2026-07-02 19.01.49]   Owner UID/GID:      0:0
[2026-07-02 19.01.49]   Default Perms:      0644
[2026-07-02 19.01.49]   Stat Format:        [-c]
[2026-07-02 19.01.49]   Stat Bytes:         [%s]
[2026-07-02 19.01.49]   Stat Perms:         [%a]
[2026-07-02 19.01.49] 
[2026-07-02 19.01.49]   Package Dir:        []
[2026-07-02 19.01.49]   SQLite Version:     [3.53.0]
[2026-07-02 19.01.49]   App Support Dir:    []
[2026-07-02 19.01.49]   Database Dir:       [/Volumes/Samsung850/databases]
[2026-07-02 19.01.49]   Database Temp Dir:  [/Volumes/Samsung850/databases/dbtmp]
[2026-07-02 19.01.49]   Main DB Path:       [/Volumes/Samsung850/databases/com.plexapp.plugins.library.db]
[2026-07-02 19.01.49]   Blobs DB Path:      [/Volumes/Samsung850/databases/com.plexapp.plugins.library.blobs.db]
[2026-07-02 19.01.49]   Cache Dir:          []
[2026-07-02 19.01.49]   Log File:           []
[2026-07-02 19.01.49]   Pid File:           []
[2026-07-02 19.01.49]   Temp Dir (Local):   []
[2026-07-02 19.01.49]   System Temp:        []
[2026-07-02 19.01.49] 
[2026-07-02 19.01.49]   Script Name:        []
[2026-07-02 19.01.49]   Script Path:        []
[2026-07-02 19.01.49]   Working Dir:        []
[2026-07-02 19.01.49] 
[2026-07-02 19.01.49]   Sqlite3 Cache Size  [0]
[2026-07-02 19.01.49]   Pidof Utility:      [pidof]
[2026-07-02 19.01.49]   FTS Query:          [SELECT name FROM sqlite_master WHERE sql LIKE '%FTS%';]
[2026-07-02 19.01.49]   Have Start/Stop:    (No)
[2026-07-02 19.01.49]   Start Command:      []
[2026-07-02 19.01.49]   Stop Command:       []
[2026-07-02 19.01.49] ------------------------------------------------------
[2026-07-02 19.01.49] 
[2026-07-02 19.01.49]  
[2026-07-02 19.01.49] Checking the PMS databases...
[2026-07-02 19.01.50] Database is damaged: row 62 missing from index index_title_sort_icu
[2026-07-02 19.01.50]   Main DB: FTS shadow table missing: 'fts4_metadata_titles_content'
[2026-07-02 19.01.50]   Main DB: FTS shadow table missing: 'fts4_tag_titles_content'
[2026-07-02 19.01.50]   Main DB: FTS shadow table missing: 'fts4_metadata_titles_icu_content'
[2026-07-02 19.01.50]   Main DB: FTS shadow table missing: 'fts4_tag_titles_icu_content'
[2026-07-02 19.01.50] Check complete. PMS main database is damaged.
[2026-07-02 19.01.50]   Blobs DB: FTS shadow table missing: 'fts4_metadata_titles_content'
[2026-07-02 19.01.50]   Blobs DB: FTS shadow table missing: 'fts4_tag_titles_content'
[2026-07-02 19.01.50]   Blobs DB: FTS shadow table missing: 'fts4_metadata_titles_icu_content'
[2026-07-02 19.01.50]   Blobs DB: FTS shadow table missing: 'fts4_tag_titles_icu_content'
[2026-07-02 19.01.50] Check complete. PMS blobs database is damaged.
[2026-07-02 19.01.50] 
[2026-07-02 19.01.50]   Main DB: FTS index 'spellfix_metadata_titles' in  - OK
[2026-07-02 19.01.50]   Main DB: FTS index 'spellfix_tag_titles' in  - OK
[2026-07-02 19.01.50]   Main DB: FTS index 'fts4_metadata_titles' in  - OK
[2026-07-02 19.01.50]   Main DB: FTS index 'fts4_tag_titles' in  - OK
[2026-07-02 19.01.51]   Main DB: FTS index 'fts4_metadata_titles_icu' in  - OK
[2026-07-02 19.01.52]   Main DB: FTS index 'fts4_tag_titles_icu' in  - OK
[2026-07-02 19.01.52]   Blobs DB: FTS index 'spellfix_metadata_titles' in  - OK
[2026-07-02 19.01.52]   Blobs DB: FTS index 'spellfix_tag_titles' in  - OK
[2026-07-02 19.01.52]   Blobs DB: FTS index 'fts4_metadata_titles' in  - OK
[2026-07-02 19.01.52]   Blobs DB: FTS index 'fts4_tag_titles' in  - OK
[2026-07-02 19.01.52]   Blobs DB: FTS index 'fts4_metadata_titles_icu' in  - OK
[2026-07-02 19.01.52]   Blobs DB: FTS index 'fts4_tag_titles_icu' in  - OK
[2026-07-02 19.01.52]  
[2026-07-02 19.01.52] 
--- [ DBRepair: Host Configuration Dump ] ---

[2026-07-02 19.01.52]   Version:            [2.0.0]
[2026-07-02 19.01.52]   Host Type:          [User Defined]
[2026-07-02 19.01.52]   Distro Name:        [macOS]
[2026-07-02 19.01.52]   Time Stamp:         [2026-07-02_19.01.52]
[2026-07-02 19.01.52]   Last User:          [None]
[2026-07-02 19.01.52]   Last Run:           [Never]
[2026-07-02 19.01.52] 
[2026-07-02 19.01.52]   Manual Config:      Yes
[2026-07-02 19.01.52]   Root Required:      No
[2026-07-02 19.01.52]   Scripted Mode:      Yes
[2026-07-02 19.01.52]   Ignore Errors:      No
[2026-07-02 19.01.52]   Checked DB:         No
[2026-07-02 19.01.52]   Damaged:            Yes
[2026-07-02 19.01.52]   Main Damaged:       No
[2026-07-02 19.01.52]   Blobs Damaged:      No
[2026-07-02 19.01.52]   Checked FTS:        Yes
[2026-07-02 19.01.52]   FTS Damaged:        No
[2026-07-02 19.01.52]   Remove Duplicates:  No
[2026-07-02 19.01.52]   Fail Status:        No
[2026-07-02 19.01.52] 
[2026-07-02 19.01.52]   Owner UID/GID:      0:0
[2026-07-02 19.01.52]   Default Perms:      0644
[2026-07-02 19.01.52]   Stat Format:        [-c]
[2026-07-02 19.01.52]   Stat Bytes:         [%s]
[2026-07-02 19.01.52]   Stat Perms:         [%a]
[2026-07-02 19.01.52] 
[2026-07-02 19.01.52]   Package Dir:        []
[2026-07-02 19.01.52]   SQLite Version:     [3.53.0]
[2026-07-02 19.01.52]   App Support Dir:    []
[2026-07-02 19.01.52]   Database Dir:       [/Volumes/Samsung850/databases]
[2026-07-02 19.01.52]   Database Temp Dir:  [/Volumes/Samsung850/databases/dbtmp]
[2026-07-02 19.01.52]   Main DB Path:       [/Volumes/Samsung850/databases/com.plexapp.plugins.library.db]
[2026-07-02 19.01.52]   Blobs DB Path:      [/Volumes/Samsung850/databases/com.plexapp.plugins.library.blobs.db]
[2026-07-02 19.01.52]   Cache Dir:          []
[2026-07-02 19.01.52]   Log File:           []
[2026-07-02 19.01.52]   Pid File:           []
[2026-07-02 19.01.52]   Temp Dir (Local):   []
[2026-07-02 19.01.52]   System Temp:        []
[2026-07-02 19.01.52] 
[2026-07-02 19.01.52]   Script Name:        []
[2026-07-02 19.01.52]   Script Path:        []
[2026-07-02 19.01.52]   Working Dir:        []
[2026-07-02 19.01.52] 
[2026-07-02 19.01.52]   Sqlite3 Cache Size  [0]
[2026-07-02 19.01.52]   Pidof Utility:      [pidof]
[2026-07-02 19.01.52]   FTS Query:          [SELECT name FROM sqlite_master WHERE sql LIKE '%FTS%';]
[2026-07-02 19.01.52]   Have Start/Stop:    (No)
[2026-07-02 19.01.52]   Start Command:      []
[2026-07-02 19.01.52]   Stop Command:       []
[2026-07-02 19.01.52] ------------------------------------------------------
[2026-07-02 19.01.52] 
[2026-07-02 19.01.52]  
[2026-07-02 19.01.52] Retaining temporary work files.
../build/pc-darwin-arm64-release/bin/DBRepair --databases  config check confi  2.42s user 0.28s system 84% cpu 3.196 total
chuck@tirol src % 

@ChuckPa

In my use case, I do a scheduled run of DBRepair every evening so I never actually see the output unless I run it manually for some other reason. In that case I could happily add a “-v” to see what was going on if needed.

I guess in my ideal world DBRepair would email me if there was something that needed attention that it couldn’t deal with, but that may be well beyond the scope of where you are headed, which I also understand perfectly!

:smiley:

I thought about sending notifications.

I ran into trouble when I looked at Windows because of all the APIs Windows has. That’s where the Windows binary gets out of scope in a real hurry.

As it currently stands, DBRepair is self-contained on all platforms, with exception of one library integral to every MacOS platform. On MacOS, It’s harder to work around it than just use what Apple has installed so I let it use the common runtime library.

I’ve looked at providing an Environment variable which calls your script/program to send info.

  • Synology - scheduled tasks already works with TLS + SMTP email.
  • QNAP - has nothing (to my knowledge)
  • ASUSTOR & the other NAS platforms – Unknown
  • Containers - Entirely on the user to hook the container into a method.
  • MacOS, Linux CLI - This can be captured, grep’d for ERROR, and then handled by the user.

I will see what I can do.


As for the Verbose flag, I’ve been leaning to hiding the verbosity.
Your feedback supports what I’m thinking so far.

I hope others chime in and share their thoughts before I get too close to finished code.

I am not a developer (only dabble in coding for personal scripts) but I feel like putting the verbosity behind a flag seems like the better practice since it then allows you to call it if needed, but if not needed it does not clutter the screen/output. Kind of like how when capturing PMS logs they say to keep it set to debug and only put verbose on if asked to.

So my vote would be hide it behind the -v/–verbose flag since it seems like that would be more of a best practice situation (at least looking from a common sense stand point).

-Shark2k

@shark2k

I think so too. I keep looking at the original code.
The extra error output is nice but is it really necessary ?

Do we need to know the FTS Tables are damaged as a whole
or specifics?

When repairing, how much info about repairs is enough ?

I just added the ‘-v’ flag to the parser. That was trivial.
Now we can decide how much .

We need be careful to avoid this snowballing into multiple verbosity levels.
( ‘-v’ and ‘-vv’ ??? )
:rofl:

Lol, yeah, you don’t want the verbosity code maintenance to become worse than the db code work!

@ChuckPa

Fair enough - you did get me thinking though … and it occurred to me that the “flaw” in my daily automated running of DBRepair is that if it was finding errors and was unable to correct them (but I wasn’t actually seeing anything weird whilst using Plex itself), I’d be none the wiser as I don’t look at the output. Hence my interest in some kind of intelligent notification in case of uncorrectable errors … I’m on macOS BTW.

And yes, minimal cheery output with the option of verbose -v would be the way to go I think.

:smiley:

You all know I write lots of comments with code…

I’m doing hefty rethinking of how the code is laid out.
I also had to write all my own support code (previously provided by the shell / OS utils).

At present, this is how big it is:

chuck@tirol src % wc -l *.c *.h
      54 CheckDatabases.c
     142 CheckDB.c
      45 CheckFragmentation.c
     104 CheckFTS.c
     734 DBRepair.c
     352 DbUtils.c
      79 DoCount.c
       0 DoDeflate-3.c
     174 DoDeflate.c
      85 DoFTSRebuild.c
     144 DoImport.c
     110 DoIndex.c
     161 DoPrunePhotoTranscoder.c
     394 DoRepair.c
     116 DoReplace.c
      57 DoSetPageSize.c
     109 DoTriggers.c
     116 DoVacuum.c
      29 ExecSql.c
      47 FreeSpaceAvailable.c
      89 GetDates.c
      52 GetOverride.c
      57 GetSqlOutput.c
     514 HostConfig.c
     178 Init.c
      43 InitDBExtensions.c
     109 LockUtils.c
      98 main.c
      65 MakeActive.c
      66 MakeBackups.c
      49 NaturalSort.c
      46 ParseOsRelease.c
       8 PrintVersion.c
      89 Service.c
      79 ShowConfig.c
      39 ShowLog.c
      42 ShowMenu.c
     106 Signals.c
     213 Stack.c
     193 Tables.c
      99 Update.c
     895 Utils.c
     127 DBRepair.h
     524 DBSchemas.h
     110 Host.h
     324 Prototypes.h
     186 Tables-old.h
      31 Tables.h
       1 Utils.h
    7484 total
chuck@tirol src % 

The end is in sight. The heavy lifting is done (except for the Windows compile & link)

I don’t know windows, but in linux, the user can use a shell wrapper to check exit codes (and with a python wrapper, send an email notification), so if DBRepair exits with various exit codes, running DBRepair unattended can notify the user that way.

Whoa, what makes you run it daily? Do you only run if no streams?

ALL:

I “slept on it”… (boy does my back hurt. haha)

I’m leaning towards:

  • Environment variable DBREPAIR_NOTIFY_CMD

The obvious benefits of this are:

  1. I don’t have to figure out how to do notifications for all platform variants
  2. I won’t bloat the code base supporting all those email mechanisms
  3. You have full control of the command (or script) which is executed
    This lets you use Bash, Python, Executables, BAT or PS1 .

This mechanism is consistent with norms:

  • it’s part of the operating environment for all invocations just like DBREPAIR_PAGESIZE & DBREPAIR_CACHEAGE are./
  • It doesn’t overload (add clutter to) the command line

How does this sound?

Yes, probably complete overkill, but so far it has caused no issues and has maybe corrected a few minor things along the way. Runs early in the morning when PMS is never in use for us.

Sounds like a sensible light touch approach… those who want to get more fancy can do so…

Environment variables are implemented: (easy work for the day)

DBREPAIR_PAGESIZE (with full validation)
DBREPAIR_CACHEAGE (with reasonable bounds)
DBREPAIR_NOTIFY_CMD (up to 256 characters length which should work for everyone as a launching point)