From 0e56a09f70de57bfb52dcd438326a65ae20d386b Mon Sep 17 00:00:00 2001 From: Roman Gershman Date: Tue, 25 Feb 2025 13:21:44 +0200 Subject: [PATCH] fix: do not crash upon inconsistent expire iterator (#4658) Fixes #4656 Signed-off-by: Roman Gershman --- src/server/db_slice.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/server/db_slice.cc b/src/server/db_slice.cc index 4e2c57577..61ba0f7b3 100644 --- a/src/server/db_slice.cc +++ b/src/server/db_slice.cc @@ -1220,7 +1220,7 @@ auto DbSlice::DeleteExpiredStep(const Context& cntx, unsigned count) -> DeleteEx std::string stash; auto cb = [&](ExpireIterator it) { - auto key = it->first.GetSlice(&stash); + string_view key = it->first.GetSlice(&stash); if (!CheckLock(IntentLock::EXCLUSIVE, cntx.db_index, key)) return; @@ -1228,9 +1228,16 @@ auto DbSlice::DeleteExpiredStep(const Context& cntx, unsigned count) -> DeleteEx time_t ttl = ExpireTime(it) - cntx.time_now_ms; if (ttl <= 0) { auto prime_it = db.prime.Find(it->first); - CHECK(!prime_it.is_done()); - result.deleted_bytes += prime_it->first.MallocUsed() + prime_it->second.MallocUsed(); - ExpireIfNeeded(cntx, prime_it); + if (prime_it.is_done()) { // A workaround for the case our tables are inconsistent. + LOG(DFATAL) << "Expired key " << key << " not found in prime table, expire_done: " + << it.is_done(); + if (!it.is_done()) { + db.expire.Erase(it->first); + } + } else { + result.deleted_bytes += prime_it->first.MallocUsed() + prime_it->second.MallocUsed(); + ExpireIfNeeded(cntx, prime_it); + } ++result.deleted; } else { result.survivor_ttl_sum += ttl;