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

planner, executor: fix haven't track the memory usage of PointGet/BatchPointGet #21230

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f76abb3
fix statement-level optimize hint will be ignored when `tryFastPlan` …
zhaoxugang Nov 23, 2020
5c81c3f
fix import,test sql
zhaoxugang Nov 23, 2020
83f4248
fix error
zhaoxugang Nov 23, 2020
7f58a62
fix unit test
zhaoxugang Nov 23, 2020
e4aa904
fix unit test
zhaoxugang Nov 23, 2020
291e2c6
fix unit test
zhaoxugang Nov 23, 2020
c9f3966
fix unit test
zhaoxugang Nov 23, 2020
87d0476
fix test
zhaoxugang Dec 11, 2020
4ff8172
fix memory track
zhaoxugang Dec 13, 2020
6ada448
fix test,revert changes about memory hit
zhaoxugang Dec 13, 2020
b521483
Merge remote-tracking branch 'origin/master' into point-get-member-hint
zhaoxugang Dec 15, 2020
93f09b1
fix
zhaoxugang Dec 17, 2020
5883956
fix
zhaoxugang Dec 25, 2020
08d4671
fix
zhaoxugang Jan 3, 2021
8fd842c
fix
zhaoxugang Jan 4, 2021
86a523a
fix
zhaoxugang Jan 4, 2021
93c21bd
fix
zhaoxugang Jan 13, 2021
97579d9
Merge branch 'master' into point-get-member-hint
zhaoxugang Jan 16, 2021
facbc93
Merge branch 'master' into point-get-member-hint
zhaoxugang Jan 23, 2021
006ac37
Merge branch 'master' into point-get-member-hint
ti-srebot Feb 18, 2021
092914a
Merge branch 'master' into point-get-member-hint
zhaoxugang Feb 18, 2021
7a7e04a
Merge remote-tracking branch 'origin/point-get-member-hint' into poin…
zhaoxugang Feb 18, 2021
65feff2
Merge branch 'master' into point-get-member-hint
ti-chi-bot Feb 22, 2021
279e4c5
Merge branch 'master' into point-get-member-hint
zhaoxugang Feb 22, 2021
1430ee2
Merge remote-tracking branch 'origin/point-get-member-hint' into poin…
zhaoxugang Feb 22, 2021
ab74f22
Merge branch 'master' into point-get-member-hint
zhaoxugang Mar 7, 2021
f2ae417
Merge branch 'master' into point-get-member-hint
zhaoxugang Mar 28, 2021
a5fa934
Merge branch 'master-upstream' into point-get-member-hint
zhaoxugang Jan 30, 2022
7d2359a
Merge branch 'master-upstream' into point-get-member-hint
zhaoxugang Feb 11, 2022
46013d0
format fix
zhaoxugang Feb 11, 2022
47e7c0a
fix bug
zhaoxugang Feb 12, 2022
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
15 changes: 15 additions & 0 deletions executor/batch_point_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/pingcap/tidb/util/hack"
"github.com/pingcap/tidb/util/logutil/consistency"
"github.com/pingcap/tidb/util/math"
"github.com/pingcap/tidb/util/memory"
"github.com/pingcap/tidb/util/rowcodec"
"github.com/tikv/client-go/v2/txnkv/txnsnapshot"
)
Expand Down Expand Up @@ -82,6 +83,8 @@ type BatchPointGetExec struct {
snapshot kv.Snapshot
stats *runtimeStatsWithSnapshot
cacheTable kv.MemBuffer

memTracker *memory.Tracker
}

// buildVirtualColumnInfo saves virtual column indices and sort them in definition order
Expand Down Expand Up @@ -165,6 +168,9 @@ func (e *BatchPointGetExec) Open(context.Context) error {
}
e.snapshot = snapshot
e.batchGetter = batchGetter

e.memTracker = memory.NewTracker(e.id, -1)
e.memTracker.AttachTo(e.ctx.GetSessionVars().StmtCtx.MemTracker)
return nil
}

