chore(db): migration for previous commits (#10319)
Recreate the blocks and block lists tables. --------- Co-authored-by: bt90 <btom1990@googlemail.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"embed"
|
"embed"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"log/slog"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
"slices"
|
||||||
@@ -21,11 +22,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
"github.com/syncthing/syncthing/internal/slogutil"
|
||||||
"github.com/syncthing/syncthing/lib/build"
|
"github.com/syncthing/syncthing/lib/build"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
const currentSchemaVersion = 3
|
const currentSchemaVersion = 4
|
||||||
|
|
||||||
//go:embed sql/**
|
//go:embed sql/**
|
||||||
var embedded embed.FS
|
var embedded embed.FS
|
||||||
@@ -91,6 +93,7 @@ func openBase(path string, maxConns int, pragmas, schemaScripts, migrationScript
|
|||||||
}
|
}
|
||||||
|
|
||||||
ver, _ := db.getAppliedSchemaVersion()
|
ver, _ := db.getAppliedSchemaVersion()
|
||||||
|
shouldVacuum := false
|
||||||
if ver.SchemaVersion > 0 {
|
if ver.SchemaVersion > 0 {
|
||||||
type migration struct {
|
type migration struct {
|
||||||
script string
|
script string
|
||||||
@@ -117,6 +120,7 @@ func openBase(path string, maxConns int, pragmas, schemaScripts, migrationScript
|
|||||||
if err := db.applyMigration(m.version, m.script); err != nil {
|
if err := db.applyMigration(m.version, m.script); err != nil {
|
||||||
return nil, wrap(err)
|
return nil, wrap(err)
|
||||||
}
|
}
|
||||||
|
shouldVacuum = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,6 +129,14 @@ func openBase(path string, maxConns int, pragmas, schemaScripts, migrationScript
|
|||||||
return nil, wrap(err)
|
return nil, wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if shouldVacuum {
|
||||||
|
// We applied migrations and should take the opportunity to vaccuum
|
||||||
|
// the database.
|
||||||
|
if err := db.vacuumAndOptimize(); err != nil {
|
||||||
|
return nil, wrap(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +212,20 @@ func (s *baseDB) expandTemplateVars(tpl string) string {
|
|||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *baseDB) vacuumAndOptimize() error {
|
||||||
|
stmts := []string{
|
||||||
|
"VACUUM;",
|
||||||
|
"PRAGMA optimize;",
|
||||||
|
"PRAGMA wal_checkpoint(truncate);",
|
||||||
|
}
|
||||||
|
for _, stmt := range stmts {
|
||||||
|
if _, err := s.sql.Exec(stmt); err != nil {
|
||||||
|
return wrap(err, stmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type stmt interface {
|
type stmt interface {
|
||||||
Exec(args ...any) (sql.Result, error)
|
Exec(args ...any) (sql.Result, error)
|
||||||
Get(dest any, args ...any) error
|
Get(dest any, args ...any) error
|
||||||
@@ -252,6 +278,8 @@ func (s *baseDB) applyMigration(ver int, script string) error {
|
|||||||
}
|
}
|
||||||
defer tx.Rollback() //nolint:errcheck
|
defer tx.Rollback() //nolint:errcheck
|
||||||
|
|
||||||
|
slog.Info("Applying database migration", slogutil.FilePath(s.baseName), "toSchema", ver, "script", script)
|
||||||
|
|
||||||
if err := s.execScript(tx, script); err != nil {
|
if err := s.execScript(tx, script); err != nil {
|
||||||
return wrap(err)
|
return wrap(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
-- Copyright (C) 2025 The Syncthing Authors.
|
||||||
|
--
|
||||||
|
-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
-- License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
-- You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
-- Copy blocks to new table with fewer indexes
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS blocks_v4
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE TABLE blocks_v4 (
|
||||||
|
hash BLOB NOT NULL,
|
||||||
|
blocklist_hash BLOB NOT NULL,
|
||||||
|
idx INTEGER NOT NULL,
|
||||||
|
offset INTEGER NOT NULL,
|
||||||
|
size INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY (hash, blocklist_hash, idx)
|
||||||
|
) STRICT, WITHOUT ROWID
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO blocks_v4 (hash, blocklist_hash, idx, offset, size)
|
||||||
|
SELECT hash, blocklist_hash, idx, offset, size FROM blocks ORDER BY hash, blocklist_hash, idx
|
||||||
|
;
|
||||||
|
|
||||||
|
DROP TABLE blocks
|
||||||
|
;
|
||||||
|
|
||||||
|
ALTER TABLE blocks_v4 RENAME TO blocks
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Copy blocklists to new table with fewer indexes
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS blocklists_v4
|
||||||
|
;
|
||||||
|
|
||||||
|
CREATE TABLE blocklists_v4 (
|
||||||
|
blocklist_hash BLOB NOT NULL PRIMARY KEY,
|
||||||
|
blprotobuf BLOB NOT NULL
|
||||||
|
) STRICT, WITHOUT ROWID
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO blocklists_v4 (blocklist_hash, blprotobuf)
|
||||||
|
SELECT blocklist_hash, blprotobuf FROM blocklists ORDER BY blocklist_hash
|
||||||
|
;
|
||||||
|
|
||||||
|
DROP TABLE blocklists
|
||||||
|
;
|
||||||
|
|
||||||
|
ALTER TABLE blocklists_v4 RENAME TO blocklists
|
||||||
|
;
|
||||||
@@ -191,6 +191,10 @@ func (a *App) startup() error {
|
|||||||
if _, ok := cfgFolders[folder]; !ok {
|
if _, ok := cfgFolders[folder]; !ok {
|
||||||
slog.Info("Cleaning metadata for dropped folder", "folder", folder)
|
slog.Info("Cleaning metadata for dropped folder", "folder", folder)
|
||||||
a.sdb.DropFolder(folder)
|
a.sdb.DropFolder(folder)
|
||||||
|
} else {
|
||||||
|
// Open the folder database, causing it to apply migrations
|
||||||
|
// early when appropriate.
|
||||||
|
_, _ = a.sdb.GetDeviceSequence(folder, protocol.LocalDeviceID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user