feat(maintenance): add policy executor and config provider
ConfigProvider, PolicyExecutor, DBStatsProvider, scheduler и safety; зависимость robfig/cron/v3. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package maintenance
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"evobgp/internal/pgmonitor"
|
||||
)
|
||||
|
||||
// TableHints are PostgreSQL statistics hints for UI recommendations.
|
||||
type TableHints struct {
|
||||
TableName string `json:"table_name"`
|
||||
DeadTuples int64 `json:"n_dead_tup"`
|
||||
BloatRatio float64 `json:"bloat_ratio,omitempty"`
|
||||
LastAutovacuum string `json:"last_autovacuum,omitempty"`
|
||||
RecommendVacuum bool `json:"recommend_vacuum"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
Refs []string `json:"refs,omitempty"`
|
||||
}
|
||||
|
||||
// DBStatsProvider wraps pgmonitor for maintenance policy hints.
|
||||
type DBStatsProvider struct {
|
||||
pg *pgmonitor.Service
|
||||
}
|
||||
|
||||
// NewDBStatsProvider constructs a stats provider.
|
||||
func NewDBStatsProvider(pg *pgmonitor.Service) *DBStatsProvider {
|
||||
return &DBStatsProvider{pg: pg}
|
||||
}
|
||||
|
||||
// Hints returns table-level vacuum/bloat hints.
|
||||
func (d *DBStatsProvider) Hints(ctx context.Context, tableName string) (TableHints, error) {
|
||||
out := TableHints{TableName: tableName}
|
||||
if d == nil || d.pg == nil {
|
||||
return out, fmt.Errorf("maintenance: postgres monitoring not configured")
|
||||
}
|
||||
if err := ValidateTableName(tableName); err != nil {
|
||||
return out, err
|
||||
}
|
||||
tables, err := d.pg.Tables(ctx, 100)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
for _, t := range tables {
|
||||
if t.Relname != tableName {
|
||||
continue
|
||||
}
|
||||
out.DeadTuples = t.DeadTuples
|
||||
out.BloatRatio = t.BloatRatio
|
||||
if t.LastAutovacuum != nil {
|
||||
out.LastAutovacuum = t.LastAutovacuum.UTC().Format("2006-01-02T15:04:05Z")
|
||||
}
|
||||
if t.BloatRatio > 0.2 && t.DeadTuples > 5000 {
|
||||
out.RecommendVacuum = true
|
||||
out.Detail = "Высокая доля n_dead_tup; рекомендуется VACUUM."
|
||||
out.Refs = []string{t.Relname}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
out.Detail = "Таблица не найдена в pg_stat_user_tables (top by size)."
|
||||
return out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user