@@ -34,8 +34,10 @@ import (
34
34
"github.com/pingcap/tidb/pkg/util/chunk"
35
35
"github.com/pingcap/tidb/pkg/util/disk"
36
36
"github.com/pingcap/tidb/pkg/util/hack"
37
+ "github.com/pingcap/tidb/pkg/util/logutil"
37
38
"github.com/pingcap/tidb/pkg/util/memory"
38
39
"github.com/pingcap/tidb/pkg/util/set"
40
+ "go.uber.org/zap"
39
41
)
40
42
41
43
// HashAggInput indicates the input of hash agg exec.
@@ -154,6 +156,8 @@ type HashAggExec struct {
154
156
spillHelper * parallelHashAggSpillHelper
155
157
// isChildDrained indicates whether the all data from child has been taken out.
156
158
isChildDrained bool
159
+
160
+ invalidMemoryUsageForTrackingTest bool
157
161
}
158
162
159
163
// Close implements the Executor Close interface.
@@ -204,6 +208,10 @@ func (e *HashAggExec) Close() error {
204
208
channel .Clear (e .finalOutputCh )
205
209
e .executed .Store (false )
206
210
if e .memTracker != nil {
211
+ if e .memTracker .BytesConsumed () < 0 {
212
+ logutil .BgLogger ().Warn ("Memory tracker's counter is invalid" , zap .Int64 ("counter" , e .memTracker .BytesConsumed ()))
213
+ e .invalidMemoryUsageForTrackingTest = true
214
+ }
207
215
e .memTracker .ReplaceBytesUsed (0 )
208
216
}
209
217
e .parallelExecValid = false
@@ -289,6 +297,8 @@ func (e *HashAggExec) initForUnparallelExec() {
289
297
}
290
298
291
299
func (e * HashAggExec ) initPartialWorkers (partialConcurrency int , finalConcurrency int , ctx sessionctx.Context ) {
300
+ memUsage := int64 (0 )
301
+
292
302
for i := 0 ; i < partialConcurrency ; i ++ {
293
303
partialResultsMap := make ([]aggfuncs.AggPartialResultMapper , finalConcurrency )
294
304
for i := 0 ; i < finalConcurrency ; i ++ {
@@ -316,6 +326,8 @@ func (e *HashAggExec) initPartialWorkers(partialConcurrency int, finalConcurrenc
316
326
inflightChunkSync : e .inflightChunkSync ,
317
327
}
318
328
329
+ memUsage += e .partialWorkers [i ].chk .MemoryUsage ()
330
+
319
331
e .partialWorkers [i ].partialResultNumInRow = e .partialWorkers [i ].getPartialResultSliceLenConsiderByteAlign ()
320
332
for j := 0 ; j < finalConcurrency ; j ++ {
321
333
e .partialWorkers [i ].BInMaps [j ] = 0
@@ -332,8 +344,11 @@ func (e *HashAggExec) initPartialWorkers(partialConcurrency int, finalConcurrenc
332
344
chk : chunk .New (e .Children (0 ).RetFieldTypes (), 0 , e .MaxChunkSize ()),
333
345
giveBackCh : e .partialWorkers [i ].inputCh ,
334
346
}
347
+ memUsage += input .chk .MemoryUsage ()
335
348
e .inputCh <- input
336
349
}
350
+
351
+ e .memTracker .Consume (memUsage )
337
352
}
338
353
339
354
func (e * HashAggExec ) initFinalWorkers (finalConcurrency int ) {
@@ -442,6 +457,7 @@ func (e *HashAggExec) fetchChildData(ctx context.Context, waitGroup *sync.WaitGr
442
457
ok bool
443
458
err error
444
459
)
460
+
445
461
defer func () {
446
462
if r := recover (); r != nil {
447
463
recoveryHashAgg (e .finalOutputCh , r )
@@ -494,6 +510,7 @@ func (e *HashAggExec) fetchChildData(ctx context.Context, waitGroup *sync.WaitGr
494
510
input .giveBackCh <- chk
495
511
496
512
if hasError := e .spillIfNeed (); hasError {
513
+ e .memTracker .Consume (- mSize )
497
514
return
498
515
}
499
516
}
@@ -857,3 +874,8 @@ func (e *HashAggExec) IsSpillTriggeredForTest() bool {
857
874
}
858
875
return false
859
876
}
877
+
878
+ // IsInvalidMemoryUsageTrackingForTest is for test
879
+ func (e * HashAggExec ) IsInvalidMemoryUsageTrackingForTest () bool {
880
+ return e .invalidMemoryUsageForTrackingTest
881
+ }
0 commit comments