FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

ROX-34561: add index health stats to diagnostic bundle (#20474) · stackrox/stackrox@936152f · GitHub

Commit 936152f

Browse files
andauthored
ROX-34561: add index health stats to diagnostic bundle (#20474)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1124a22 commit 936152f

3 files changed

Lines changed: 91 additions & 1 deletion

File tree

‎central/debug/service/service.go‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,16 @@ func getCentralDBData(ctx context.Context, zipWriter *zipWriter) error {
512512
if activities.Error != "" {
513513
log.Errorw("error retrieving pg_stat_activity", logging.Err(errors.New(activities.Error)))
514514
}
515-
return addJSONToZip(zipWriter, "central-db-pg-activity.json", activities)
515+
if err := addJSONToZip(zipWriter, "central-db-pg-activity.json", activities); err != nil {
516+
return err
517+
}
518+
519+
// Get the index health stats
520+
indexStats := stats.GetPGIndexStats(ctx, db, pgStatStatementsMax)
521+
if indexStats.Error != "" {
522+
log.Errorw("error retrieving pg_stat_user_indexes", logging.Err(errors.New(indexStats.Error)))
523+
}
524+
return addJSONToZip(zipWriter, "central-db-pg-index-stats.json", indexStats)
516525
}
517526

518527
func (s *serviceImpl) getLogImbue(ctx context.Context, zipWriter *zipWriter) error {

‎pkg/postgres/stats/stats.go‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,55 @@ func GetPGStatActivities(ctx context.Context, db postgres.DB, limit int) *PGStat
204204
}
205205
return &activities
206206
}
207+
208+
// PGIndexStat is the data model for a single index from pg_stat_user_indexes joined with pg_index
209+
type PGIndexStat struct {
210+
TableName string
211+
IndexName string
212+
IndexType string
213+
IndexSizeBytes int64
214+
IsValid bool
215+
IsReady bool
216+
IndexScans int64
217+
}
218+
219+
// PGIndexStats is a wrapper around PGIndexStat
220+
type PGIndexStats struct {
221+
Indexes []*PGIndexStat
222+
Error string
223+
}
224+
225+
// GetPGIndexStats returns index health information from pg_stat_user_indexes joined with pg_index.
226+
// pg_stat_user_indexes is used to scope results to the current user's indexes only,
227+
// avoiding exposure of indexes from management or infrastructure schemas on external databases.
228+
func GetPGIndexStats(ctx context.Context, db postgres.DB, limit int) *PGIndexStats {
229+
var indexStats PGIndexStats
230+
rows, err := db.Query(ctx,
231+
`SELECT s.relname, s.indexrelname, am.amname,
232+
pg_relation_size(ix.indexrelid), ix.indisvalid, ix.indisready,
233+
s.idx_scan
234+
FROM pg_stat_user_indexes s
235+
JOIN pg_index ix ON ix.indexrelid = s.indexrelid
236+
JOIN pg_class i ON i.oid = ix.indexrelid
237+
JOIN pg_am am ON am.oid = i.relam
238+
ORDER BY pg_relation_size(ix.indexrelid) DESC
239+
LIMIT $1`, limit)
240+
if err != nil {
241+
indexStats.Error = err.Error()
242+
return &indexStats
243+
}
244+
defer rows.Close()
245+
246+
for rows.Next() {
247+
var idx PGIndexStat
248+
if err := rows.Scan(&idx.TableName, &idx.IndexName, &idx.IndexType, &idx.IndexSizeBytes, &idx.IsValid, &idx.IsReady, &idx.IndexScans); err != nil {
249+
indexStats.Error = errors.Wrap(err, "error scanning rows from pg_stat_user_indexes").Error()
250+
return &indexStats
251+
}
252+
indexStats.Indexes = append(indexStats.Indexes, &idx)
253+
}
254+
if err := rows.Err(); err != nil {
255+
indexStats.Error = err.Error()
256+
}
257+
return &indexStats
258+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//go:build sql_integration
2+
3+
package stats
4+
5+
import (
6+
"context"
7+
"testing"
8+
9+
"github.com/stackrox/rox/pkg/postgres/pgtest"
10+
"github.com/stackrox/rox/pkg/sac"
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
func TestGetPGIndexStats(t *testing.T) {
16+
ctx := sac.WithAllAccess(context.Background())
17+
tp := pgtest.ForT(t)
18+
defer tp.Close()
19+
20+
result := GetPGIndexStats(ctx, tp.DB, 100)
21+
require.Empty(t, result.Error)
22+
assert.NotNil(t, result.Indexes)
23+
for _, idx := range result.Indexes {
24+
assert.NotEmpty(t, idx.TableName)
25+
assert.NotEmpty(t, idx.IndexName)
26+
assert.NotEmpty(t, idx.IndexType)
27+
assert.True(t, idx.IsValid, "index %s on %s should be valid", idx.IndexName, idx.TableName)
28+
}
29+
}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL