There appears to be a potential data race risk related to pointer usage in client_batch.go.
Specifically, the following fields are accessed without any explicit synchronization or protection:
|
// batchCommandsBuilder collects a batch of `batchCommandsEntry`s to build |
|
// `BatchCommandsRequest`s. |
|
type batchCommandsBuilder struct { |
|
// Each BatchCommandsRequest_Request sent to a store has a unique identity to |
|
// distinguish its response. |
|
idAlloc uint64 |
|
entries *PriorityQueue |
|
requests []*tikvpb.BatchCommandsRequest_Request |
|
requestIDs []uint64 |
|
// In most cases, there isn't any forwardingReq. |
|
forwardingReqs map[string]*tikvpb.BatchCommandsRequest |
|
|
|
latestReqStartTime time.Time |
|
} |
At the same time, the code attempts to avoid concurrent execution in the following sections:
|
// reset resets the builder to the initial state. |
|
// Should call it before collecting a new batch. |
|
func (b *batchCommandsBuilder) reset() { |
|
b.entries.clean() |
|
// 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. |
|
for i := 0; i < len(b.requests); i++ { |
|
b.requests[i] = nil |
|
} |
|
b.requests = b.requests[:0] |
|
b.requestIDs = b.requestIDs[:0] |
|
|
|
for k := range b.forwardingReqs { |
|
delete(b.forwardingReqs, k) |
|
} |
|
} |
https://github.com/tikv/client-go/blob/01cdf70d1ad66f0c870410abb869ee2867c08da7/internal/client/client_batch.go#L152C32-L152C46
However, it seems that these checks do not fully prevent concurrent access to the underlying data structures.
In particular, the following shared fields appear to be vulnerable to concurrent read/write access:
entries *PriorityQueue
requests []*tikvpb.BatchCommandsRequest_Request
Since these pointers (and the data they reference) are mutated across different code paths without clear locking or ownership guarantees, a data race may occur under concurrent execution.
related PR:
this PR(#1242) does not fully fix the issue reported in: pingcap/tidb#51921 , We are still encountering a similar issue even after this PR was merged, which suggests that the underlying concurrency problem may remain unresolved.
There appears to be a potential data race risk related to pointer usage in client_batch.go.
Specifically, the following fields are accessed without any explicit synchronization or protection:
client-go/internal/client/client_batch.go
Lines 115 to 128 in 01cdf70
At the same time, the code attempts to avoid concurrent execution in the following sections:
client-go/internal/client/client_batch.go
Lines 208 to 225 in 01cdf70
https://github.com/tikv/client-go/blob/01cdf70d1ad66f0c870410abb869ee2867c08da7/internal/client/client_batch.go#L152C32-L152C46
However, it seems that these checks do not fully prevent concurrent access to the underlying data structures.
In particular, the following shared fields appear to be vulnerable to concurrent read/write access:
Since these pointers (and the data they reference) are mutated across different code paths without clear locking or ownership guarantees, a data race may occur under concurrent execution.
related PR:
this PR(#1242) does not fully fix the issue reported in: pingcap/tidb#51921 , We are still encountering a similar issue even after this PR was merged, which suggests that the underlying concurrency problem may remain unresolved.