Fix various migration issues (#5723)

* Indicate while backing up database
* Close migrate connection to db before optimising
* Don't vacuum post-migration

In most cases is probably not needed and can be an optonal user-initiated step

* Ensure connection close on NewMigrator error
* Perform post-migration using migrator connection

Flush WAL file at end of migration
This commit is contained in:
WithoutPants
2025-03-19 08:04:21 +11:00
committed by GitHub
parent 529e4f6514
commit daed09e487
3 changed files with 63 additions and 15 deletions

View File

@@ -430,7 +430,19 @@ func (db *Database) Vacuum(ctx context.Context) error {
// Analyze runs an ANALYZE on the database to improve query performance.
func (db *Database) Analyze(ctx context.Context) error {
_, err := db.writeDB.ExecContext(ctx, "ANALYZE")
return analyze(ctx, db.writeDB)
}
// analyze runs an ANALYZE on the database to improve query performance.
func analyze(ctx context.Context, db *sqlx.DB) error {
_, err := db.ExecContext(ctx, "ANALYZE")
return err
}
// flushWAL flushes the Write-Ahead Log (WAL) to the main database file.
// It also truncates the WAL file to 0 bytes.
func flushWAL(ctx context.Context, db *sqlx.DB) error {
_, err := db.ExecContext(ctx, "PRAGMA wal_checkpoint(TRUNCATE)")
return err
}

View File

@@ -39,6 +39,12 @@ func NewMigrator(db *Database) (*Migrator, error) {
m.conn.SetConnMaxIdleTime(dbConnTimeout)
m.m, err = m.getMigrate()
// if error encountered, close the connection
if err != nil {
m.Close()
}
return m, err
}
@@ -124,6 +130,27 @@ func (m *Migrator) runCustomMigration(ctx context.Context, fn customMigrationFun
return nil
}
func (m *Migrator) PostMigrate(ctx context.Context) error {
// optimise the database
var err error
logger.Info("Running database analyze")
// don't use Optimize/vacuum as this adds a significant amount of time
// to the migration
err = analyze(ctx, m.conn)
if err == nil {
logger.Debug("Flushing WAL")
err = flushWAL(ctx, m.conn)
}
if err != nil {
return fmt.Errorf("error optimising database: %s", err)
}
return nil
}
func (db *Database) getDatabaseSchemaVersion() (uint, error) {
m, err := NewMigrator(db)
if err != nil {