osbuild-service-maintenance: Vacuum tables

Call vacuum analyze after each chunk of updates, and dump vacuum stats
at the beginning and end of the db cleanup.

Nulling results can increase size on disk, but calling vacuum analyze
will free up space within the table (not on disk) and reuse the space
for new inserts and updates.
This commit is contained in:
Sanne Raymaekers 2022-06-07 13:12:14 +02:00 committed by Ondřej Budai
parent 8bfc6c9961
commit ff408aa68f
2 changed files with 89 additions and 0 deletions

View file

@ -22,6 +22,11 @@ func DBCleanup(dbURL string, dryRun bool, cutoff time.Time) error {
return fmt.Errorf("Error querying jobs: %v", err) return fmt.Errorf("Error querying jobs: %v", err)
} }
err = jobs.LogVacuumStats()
if err != nil {
logrus.Errorf("Error running vacuum stats: %v", err)
}
for k, v := range jobsByType { for k, v := range jobsByType {
logrus.Infof("Deleting results from %d %s jobs", len(v), k) logrus.Infof("Deleting results from %d %s jobs", len(v), k)
if dryRun { if dryRun {
@ -42,8 +47,17 @@ func DBCleanup(dbURL string, dryRun bool, cutoff time.Time) error {
continue continue
} }
logrus.Infof("Deleted results from %d jobs out of %d job ids", rows, len(v)) logrus.Infof("Deleted results from %d jobs out of %d job ids", rows, len(v))
err = jobs.VacuumAnalyze()
if err != nil {
logrus.Errorf("Error running vacuum analyze: %v", err)
}
} }
} }
err = jobs.LogVacuumStats()
if err != nil {
logrus.Errorf("Error running vacuum stats: %v", err)
}
return nil return nil
} }

View file

@ -110,6 +110,14 @@ const (
UPDATE jobs UPDATE jobs
SET result = NULL SET result = NULL
WHERE id = ANY($1)` WHERE id = ANY($1)`
sqlVacuumAnalyze = `
VACUUM ANALYZE`
sqlVacuumStats = `
SELECT relname, pg_size_pretty(pg_total_relation_size(relid)),
n_tup_ins, n_tup_upd, n_tup_del, n_live_tup, n_dead_tup,
vacuum_count, autovacuum_count, analyze_count, autoanalyze_count,
last_vacuum, last_autovacuum, last_analyze, last_autoanalyze
FROM pg_stat_user_tables`
) )
type DBJobQueue struct { type DBJobQueue struct {
@ -658,3 +666,70 @@ func (q *DBJobQueue) DeleteJobResult(jobIds []uuid.UUID) (int64, error) {
} }
return tag.RowsAffected(), nil return tag.RowsAffected(), nil
} }
func (q *DBJobQueue) VacuumAnalyze() error {
conn, err := q.pool.Acquire(context.Background())
if err != nil {
return fmt.Errorf("error connecting to database: %v", err)
}
defer conn.Release()
_, err = conn.Exec(context.Background(), sqlVacuumAnalyze)
if err != nil {
return fmt.Errorf("Error running VACUUM ANALYZE: %v", err)
}
return nil
}
func (q *DBJobQueue) LogVacuumStats() error {
conn, err := q.pool.Acquire(context.Background())
if err != nil {
return fmt.Errorf("error connecting to database: %v", err)
}
defer conn.Release()
rows, err := conn.Query(context.Background(), sqlVacuumStats)
if err != nil {
return fmt.Errorf("Error querying vacuum stats: %v", err)
}
defer rows.Close()
for rows.Next() {
var relName, relSize string
var ins, upd, del, live, dead, vc, avc, ac, aac int64
var lvc, lavc, lan, laan *time.Time
err = rows.Scan(&relName, &relSize, &ins, &upd, &del, &live, &dead,
&vc, &avc, &ac, &aac,
&lvc, &lavc, &lan, &laan)
if err != nil {
return err
}
logrus.Infof("Stats for table %s", relName)
logrus.Infof(" Total table size: %s", relSize)
logrus.Info(" Tuples:")
logrus.Infof(" Inserted: %d", ins)
logrus.Infof(" Updated: %d", upd)
logrus.Infof(" Deleted: %d", del)
logrus.Infof(" Live: %d", live)
logrus.Infof(" Dead: %d", dead)
logrus.Info(" Vacuum stats:")
logrus.Infof(" Vacuum count: %d", vc)
logrus.Infof(" AutoVacuum count: %d", avc)
logrus.Infof(" Last vacuum: %v", lvc)
logrus.Infof(" Last autovacuum: %v", lavc)
logrus.Info(" Analyze stats:")
logrus.Infof(" Analyze count: %d", ac)
logrus.Infof(" AutoAnalyze count: %d", aac)
logrus.Infof(" Last analyze: %v", lan)
logrus.Infof(" Last autoanalyze: %v", laan)
logrus.Info("---")
}
if rows.Err() != nil {
return rows.Err()
}
return nil
}