diff --git a/HISTORY.md b/HISTORY.md index 3add487c7..3221553b7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,8 @@ # Rocksdb Change Log +## 6.24.1 (2021-08-31) +### Bug Fixes +* Fix a race in item ref counting in LRUCache when promoting an item from the SecondaryCache. + ## 6.24.0 (2021-08-20) ### Bug Fixes * If the primary's CURRENT file is missing or inaccessible, the secondary instance should not hang repeatedly trying to switch to a new MANIFEST. It should instead return the error code encountered while accessing the file. diff --git a/cache/lru_cache.cc b/cache/lru_cache.cc index 689242ca9..bab58a2a2 100644 --- a/cache/lru_cache.cc +++ b/cache/lru_cache.cc @@ -360,7 +360,10 @@ Status LRUCacheShard::InsertItem(LRUHandle* e, Cache::Handle** handle, if (handle == nullptr) { LRU_Insert(e); } else { - e->Ref(); + // If caller already holds a ref, no need to take one here + if (!e->HasRefs()) { + e->Ref(); + } *handle = reinterpret_cast(e); } } @@ -398,11 +401,7 @@ void LRUCacheShard::Promote(LRUHandle* e) { if (e->value) { Cache::Handle* handle = reinterpret_cast(e); Status s = InsertItem(e, &handle, /*free_handle_on_fail=*/false); - if (s.ok()) { - // InsertItem would have taken a reference on the item, so decrement it - // here as we expect the caller to already hold a reference - e->Unref(); - } else { + if (!s.ok()) { // Item is in memory, but not accounted against the cache capacity. // When the handle is released, the item should get deleted assert(!e->InCache());