-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Bug Report
What happened
Memory usage in TiKV grows unboundedly over time, particularly in the concurrency_manager LockTable. After leader eviction (QPS drops to 0), memory usage remains high and does not decrease.
What did you expect to happen
Memory should be reclaimed after locks are released and GC runs.
Root Cause
The bug is in crossbeam-skiplist's RefRange iterator (base.rs).
RefRange::next() and next_back() use clone_from() to update self.head/self.tail:
self.head.clone_from(&next_head);Since RefEntry has no Drop implementation (by design - callers must explicitly call release()), the old entry is dropped without decrementing its refcount. This causes permanent memory leaks.
The correct pattern (used in RefIter::next()) is:
if let Some(e) = mem::replace(&mut self.head, next_head.clone()) {
unsafe { e.node.decrement(guard); }
}Impact
Any code using SkipMap::range() iterators leaks memory. In TiKV, this affects:
LockTable::check_range()LockTable::find_first()
Reproduction
Stress test results (10 seconds, range iteration + insert/remove cycle):
before fix:
t=10s ops=11786 len=7530 alloc=3MB
after fix:
t=10s ops=11710 len=3422 alloc=613MB
Versions
- v6.5.6 <= version <= v8.5