mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-11 10:25:47 +02:00
fix(server): mget crash on same key get (#2474)
* fix(server): mget crash on same key get
fix: #2465
the bug: on cache mode mget bumps up items. When executing mget with the same key several times i.e mget key key we will invalidate the iterator when we bump up the item in dash table.
the fix: bump up/down items only once by using bumped_items set
This PR also reverts c225113
and updates the bumped stats and bumped_items set if the item was bumped
Signed-off-by: adi_holden <adi@dragonflydb.io>
This commit is contained in:
parent
3ebb32df3f
commit
9f4c4353b5
6 changed files with 62 additions and 37 deletions
|
@ -117,16 +117,16 @@ class PrimeEvictionPolicy {
|
|||
|
||||
class PrimeBumpPolicy {
|
||||
public:
|
||||
PrimeBumpPolicy(const absl::flat_hash_set<CompactObjectView>& bumped_items)
|
||||
: bumped_items_(bumped_items) {
|
||||
PrimeBumpPolicy(const absl::flat_hash_set<CompactObjectView>& fetched_items)
|
||||
: fetched_items_(fetched_items) {
|
||||
}
|
||||
// returns true if key can be made less important for eviction (opposite of bump up)
|
||||
bool CanBumpDown(const CompactObj& obj) const {
|
||||
return !obj.IsSticky() && !bumped_items_.contains(obj);
|
||||
// returns true if we can change the object location in dash table.
|
||||
bool CanBump(const CompactObj& obj) const {
|
||||
return !obj.IsSticky() && !fetched_items_.contains(obj);
|
||||
}
|
||||
|
||||
private:
|
||||
const absl::flat_hash_set<CompactObjectView>& bumped_items_;
|
||||
const absl::flat_hash_set<CompactObjectView>& fetched_items_;
|
||||
};
|
||||
|
||||
bool PrimeEvictionPolicy::CanGrow(const PrimeTable& tbl) const {
|
||||
|
@ -497,9 +497,12 @@ OpResult<DbSlice::ItAndExp> DbSlice::FindInternal(const Context& cntx, std::stri
|
|||
};
|
||||
db.prime.CVCUponBump(change_cb_.back().first, res.it, bump_cb);
|
||||
}
|
||||
res.it = db.prime.BumpUp(res.it, PrimeBumpPolicy{bumped_items_});
|
||||
++events_.bumpups;
|
||||
bumped_items_.insert(res.it->first.AsRef());
|
||||
auto bump_it = db.prime.BumpUp(res.it, PrimeBumpPolicy{fetched_items_});
|
||||
if (bump_it != res.it) { // the item was bumped
|
||||
res.it = bump_it;
|
||||
++events_.bumpups;
|
||||
}
|
||||
fetched_items_.insert(res.it->first.AsRef());
|
||||
}
|
||||
|
||||
db.top_keys.Touch(key);
|
||||
|
@ -673,7 +676,7 @@ bool DbSlice::Del(DbIndex db_ind, PrimeIterator it) {
|
|||
DbContext cntx{db_ind, GetCurrentTimeMs()};
|
||||
doc_del_cb_(key, cntx, it->second);
|
||||
}
|
||||
bumped_items_.erase(it->first.AsRef());
|
||||
fetched_items_.erase(it->first.AsRef());
|
||||
PerformDeletion(it, db.get());
|
||||
deletion_count_++;
|
||||
|
||||
|
@ -734,7 +737,7 @@ void DbSlice::FlushDbIndexes(const std::vector<DbIndex>& indexes) {
|
|||
tiered->CancelAllIos(index);
|
||||
}
|
||||
}
|
||||
CHECK(bumped_items_.empty());
|
||||
CHECK(fetched_items_.empty());
|
||||
auto cb = [this, flush_db_arr = std::move(flush_db_arr)]() mutable {
|
||||
for (auto& db_ptr : flush_db_arr) {
|
||||
if (db_ptr && db_ptr->stats.tiered_entries > 0) {
|
||||
|
@ -1536,7 +1539,7 @@ void DbSlice::PerformDeletion(PrimeIterator del_it, DbTable* table) {
|
|||
void DbSlice::OnCbFinish() {
|
||||
// TBD update bumpups logic we can not clear now after cb finish as cb can preempt
|
||||
// btw what do we do with inline?
|
||||
bumped_items_.clear();
|
||||
fetched_items_.clear();
|
||||
}
|
||||
|
||||
} // namespace dfly
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue