@@ -114,7 +114,8 @@ type hashRowContainer struct {
114
114
memTracker * memory.Tracker
115
115
116
116
// chkBuf buffer the data reads from the disk if rowContainer is spilled.
117
- chkBuf * chunk.Chunk
117
+ chkBuf * chunk.Chunk
118
+ chkBufSizeForOneProbe int64
118
119
}
119
120
120
121
func newHashRowContainer (sCtx sessionctx.Context , hCtx * hashContext , allTypes []* types.FieldType ) * hashRowContainer {
@@ -213,6 +214,15 @@ func (c *hashRowContainer) GetAllMatchedRows(probeHCtx *hashContext, probeSideRo
213
214
return matched , nil
214
215
}
215
216
217
+ // signalCheckpointForJoinMask indicates the times of row probe that a signal detection will be triggered.
218
+ const signalCheckpointForJoinMask int = 1 << 14 - 1
219
+
220
+ // rowSize is the size of Row.
221
+ const rowSize = int64 (unsafe .Sizeof (chunk.Row {}))
222
+
223
+ // rowPtrSize is the size of RowPtr.
224
+ const rowPtrSize = int64 (unsafe .Sizeof (chunk.RowPtr {}))
225
+
216
226
// GetMatchedRowsAndPtrs get matched rows and Ptrs from probeRow. It can be called
217
227
// in multiple goroutines while each goroutine should keep its own
218
228
// h and buf.
@@ -225,7 +235,23 @@ func (c *hashRowContainer) GetMatchedRowsAndPtrs(probeKey uint64, probeRow chunk
225
235
matched = matched [:0 ]
226
236
var matchedRow chunk.Row
227
237
matchedPtrs = matchedPtrs [:0 ]
228
- for _ , ptr := range innerPtrs {
238
+
239
+ // Some variables used for memTracker.
240
+ var (
241
+ matchedDataSize = int64 (cap (matched ))* rowSize + int64 (cap (matchedPtrs ))* rowPtrSize
242
+ lastChunkBufPointer * chunk.Chunk = nil
243
+ memDelta int64 = 0
244
+ needTrackMemUsage = cap (innerPtrs ) > signalCheckpointForJoinMask
245
+ )
246
+ c .chkBuf = nil
247
+ c .memTracker .Consume (- c .chkBufSizeForOneProbe )
248
+ if needTrackMemUsage {
249
+ c .memTracker .Consume (int64 (cap (innerPtrs )) * rowPtrSize )
250
+ defer c .memTracker .Consume (- int64 (cap (innerPtrs ))* rowPtrSize + memDelta )
251
+ }
252
+ c .chkBufSizeForOneProbe = 0
253
+
254
+ for i , ptr := range innerPtrs {
229
255
matchedRow , c .chkBuf , err = c .rowContainer .GetRowAndAppendToChunk (ptr , c .chkBuf )
230
256
if err != nil {
231
257
return nil , nil , err
@@ -235,6 +261,19 @@ func (c *hashRowContainer) GetMatchedRowsAndPtrs(probeKey uint64, probeRow chunk
235
261
if err != nil {
236
262
return nil , nil , err
237
263
}
264
+ if needTrackMemUsage && c .chkBuf != lastChunkBufPointer && lastChunkBufPointer != nil {
265
+ lastChunkSize := lastChunkBufPointer .MemoryUsage ()
266
+ c .chkBufSizeForOneProbe += lastChunkSize
267
+ memDelta += lastChunkSize
268
+ }
269
+ lastChunkBufPointer = c .chkBuf
270
+ if needTrackMemUsage && (i & signalCheckpointForJoinMask == signalCheckpointForJoinMask ) {
271
+ // Trigger Consume for checking the OOM Action signal
272
+ memDelta += int64 (cap (matched ))* rowSize + int64 (cap (matchedPtrs ))* rowPtrSize - matchedDataSize
273
+ matchedDataSize = int64 (cap (matched ))* rowSize + int64 (cap (matchedPtrs ))* rowPtrSize
274
+ c .memTracker .Consume (memDelta + 1 )
275
+ memDelta = 0
276
+ }
238
277
if ! ok {
239
278
atomic .AddInt64 (& c .stat .probeCollision , 1 )
240
279
continue
0 commit comments