Skip to content

Commit

Permalink
feat: auto-explain slow postgres queries(default 10s)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sidddddarth committed Nov 4, 2024
1 parent 6abcedd commit b39a266
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions utils/misc/dbutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ func NewDatabaseConnectionPool(
if err := db.Ping(); err != nil {
return nil, fmt.Errorf("Error pinging database: %w", err)
}
if _, err := db.ExecContext(ctx, "LOAD 'auto_explain';"); err != nil {
return nil, fmt.Errorf("Error loading auto_explain: %w", err)
}
autoExplainDurationThresholdVar := conf.GetReloadableDurationVar(10, time.Second, "db."+componentName+".autoExplainDurationThreshold", "db.autoExplainDurationThreshold")
autoExplainEnabledVar := conf.GetReloadableBoolVar(true, "db."+componentName+".autoExplainEnabled", "db.autoExplainEnabled")
autoExplainConfigValue := autoExplainConfig{
enabled: autoExplainEnabledVar.Load(),
threshold: autoExplainDurationThresholdVar.Load(),
}
autoExplainConfigValueVar := &autoExplainConfigLoader{
enabled: autoExplainEnabledVar,
threshold: autoExplainDurationThresholdVar,
}
updateAutoExplainDurationThreshold(ctx, db, autoExplainConfigValue)
if err := stat.RegisterCollector(
collectors.NewDatabaseSQLStats(
componentName,
Expand Down Expand Up @@ -98,12 +112,43 @@ func NewDatabaseConnectionPool(
updatePoolConfig(db.SetConnMaxIdleTime, &maxIdleTime, maxIdleTimeVar)
updatePoolConfig(db.SetMaxIdleConns, &maxIdleConns, maxIdleConnsVar)
updatePoolConfig(db.SetConnMaxLifetime, &maxConnLifetime, maxConnLifetimeVar)
updatePoolConfig(func(config autoExplainConfig) {
updateAutoExplainDurationThreshold(ctx, db, config)
}, &autoExplainConfigValue, autoExplainConfigValueVar)
}
}
})
return db, nil
}

type autoExplainConfig struct {
enabled bool
threshold time.Duration
}

type autoExplainConfigLoader struct {
enabled config.ValueLoader[bool]
threshold config.ValueLoader[time.Duration]
}

func (l autoExplainConfigLoader) Load() autoExplainConfig {
return autoExplainConfig{
enabled: l.enabled.Load(),
threshold: l.threshold.Load(),
}
}

func updateAutoExplainDurationThreshold(ctx context.Context, db *sql.DB, config autoExplainConfig) {
threshold := config.threshold.Milliseconds()
if !config.enabled {
threshold = -1
}
_, err := db.ExecContext(ctx, fmt.Sprintf("SET auto_explain.log_min_duration = %d;", threshold))
if err != nil {
panic(fmt.Errorf("Error setting auto_explain.log_min_duration: %w", err))
}
}

func updatePoolConfig[T comparable](setter func(T), current *T, conf config.ValueLoader[T]) {
newValue := conf.Load()
if newValue != *current {
Expand Down

0 comments on commit b39a266

Please sign in to comment.