diff --git a/HISTORY.md b/HISTORY.md index c29f8d51e..8fb5ffa62 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,8 @@ # Rocksdb Change Log +## 6.23.4 (2021-08-31) +### Bug Fixes +* Fix a race in item ref counting in LRUCache when promoting an item from the SecondaryCache. + ## 6.23.3 (2021-08-09) ### Bug Fixes * Removed a call to `RenameFile()` on a non-existent info log file ("LOG") when opening a new DB. Such a call was guaranteed to fail though did not impact applications since we swallowed the error. Now we also stopped swallowing errors in renaming "LOG" file. diff --git a/cache/lru_cache.cc b/cache/lru_cache.cc index db60828c0..e43e8e5a0 100644 --- a/cache/lru_cache.cc +++ b/cache/lru_cache.cc @@ -358,7 +358,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); } } @@ -396,11 +399,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());