fix: properly clear tiered stashes upon expirations (#4395)

Fixes #4387

Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
Roman Gershman 2025-01-02 15:49:13 +02:00 committed by GitHub
parent 0832d23f13
commit 6e9409c65c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 17 additions and 4 deletions

View file

@ -1479,9 +1479,13 @@ void DbSlice::PerformDeletion(Iterator del_it, ExpIterator exp_it, DbTable* tabl
} }
DbTableStats& stats = table->stats; DbTableStats& stats = table->stats;
const PrimeValue& pv = del_it->second; PrimeValue& pv = del_it->second;
if (pv.IsExternal() && shard_owner()->tiered_storage()) { if (pv.HasStashPending()) {
string scratch;
string_view key = del_it->first.GetSlice(&scratch);
shard_owner()->tiered_storage()->CancelStash(table->index, key, &pv);
} else if (pv.IsExternal()) {
shard_owner()->tiered_storage()->Delete(table->index, &del_it->second); shard_owner()->tiered_storage()->Delete(table->index, &del_it->second);
} }

View file

@ -487,7 +487,7 @@ void Driver::ParseRESP() {
PopRequest(); PopRequest();
} }
io_buf_.ConsumeInput(consumed); io_buf_.ConsumeInput(consumed);
} while (result == RedisParser::OK); } while (result == RedisParser::OK && io_buf_.InputLen() > 0);
} }
void Driver::ParseMC() { void Driver::ParseMC() {

View file

@ -391,7 +391,7 @@ bool TieredStorage::TryStash(DbIndex dbid, string_view key, PrimeValue* value) {
return false; return false;
// This invariant should always hold because ShouldStash tests for IoPending flag. // This invariant should always hold because ShouldStash tests for IoPending flag.
DCHECK(!bins_->IsPending(dbid, key)); CHECK(!bins_->IsPending(dbid, key));
// TODO: When we are low on memory we should introduce a back-pressure, to avoid OOMs // TODO: When we are low on memory we should introduce a back-pressure, to avoid OOMs
// with a lot of underutilized disk space. // with a lot of underutilized disk space.

View file

@ -317,4 +317,13 @@ TEST_F(TieredStorageTest, MemoryPressure) {
EXPECT_LT(used_mem_peak.load(), 20_MB); EXPECT_LT(used_mem_peak.load(), 20_MB);
} }
TEST_F(TieredStorageTest, Expiry) {
string val = BuildString(100);
Run({"psetex", "key1", "1", val});
AdvanceTime(10);
Run({"psetex", "key1", "1", val});
auto resp = Run({"get", "key1"});
EXPECT_EQ(resp, val);
}
} // namespace dfly } // namespace dfly