Expand Down Expand Up @@ -212,6 +218,12 @@ func MockNewCacheTableSnapShot(snapshot kv.Snapshot, memBuffer kv.MemBuffer) *ca

// Close implements the Executor interface.
func (e *BatchPointGetExec) Close() error {

if e.memTracker != nil {
e.memTracker.Consume(-e.memTracker.BytesConsumed())
e.memTracker = nil
}

if e.runtimeStats != nil && e.snapshot != nil {
e.snapshot.SetOption(kv.CollectRuntimeStats, nil)
}
Expand Down Expand Up @@ -271,6 +283,7 @@ func (e *BatchPointGetExec) initialize(ctx context.Context) error {
dedup := make(map[hack.MutableString]struct{})
toFetchIndexKeys := make([]kv.Key, 0, len(e.idxVals))
for _, idxVals := range e.idxVals {
e.memTracker.Consume(types.EstimatedMemUsage(idxVals, 1))
// For all x, 'x IN (null)' evaluate to null, so the query get no result.
if datumsContainNull(idxVals) {
continue
Expand Down Expand Up @@ -498,7 +511,9 @@ func (e *BatchPointGetExec) initialize(ctx context.Context) error {
continue
}
e.values = append(e.values, val)
e.memTracker.Consume(int64(cap(val)))
handles = append(handles, e.handles[i])
e.memTracker.Consume(e.handles[i].MemoryUsage())
if e.lock && rc {
existKeys = append(existKeys, key)
// when e.handles is set in builder directly, index should be primary key and the plan is CommonHandleRead
Expand Down
15 changes: 13 additions & 2 deletions executor/point_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/pingcap/tidb/util/codec"
"github.com/pingcap/tidb/util/execdetails"
"github.com/pingcap/tidb/util/logutil/consistency"
"github.com/pingcap/tidb/util/memory"
"github.com/pingcap/tidb/util/rowcodec"
"github.com/tikv/client-go/v2/txnkv/txnsnapshot"
)
Expand Down Expand Up @@ -103,6 +104,8 @@ type PointGetExecutor struct {

stats *runtimeStatsWithSnapshot
cacheTable kv.MemBuffer

memTracker *memory.Tracker
}

// Init set fields needed for PointGetExecutor reuse, this does NOT change baseExecutor field
Expand Down Expand Up @@ -174,6 +177,8 @@ func (e *PointGetExecutor) Open(context.Context) error {
if readReplicaType.IsFollowerRead() {
e.snapshot.SetOption(kv.ReplicaRead, readReplicaType)
}
e.memTracker = memory.NewTracker(e.id, -1)
e.memTracker.AttachTo(e.ctx.GetSessionVars().StmtCtx.MemTracker)
e.snapshot.SetOption(kv.TaskID, e.ctx.GetSessionVars().StmtCtx.TaskID)
e.snapshot.SetOption(kv.ReadReplicaScope, e.readReplicaScope)
e.snapshot.SetOption(kv.IsStalenessReadOnly, e.isStaleness)
Expand All @@ -198,6 +203,11 @@ func (e *PointGetExecutor) Open(context.Context) error {

// Close implements the Executor interface.
func (e *PointGetExecutor) Close() error {
if e.memTracker != nil {
e.memTracker.Consume(-e.memTracker.BytesConsumed())
e.memTracker = nil
}

if e.runtimeStats != nil && e.snapshot != nil {
e.snapshot.SetOption(kv.CollectRuntimeStats, nil)
}
Expand Down Expand Up @@ -248,14 +258,15 @@ func (e *PointGetExecutor) Next(ctx context.Context, req *chunk.Chunk) error {
if err != nil && !kv.ErrNotExist.Equal(err) {
return err
}
e.memTracker.Consume(int64(cap(e.idxKey)))

e.handleVal, err = e.get(ctx, e.idxKey)
if err != nil {
if !kv.ErrNotExist.Equal(err) {
return err
}
}

e.memTracker.Consume(int64(cap(e.handleVal)))
// try lock the index key if isolation level is not read consistency
// also lock key if read consistency read a value
if !e.ctx.GetSessionVars().IsPessimisticReadConsistency() || len(e.handleVal) > 0 {
Expand Down Expand Up @@ -301,7 +312,7 @@ func (e *PointGetExecutor) Next(ctx context.Context, req *chunk.Chunk) error {
})
}
}

e.memTracker.Consume(e.handle.MemoryUsage())
key := tablecodec.EncodeRowKeyWithHandle(tblID, e.handle)
val, err := e.getAndLock(ctx, key)
if err != nil {
Expand Down
12 changes: 12 additions & 0 deletions kv/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@
Data() ([]types.Datum, error)
// String implements the fmt.Stringer interface.
String() string
// MemoryUsage returns the total memory usage of a Handle in bytes.
MemoryUsage() int64
}

// IntHandle implement the Handle interface for int64 type handle.
Expand Down Expand Up @@ -228,6 +230,11 @@
return strconv.FormatInt(int64(ih), 10)
}

// MemoryUsage implements the Handle interface.
func (ih IntHandle) MemoryUsage() int64 {
return 8

Check warning on line 235 in kv/key.go

View check run for this annotation

Codecov / codecov/patch

kv/key.go#L234-L235

Added lines #L234 - L235 were not covered by tests
}

// CommonHandle implements the Handle interface for non-int64 type handle.
type CommonHandle struct {
encoded []byte
Expand Down Expand Up @@ -347,6 +354,11 @@
return fmt.Sprintf("{%s}", strings.Join(strs, ", "))
}

// MemoryUsage implements the Handle interface.
func (ch *CommonHandle) MemoryUsage() int64 {
return int64(cap(ch.encoded))

Check warning on line 359 in kv/key.go

View check run for this annotation

Codecov / codecov/patch

kv/key.go#L358-L359

Added lines #L358 - L359 were not covered by tests
}

// HandleMap is the map for Handle.
type HandleMap struct {
ints map[int64]interface{}
Expand Down
26 changes: 26 additions & 0 deletions session/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3458,6 +3458,32 @@ func (s *testSessionSuite2) TestStmtHints(c *C) {
c.Assert(tk.Se.GetSessionVars().GetReplicaRead(), Equals, kv.ReplicaReadFollower)
}

// Test memory track in POINT_GET/BATCH_POINT_GET for issue 21653
func (s *testSessionSuite2) TestPointGetMemoryTracking(c *C) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Could you directly validate the tracked memory usage?
  2. Please also add tests for clustered index whose type is not an integer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't directly validate the memory usage,do you have some advices to do it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, what is the difference between integer and others, why need add tests for clustered index whose type is not an integer.

tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t1(a int primary key);")
config.UpdateGlobal(func(conf *config.Config) {
conf.OOMAction = config.OOMActionCancel
})
tk.MustExec("insert into t1 values (1);")
tk.MustQuery("select * from t1 where a = 1;").Check(testkit.Rows("1"))
tk.MustExec("set tidb_mem_quota_query=1;")
err := tk.QueryToErr("select * from t1 where a = 1;")
wshwsh12 marked this conversation as resolved.
Show resolved Hide resolved
c.Assert(err, NotNil)
c.Assert(err.Error(), Matches, "Out Of Memory Quota!.*")
err = tk.QueryToErr("select * from t1 where a in (1,2,3);")
c.Assert(err, NotNil)
c.Assert(err.Error(), Matches, "Out Of Memory Quota!.*")
tk.MustExec("set tidb_mem_quota_query=1024;")
tk.MustQuery("select * from t1 where a = 1;").Check(testkit.Rows("1"))
err = tk.QueryToErr("select * from t1 where a = 1;")
c.Check(err, IsNil)
err = tk.QueryToErr("select * from t1 where a in (1,2,3);")
c.Check(err, IsNil)
}

func (s *testSessionSuite3) TestPessimisticLockOnPartition(c *C) {
// This test checks that 'select ... for update' locks the partition instead of the table.
// Cover a bug that table ID is used to encode the lock key mistakenly.
Expand Down