Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

insights: surface suboptimal plans and failed executions #86458

Merged
merged 1 commit into from
Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/sql/crdb_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -6432,7 +6432,7 @@ func populateExecutionInsights(
}

indexRecommendations := tree.NewDArray(types.String)
for _, recommendation := range insight.Statement.IndexRecommendation {
for _, recommendation := range insight.Statement.IndexRecommendations {
if err := indexRecommendations.Append(tree.NewDString(recommendation)); err != nil {
return err
}
Expand All @@ -6446,7 +6446,7 @@ func populateExecutionInsights(
tree.NewDBytes(tree.DBytes(sqlstatsutil.EncodeUint64ToBytes(uint64(insight.Statement.FingerprintID)))),
problems,
tree.NewDString(insight.Statement.Query),
tree.NewDString(insight.Statement.Status),
tree.NewDString(insight.Statement.Status.String()),
startTimestamp,
endTimestamp,
tree.MakeDBool(tree.DBool(insight.Statement.FullScan)),
Expand Down
9 changes: 7 additions & 2 deletions pkg/sql/sqlstats/insights/insights.proto
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,19 @@ message Transaction {
}

message Statement {
enum Status {
Completed = 0;
Failed = 1;
}

bytes id = 1 [(gogoproto.customname) = "ID",
(gogoproto.customtype) = "github.com/cockroachdb/cockroach/pkg/sql/clusterunique.ID",
(gogoproto.nullable) = false];
uint64 fingerprint_id = 2 [(gogoproto.customname) = "FingerprintID",
(gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.StmtFingerprintID"];
double latency_in_seconds = 3;
string query = 4;
string status = 5;
Status status = 5;
google.protobuf.Timestamp start_time = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
google.protobuf.Timestamp end_time = 7 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
bool full_scan = 8;
Expand All @@ -82,7 +87,7 @@ message Statement {
// Nodes is the ordered list of nodes ids on which the statement was executed.
repeated int64 nodes = 17;
google.protobuf.Duration contention = 18 [(gogoproto.stdduration) = true];
repeated string index_recommendation = 19;
repeated string index_recommendations = 19;

}

Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/sqlstats/insights/integration/insights_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ func TestInsightsIntegration(t *testing.T) {
return err
}

if status != "completed" {
return fmt.Errorf("expected 'completed', but was %s", status)
if status != "Completed" {
return fmt.Errorf("expected 'Completed', but was %s", status)
}

delayFromTable := endInsights.Sub(startInsights).Seconds()
Expand Down
8 changes: 8 additions & 0 deletions pkg/sql/sqlstats/insights/problems.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,18 @@ type problems struct {
}

func (p *problems) examine(stmt *Statement) (result []Problem) {
if len(stmt.IndexRecommendations) > 0 {
result = append(result, Problem_SuboptimalPlan)
}

if stmt.Retries >= HighRetryCountThreshold.Get(&p.st.SV) {
result = append(result, Problem_HighRetryCount)
}

if stmt.Status == Statement_Failed {
result = append(result, Problem_FailedExecution)
}

if len(result) == 0 {
result = append(result, Problem_Unknown)
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/sql/sqlstats/insights/problems_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,21 @@ func TestProblems(t *testing.T) {
statement: &Statement{},
problems: []Problem{Problem_Unknown},
},
{
name: "suboptimal plan",
statement: &Statement{IndexRecommendations: []string{"THIS IS AN INDEX RECOMMENDATION"}},
problems: []Problem{Problem_SuboptimalPlan},
},
{
name: "high retry count",
statement: &Statement{Retries: 10},
problems: []Problem{Problem_HighRetryCount},
},
{
name: "failed execution",
statement: &Statement{Status: Statement_Failed},
problems: []Problem{Problem_FailedExecution},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
Expand Down
44 changes: 22 additions & 22 deletions pkg/sql/sqlstats/ssmemstorage/ss_mem_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ var timestampSize = int64(unsafe.Sizeof(time.Time{}))

var _ sqlstats.Writer = &Container{}

func getStatusString(statementError error) string {
func getStatus(statementError error) insights.Statement_Status {
if statementError == nil {
return "completed"
return insights.Statement_Completed
}

return "failed"
return insights.Statement_Failed
}

// RecordStatement implements sqlstats.Writer interface.
Expand Down Expand Up @@ -182,25 +182,25 @@ func (s *Container) RecordStatement(
}

s.outliersRegistry.ObserveStatement(value.SessionID, &insights.Statement{
ID: value.StatementID,
FingerprintID: stmtFingerprintID,
LatencyInSeconds: value.ServiceLatency,
Query: value.Query,
Status: getStatusString(value.StatementError),
StartTime: value.StartTime,
EndTime: value.EndTime,
FullScan: value.FullScan,
User: value.SessionData.User().Normalized(),
ApplicationName: value.SessionData.ApplicationName,
Database: value.SessionData.Database,
PlanGist: value.PlanGist,
Retries: int64(value.AutoRetryCount),
AutoRetryReason: autoRetryReason,
RowsRead: value.RowsRead,
RowsWritten: value.RowsWritten,
Nodes: value.Nodes,
Contention: contention,
IndexRecommendation: value.IndexRecommendations,
ID: value.StatementID,
FingerprintID: stmtFingerprintID,
LatencyInSeconds: value.ServiceLatency,
Query: value.Query,
Status: getStatus(value.StatementError),
StartTime: value.StartTime,
EndTime: value.EndTime,
FullScan: value.FullScan,
User: value.SessionData.User().Normalized(),
ApplicationName: value.SessionData.ApplicationName,
Database: value.SessionData.Database,
PlanGist: value.PlanGist,
Retries: int64(value.AutoRetryCount),
AutoRetryReason: autoRetryReason,
RowsRead: value.RowsRead,
RowsWritten: value.RowsWritten,
Nodes: value.Nodes,
Contention: contention,
IndexRecommendations: value.IndexRecommendations,
})

return stats.ID, nil
Expand Down