From b10d1a58c718bce8c3ed364d85781a4fade45e9c Mon Sep 17 00:00:00 2001 From: pingcap-github-bot Date: Thu, 12 Dec 2019 11:05:58 +0800 Subject: [PATCH] store/tikv: fix a memory leak in the batchClient for the large transactions (#14031) (#14032) --- store/tikv/client_batch.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/store/tikv/client_batch.go b/store/tikv/client_batch.go index 1f349c70b9a8f..ae14f3522b528 100644 --- a/store/tikv/client_batch.go +++ b/store/tikv/client_batch.go @@ -398,6 +398,22 @@ func (b *batchCommandsEntry) isCanceled() bool { const idleTimeout = 3 * time.Minute +func resetEntries(entries []*batchCommandsEntry) []*batchCommandsEntry { + for i := 0; i < len(entries); i++ { + entries[i] = nil + } + entries = entries[:0] + return entries +} + +func resetRequests(requests []*tikvpb.BatchCommandsRequest_Request) []*tikvpb.BatchCommandsRequest_Request { + for i := 0; i < len(requests); i++ { + requests[i] = nil + } + requests = requests[:0] + return requests +} + func (a *batchConn) batchSendLoop(cfg config.TiKVClient) { defer func() { if r := recover(); r != nil { @@ -416,8 +432,12 @@ func (a *batchConn) batchSendLoop(cfg config.TiKVClient) { var bestBatchWaitSize = cfg.BatchWaitSize for { - entries = entries[:0] - requests = requests[:0] + // NOTE: We can't simply set entries = entries[:0] here. + // The data in the cap part of the slice would reference the prewrite keys whose + // underlying memory is borrowed from memdb. The reference cause GC can't release + // the memdb, leading to serious memory leak problems in the large transaction case. + entries = resetEntries(entries) + requests = resetRequests(requests) requestIDs = requestIDs[:0] a.pendingRequests.Set(float64(len(a.batchCommandsCh)))