Add PostgreSQL checkpoint functionality and update related database operations
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-02-16 09:21:00 +11:00
parent ff1ec3f4aa
commit 6da2da3e82
8 changed files with 412 additions and 34 deletions

View File

@@ -633,6 +633,47 @@ func CheckpointSQLite(ctx context.Context, dbConn *sqlx.DB) error {
return nil
}
// CheckpointPostgres requests a checkpoint when using PostgreSQL. No-op for other drivers.
// If the connected role lacks permission, the request is skipped without returning an error.
func CheckpointPostgres(ctx context.Context, dbConn *sqlx.DB) error {
driver := strings.ToLower(dbConn.DriverName())
if driver != "pgx" && driver != "postgres" {
return nil
}
if ctx == nil {
ctx = context.Background()
}
start := time.Now()
slog.Debug("postgres checkpoint start")
cctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
_, err := dbConn.ExecContext(cctx, `CHECKPOINT`)
if err != nil {
msg := strings.ToLower(err.Error())
if strings.Contains(msg, "must be superuser") || strings.Contains(msg, "pg_checkpoint") || strings.Contains(msg, "permission denied") {
slog.Debug("postgres checkpoint skipped (insufficient privilege)", "error", err)
return nil
}
slog.Warn("postgres checkpoint failed", "error", err, "duration", time.Since(start))
return err
}
slog.Debug("postgres checkpoint complete", "duration", time.Since(start))
return nil
}
// CheckpointDatabase performs the checkpoint operation appropriate for the active DB driver.
// It returns the action name for logging.
func CheckpointDatabase(ctx context.Context, dbConn *sqlx.DB) (string, error) {
switch strings.ToLower(dbConn.DriverName()) {
case "sqlite":
return "sqlite_wal_checkpoint", CheckpointSQLite(ctx, dbConn)
case "pgx", "postgres":
return "postgres_checkpoint", CheckpointPostgres(ctx, dbConn)
default:
return "none", nil
}
}
// EnsureVmHourlyStats creates the shared per-snapshot cache table used by Go aggregations.
func EnsureVmHourlyStats(ctx context.Context, dbConn *sqlx.DB) error {
ddl := `