fix: SQLite WAL mode y busy_timeout para evitar SQLITE_BUSY
Registra un connection hook en el driver modernc/sqlite que ejecuta PRAGMA journal_mode=WAL y PRAGMA busy_timeout=5000 en cada conexión nueva. Esto previene errores SQLITE_BUSY cuando múltiples goroutines escriben concurrentemente (crypto sync de mautrix + memory store + knowledge store). Incluye tests que verifican: - Pragmas aplicados correctamente en cada conexión - Escrituras concurrentes sin error (mismo sql.DB y conexiones separadas) - Archivo -wal creado en disco confirmando WAL activo Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+27
-2
@@ -1,12 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
|
||||
moderncsqlite "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// mautrix dbutil opens sqlite as "sqlite3"; register the pure-Go driver under that name.
|
||||
sql.Register("sqlite3", &moderncsqlite.Driver{})
|
||||
// mautrix dbutil opens sqlite as "sqlite3"; register the pure-Go driver
|
||||
// under that name. We add a connection hook that sets WAL mode and a
|
||||
// busy timeout on every connection to prevent SQLITE_BUSY crashes during
|
||||
// concurrent writes (crypto store sync + memory store).
|
||||
d := &moderncsqlite.Driver{}
|
||||
d.RegisterConnectionHook(sqlitePragmaHook)
|
||||
sql.Register("sqlite3", d)
|
||||
}
|
||||
|
||||
// sqlitePragmaHook sets WAL journal mode and a 5-second busy timeout on
|
||||
// every new SQLite connection. This prevents SQLITE_BUSY errors when
|
||||
// multiple goroutines write concurrently (e.g. mautrix crypto sync +
|
||||
// memory/knowledge stores).
|
||||
func sqlitePragmaHook(conn moderncsqlite.ExecQuerierContext, _ string) error {
|
||||
ctx := context.Background()
|
||||
pragmas := []string{
|
||||
"PRAGMA journal_mode=WAL",
|
||||
"PRAGMA busy_timeout=5000",
|
||||
}
|
||||
for _, p := range pragmas {
|
||||
if _, err := conn.ExecContext(ctx, p, []driver.NamedValue{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user