Compare commits

...

3 Commits

Author SHA1 Message Date
dependabot[bot]
4fefbe1f42
Merge 77d7e558b73654e6ee0b18b6ec30a828ec6a7a1f into ca83ebbb53d536cac1c15d6f41101d4ca1b9269f 2025-11-27 02:00:32 +00:00
Deluan
ca83ebbb53 feat: add DevOptimizeDB flag to control SQLite optimization
Added a new DevOptimizeDB configuration flag (default true) that controls
whether SQLite PRAGMA OPTIMIZE and ANALYZE commands are executed. This allows
disabling database optimization operations for debugging or testing purposes.

The flag guards optimization commands in:
- db/db.go: Initial connection, post-migration, and shutdown optimization
- persistence/library_repository.go: Post-scan optimization
- db/migrations/migration.go: ANALYZE during forced full rescans

Set ND_DEVOPTIMIZEDB=false to disable all database optimization commands.
2025-11-25 19:49:03 -05:00
dependabot[bot]
77d7e558b7
chore(deps): bump actions/stale from 9 to 10 in /.github/workflows
Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 18:01:25 +00:00
5 changed files with 24 additions and 12 deletions

View File

@ -28,7 +28,7 @@ jobs:
This pull request has been automatically locked since there This pull request has been automatically locked since there
has not been any recent activity after it was closed. has not been any recent activity after it was closed.
Please open a new issue for related bugs. Please open a new issue for related bugs.
- uses: actions/stale@v9 - uses: actions/stale@v10
with: with:
operations-per-run: 999 operations-per-run: 999
days-before-issue-stale: 180 days-before-issue-stale: 180

View File

@ -131,6 +131,7 @@ type configOptions struct {
DevEnablePluginsInsights bool DevEnablePluginsInsights bool
DevPluginCompilationTimeout time.Duration DevPluginCompilationTimeout time.Duration
DevExternalArtistFetchMultiplier float64 DevExternalArtistFetchMultiplier float64
DevOptimizeDB bool
} }
type scannerOptions struct { type scannerOptions struct {
@ -427,7 +428,7 @@ func validatePurgeMissingOption() error {
} }
} }
if !valid { if !valid {
err := fmt.Errorf("Invalid Scanner.PurgeMissing value: '%s'. Must be one of: %v", Server.Scanner.PurgeMissing, allowedValues) err := fmt.Errorf("invalid Scanner.PurgeMissing value: '%s'. Must be one of: %v", Server.Scanner.PurgeMissing, allowedValues)
log.Error(err.Error()) log.Error(err.Error())
Server.Scanner.PurgeMissing = consts.PurgeMissingNever Server.Scanner.PurgeMissing = consts.PurgeMissingNever
return err return err
@ -609,6 +610,7 @@ func setViperDefaults() {
viper.SetDefault("devenablepluginsinsights", true) viper.SetDefault("devenablepluginsinsights", true)
viper.SetDefault("devplugincompilationtimeout", time.Minute) viper.SetDefault("devplugincompilationtimeout", time.Minute)
viper.SetDefault("devexternalartistfetchmultiplier", 1.5) viper.SetDefault("devexternalartistfetchmultiplier", 1.5)
viper.SetDefault("devoptimizedb", true)
} }
func init() { func init() {

View File

@ -45,10 +45,12 @@ func Db() *sql.DB {
if err != nil { if err != nil {
log.Fatal("Error opening database", err) log.Fatal("Error opening database", err)
} }
_, err = db.Exec("PRAGMA optimize=0x10002") if conf.Server.DevOptimizeDB {
if err != nil { _, err = db.Exec("PRAGMA optimize=0x10002")
log.Error("Error applying PRAGMA optimize", err) if err != nil {
return nil log.Error("Error applying PRAGMA optimize", err)
return nil
}
} }
return db return db
}) })
@ -99,7 +101,7 @@ func Init(ctx context.Context) func() {
log.Fatal(ctx, "Failed to apply new migrations", err) log.Fatal(ctx, "Failed to apply new migrations", err)
} }
if hasSchemaChanges { if hasSchemaChanges && conf.Server.DevOptimizeDB {
log.Debug(ctx, "Applying PRAGMA optimize after schema changes") log.Debug(ctx, "Applying PRAGMA optimize after schema changes")
_, err = db.ExecContext(ctx, "PRAGMA optimize") _, err = db.ExecContext(ctx, "PRAGMA optimize")
if err != nil { if err != nil {
@ -114,6 +116,9 @@ func Init(ctx context.Context) func() {
// Optimize runs PRAGMA optimize on each connection in the pool // Optimize runs PRAGMA optimize on each connection in the pool
func Optimize(ctx context.Context) { func Optimize(ctx context.Context) {
if !conf.Server.DevOptimizeDB {
return
}
numConns := Db().Stats().OpenConnections numConns := Db().Stats().OpenConnections
if numConns == 0 { if numConns == 0 {
log.Debug(ctx, "No open connections to optimize") log.Debug(ctx, "No open connections to optimize")

View File

@ -7,6 +7,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/consts" "github.com/navidrome/navidrome/consts"
) )
@ -21,11 +22,13 @@ func notice(tx *sql.Tx, msg string) {
// Call this in migrations that requires a full rescan // Call this in migrations that requires a full rescan
func forceFullRescan(tx *sql.Tx) error { func forceFullRescan(tx *sql.Tx) error {
// If a full scan is required, most probably the query optimizer is outdated, so we run `analyze`. // If a full scan is required, most probably the query optimizer is outdated, so we run `analyze`.
_, err := tx.Exec(`ANALYZE;`) if conf.Server.DevOptimizeDB {
if err != nil { _, err := tx.Exec(`ANALYZE;`)
return err if err != nil {
return err
}
} }
_, err = tx.Exec(fmt.Sprintf(` _, err := tx.Exec(fmt.Sprintf(`
INSERT OR REPLACE into property (id, value) values ('%s', '1'); INSERT OR REPLACE into property (id, value) values ('%s', '1');
`, consts.FullScanAfterMigrationFlagKey)) `, consts.FullScanAfterMigrationFlagKey))
return err return err

View File

@ -179,7 +179,9 @@ func (r *libraryRepository) ScanEnd(id int) error {
// https://www.sqlite.org/pragma.html#pragma_optimize // https://www.sqlite.org/pragma.html#pragma_optimize
// Use mask 0x10000 to check table sizes without running ANALYZE // Use mask 0x10000 to check table sizes without running ANALYZE
// Running ANALYZE can cause query planner issues with expression-based collation indexes // Running ANALYZE can cause query planner issues with expression-based collation indexes
_, err = r.executeSQL(Expr("PRAGMA optimize=0x10000;")) if conf.Server.DevOptimizeDB {
_, err = r.executeSQL(Expr("PRAGMA optimize=0x10000;"))
}
return err return err
} }