-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
480 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// Copyright 2018 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package executor | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/juju/errors" | ||
"github.com/opentracing/basictracer-go" | ||
opentracing "github.com/opentracing/opentracing-go" | ||
"github.com/pingcap/tidb/ast" | ||
"github.com/pingcap/tidb/plan" | ||
"github.com/pingcap/tidb/util/chunk" | ||
"github.com/pingcap/tidb/util/tracing" | ||
"golang.org/x/net/context" | ||
) | ||
|
||
// TraceExec represents a root executor of trace query. | ||
type TraceExec struct { | ||
baseExecutor | ||
// CollectedSpans collects all span during execution. Span is appended via | ||
// callback method which passes into tracer implementation. | ||
CollectedSpans []basictracer.RawSpan | ||
// exhausted being true means there is no more result. | ||
exhausted bool | ||
// stmtNode is the real query ast tree and it is used for building real query's plan. | ||
stmtNode ast.StmtNode | ||
// rootTrace represents root span which is father of all other span. | ||
rootTrace opentracing.Span | ||
|
||
builder *executorBuilder | ||
} | ||
|
||
// Next executes real query and collects span later. | ||
func (e *TraceExec) Next(ctx context.Context, chk *chunk.Chunk) error { | ||
chk.Reset() | ||
if e.exhausted { | ||
return nil | ||
} | ||
|
||
// record how much time was spent for optimizeing plan | ||
optimizeSp := e.rootTrace.Tracer().StartSpan("plan_optimize", opentracing.FollowsFrom(e.rootTrace.Context())) | ||
stmtPlan, err := plan.Optimize(e.builder.ctx, e.stmtNode, e.builder.is) | ||
if err != nil { | ||
return err | ||
} | ||
optimizeSp.Finish() | ||
|
||
pp, ok := stmtPlan.(plan.PhysicalPlan) | ||
if !ok { | ||
return errors.New("cannot cast logical plan to physical plan") | ||
} | ||
|
||
// append select executor to trace executor | ||
stmtExec := e.builder.build(pp) | ||
|
||
e.rootTrace = tracing.NewRecordedTrace("trace_exec", func(sp basictracer.RawSpan) { | ||
e.CollectedSpans = append(e.CollectedSpans, sp) | ||
}) | ||
err = stmtExec.Open(ctx) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
stmtExecChk := stmtExec.newChunk() | ||
|
||
// store span into context | ||
ctx = opentracing.ContextWithSpan(ctx, e.rootTrace) | ||
|
||
for { | ||
if err := stmtExec.Next(ctx, stmtExecChk); err != nil { | ||
return errors.Trace(err) | ||
} | ||
if stmtExecChk.NumRows() == 0 { | ||
break | ||
} | ||
} | ||
|
||
e.rootTrace.LogKV("event", "tracing completed") | ||
e.rootTrace.Finish() | ||
var rootSpan basictracer.RawSpan | ||
|
||
treeSpans := make(map[uint64][]basictracer.RawSpan) | ||
for _, sp := range e.CollectedSpans { | ||
treeSpans[sp.ParentSpanID] = append(treeSpans[sp.ParentSpanID], sp) | ||
// if a span's parentSpanID is 0, then it is root span | ||
// this is by design | ||
if sp.ParentSpanID == 0 { | ||
rootSpan = sp | ||
} | ||
} | ||
|
||
dfsTree(rootSpan, treeSpans, "", false, chk) | ||
e.exhausted = true | ||
return nil | ||
} | ||
|
||
func dfsTree(span basictracer.RawSpan, tree map[uint64][]basictracer.RawSpan, prefix string, isLast bool, chk *chunk.Chunk) { | ||
suffix := "" | ||
spans := tree[span.Context.SpanID] | ||
var newPrefix string | ||
if span.ParentSpanID == 0 { | ||
newPrefix = prefix | ||
} else { | ||
if len(tree[span.ParentSpanID]) > 0 && !isLast { | ||
suffix = "├─" | ||
newPrefix = prefix + "│ " | ||
} else { | ||
suffix = "└─" | ||
newPrefix = prefix + " " | ||
} | ||
} | ||
|
||
chk.AppendString(0, prefix+suffix+span.Operation) | ||
chk.AppendString(1, span.Start.Format(time.StampNano)) | ||
chk.AppendString(2, span.Duration.String()) | ||
|
||
for i, sp := range spans { | ||
dfsTree(sp, tree, newPrefix, i == (len(spans))-1 /*last element of array*/, chk) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright 2018 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package executor_test | ||
|
||
import ( | ||
. "github.com/pingcap/check" | ||
"github.com/pingcap/tidb/util/testkit" | ||
) | ||
|
||
type testTraceExec struct{} | ||
|
||
func (s *testTraceExec) SetupSuite(c *C) { | ||
} | ||
|
||
func (s *testSuite) TestTraceExec(c *C) { | ||
tk := testkit.NewTestKit(c, s.store) | ||
tk.MustExec("use test") | ||
testSQL := `create table trace (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1);` | ||
tk.MustExec(testSQL) | ||
// TODO: check result later in another PR. | ||
tk.MustExec("trace select * from trace where id = 0;") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package plan | ||
|
||
import ( | ||
"github.com/pingcap/tidb/ast" | ||
) | ||
|
||
// Trace represents a trace plan. | ||
type Trace struct { | ||
baseSchemaProducer | ||
|
||
StmtNode ast.StmtNode | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.