Skip to content

Commit 53b5f74

Browse files
committed
fix: expose planner/activity stats in offline mode
1 parent 6e144e1 commit 53b5f74

3 files changed

Lines changed: 49 additions & 3 deletions

File tree

cmd/dryrun/main.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,14 @@ func mcpServeCmd() *cobra.Command {
851851
effectiveSchemaFile, len(snap.Tables))
852852
server = drmcp.NewOfflineServer(snap, lintCfg)
853853
server.SetSchemaCandidates(candidates)
854+
// history.db carries planner/activity stats; without it offline tools (vacuum_health, compare_nodes…) see nil sizing
855+
if h, err := history.OpenDefault(); err == nil {
856+
server.SetHistory(h)
857+
server.SetSnapshotKey(resolveSnapshotKey())
858+
if server.BootstrapFromHistory(context.Background()) {
859+
fmt.Fprintln(os.Stderr, "dryrun: attached planner/activity stats from history.db")
860+
}
861+
}
854862
case flagDB != "":
855863
ctx := context.Background()
856864
conn, err := schema.Connect(ctx, flagDB)

internal/mcp/server.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,25 @@ func (s *Server) SetSnapshotKey(key history.SnapshotKey) {
7070
s.snapshotKey = key
7171
}
7272

73+
// Lets offline mode wire in history.db after construction
74+
func (s *Server) SetHistory(hist *history.Store) {
75+
s.mu.Lock()
76+
defer s.mu.Unlock()
77+
s.history = hist
78+
}
79+
80+
func (s *Server) BootstrapFromHistory(ctx context.Context) bool {
81+
a, ok := s.loadAnnotatedFromHistory(ctx)
82+
if !ok || a == nil || a.Schema == nil {
83+
return false
84+
}
85+
s.mu.Lock()
86+
s.annotated = a
87+
s.uninitialized = false
88+
s.mu.Unlock()
89+
return true
90+
}
91+
7392
func (s *Server) loadAnnotatedFromHistory(ctx context.Context) (*schema.AnnotatedSchema, bool) {
7493
s.mu.RLock()
7594
hist := s.history

internal/schema/vacuum.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"sort"
77
"strconv"
88
"strings"
9+
"time"
910
)
1011

1112
type (
@@ -33,9 +34,17 @@ type (
3334
EffectiveScale float64 `json:"effective_scale_factor"`
3435
EffectiveAnalyzeThreshold int64 `json:"effective_analyze_threshold"`
3536
EffectiveAnalyzeScale float64 `json:"effective_analyze_scale_factor"`
36-
AnalyzeTriggerAt float64 `json:"analyze_trigger_at"`
37-
AutovacuumEnabled bool `json:"autovacuum_enabled"`
38-
Recommendations []string `json:"recommendations,omitempty"`
37+
AnalyzeTriggerAt float64 `json:"analyze_trigger_at"`
38+
AutovacuumEnabled bool `json:"autovacuum_enabled"`
39+
LastVacuum *time.Time `json:"last_vacuum,omitempty"`
40+
LastAutovacuum *time.Time `json:"last_autovacuum,omitempty"`
41+
LastAnalyze *time.Time `json:"last_analyze,omitempty"`
42+
LastAutoanalyze *time.Time `json:"last_autoanalyze,omitempty"`
43+
VacuumCount int64 `json:"vacuum_count"`
44+
AutovacuumCount int64 `json:"autovacuum_count"`
45+
AnalyzeCount int64 `json:"analyze_count"`
46+
AutoanalyzeCount int64 `json:"autoanalyze_count"`
47+
Recommendations []string `json:"recommendations,omitempty"`
3948
}
4049
)
4150

@@ -187,6 +196,16 @@ func AnalyzeVacuumHealth(a *AnnotatedSchema) []VacuumHealth {
187196
AnalyzeTriggerAt: analyzeTrigger,
188197
AutovacuumEnabled: avEnabled,
189198
}
199+
if activity != nil {
200+
vh.LastVacuum = activity.LastVacuum
201+
vh.LastAutovacuum = activity.LastAutovacuum
202+
vh.LastAnalyze = activity.LastAnalyze
203+
vh.LastAutoanalyze = activity.LastAutoanalyze
204+
vh.VacuumCount = activity.VacuumCount
205+
vh.AutovacuumCount = activity.AutovacuumCount
206+
vh.AnalyzeCount = activity.AnalyzeCount
207+
vh.AutoanalyzeCount = activity.AutoanalyzeCount
208+
}
190209

191210
if !avEnabled {
192211
vh.Recommendations = append(vh.Recommendations,

0 commit comments

Comments
 (0)