@@ -154,6 +154,8 @@ type HashAggExec struct {
154
154
spillHelper * parallelHashAggSpillHelper
155
155
// isChildDrained indicates whether the all data from child has been taken out.
156
156
isChildDrained bool
157
+
158
+ invalidMemoryUsageForTrackingTest bool
157
159
}
158
160
159
161
// Close implements the Executor Close interface.
@@ -204,7 +206,11 @@ func (e *HashAggExec) Close() error {
204
206
channel .Clear (e .finalOutputCh )
205
207
e .executed .Store (false )
206
208
if e .memTracker != nil {
207
- e .memTracker .ReplaceBytesUsed (0 )
209
+ if e .memTracker .BytesConsumed () < 0 {
210
+ e .invalidMemoryUsageForTrackingTest = true
211
+ } else {
212
+ e .memTracker .ReplaceBytesUsed (0 )
213
+ }
208
214
}
209
215
e .parallelExecValid = false
210
216
if e .parallelAggSpillAction != nil {
@@ -285,6 +291,8 @@ func (e *HashAggExec) initForUnparallelExec() {
285
291
}
286
292
287
293
func (e * HashAggExec ) initPartialWorkers (partialConcurrency int , finalConcurrency int , ctx sessionctx.Context ) {
294
+ memUsage := int64 (0 )
295
+
288
296
for i := 0 ; i < partialConcurrency ; i ++ {
289
297
partialResultsMap := make ([]aggfuncs.AggPartialResultMapper , finalConcurrency )
290
298
for i := 0 ; i < finalConcurrency ; i ++ {
@@ -311,6 +319,8 @@ func (e *HashAggExec) initPartialWorkers(partialConcurrency int, finalConcurrenc
311
319
inflightChunkSync : e .inflightChunkSync ,
312
320
}
313
321
322
+ memUsage += e .partialWorkers [i ].chk .MemoryUsage ()
323
+
314
324
e .partialWorkers [i ].partialResultNumInRow = e .partialWorkers [i ].getPartialResultSliceLenConsiderByteAlign ()
315
325
for j := 0 ; j < finalConcurrency ; j ++ {
316
326
e .partialWorkers [i ].BInMaps [j ] = 0
@@ -328,9 +338,11 @@ func (e *HashAggExec) initPartialWorkers(partialConcurrency int, finalConcurrenc
328
338
chk : exec .NewFirstChunk (e .Children (0 )),
329
339
giveBackCh : e .partialWorkers [i ].inputCh ,
330
340
}
331
- e . memTracker . Consume ( input .chk .MemoryUsage () )
341
+ memUsage += input .chk .MemoryUsage ()
332
342
e .inputCh <- input
333
343
}
344
+
345
+ e .memTracker .Consume (memUsage )
334
346
}
335
347
336
348
func (e * HashAggExec ) initFinalWorkers (finalConcurrency int ) {
@@ -442,6 +454,7 @@ func (e *HashAggExec) fetchChildData(ctx context.Context, waitGroup *sync.WaitGr
442
454
ok bool
443
455
err error
444
456
)
457
+
445
458
defer func () {
446
459
if r := recover (); r != nil {
447
460
recoveryHashAgg (e .finalOutputCh , r )
@@ -494,6 +507,7 @@ func (e *HashAggExec) fetchChildData(ctx context.Context, waitGroup *sync.WaitGr
494
507
input .giveBackCh <- chk
495
508
496
509
if hasError := e .spillIfNeed (); hasError {
510
+ e .memTracker .Consume (- mSize )
497
511
return
498
512
}
499
513
}
@@ -857,3 +871,8 @@ func (e *HashAggExec) IsSpillTriggeredForTest() bool {
857
871
}
858
872
return false
859
873
}
874
+
875
+ // IsInvalidMemoryUsageTrackingForTest is for test
876
+ func (e * HashAggExec ) IsInvalidMemoryUsageTrackingForTest () bool {
877
+ return e .invalidMemoryUsageForTrackingTest
878
+ }
0 commit comments