From ae7e43249a350368bf4a28479c10df7950e01827 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 11 Jan 2021 13:47:58 +0800 Subject: [PATCH] store/tikv: fix a concurrency bug that may cause the batchClient timeout (#22239) --- store/tikv/client.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/store/tikv/client.go b/store/tikv/client.go index 315c6964fd96a..4cc159c0d1271 100644 --- a/store/tikv/client.go +++ b/store/tikv/client.go @@ -229,6 +229,9 @@ type rpcClient struct { security config.Security idleNotify uint32 + // recycleMu protect the conns from being modified during a connArray is taken out and used. + // That means recycleIdleConnArray() will wait until nobody doing sendBatchRequest() + recycleMu sync.RWMutex // Periodically check whether there is any connection that is idle and then close and remove these connections. // Implement background cleanup. isClosed bool @@ -344,11 +347,15 @@ func (c *rpcClient) SendRequest(ctx context.Context, addr string, req *tikvrpc.R }() if atomic.CompareAndSwapUint32(&c.idleNotify, 1, 0) { + c.recycleMu.Lock() c.recycleIdleConnArray() + c.recycleMu.Unlock() } // TiDB will not send batch commands to TiFlash, to resolve the conflict with Batch Cop Request. enableBatch := req.StoreTp != kv.TiDB && req.StoreTp != kv.TiFlash + c.recycleMu.RLock() + defer c.recycleMu.RUnlock() connArray, err := c.getConnArray(addr, enableBatch) if err != nil { return nil, errors.Trace(err)