sstables: clean up TemporaryHashes file in wipe()

The TemporaryHashes.db.tmp file is created during SSTable writing to
store intermediate bloom filter hashes and is deleted before the SSTable
is sealed. Since it is not tracked in the TOC, it is also absent from
_recognized_components and all_components().

When an SSTable write fails before sealing (e.g. streaming rejected due
to critical disk utilization), wipe() is called to clean up the partial
SSTable. However, wipe() only iterates over all_components(), so the
TemporaryHashes file was left behind as an orphan.

Previously, the only cleanup mechanism for this file was the
startup-time directory scanner in sstable_directory, which would not
help when the orphan needs to be cleaned up at runtime.

Explicitly remove the TemporaryHashes file in wipe(), ignoring ENOENT
for the common case where the file was already removed before sealing.
This commit is contained in:
Łukasz Paszkowski
2026-03-24 12:11:31 +01:00
parent 159675e975
commit 8d34127684

View File

@@ -538,6 +538,17 @@ future<> filesystem_storage::wipe(const sstable& sst, sync_dir sync) noexcept {
sstlog.debug("Forgiving ENOENT when deleting file {}", fname);
}
});
// TemporaryHashes is not tracked in recognized_components (and thus
// not in all_components()), because it is a transient file created
// during SSTable writing and removed before sealing. If the write
// failed before sealing, the file may still be on disk and must be
// cleaned up explicitly.
// Use file_exists() to avoid a C++ exception on the common path
// where the file was already removed before sealing.
auto temp_hashes = filename(sst, dir_name.native(), sst._generation, component_type::TemporaryHashes);
if (co_await file_exists(temp_hashes)) {
co_await sst.sstable_write_io_check(remove_file, std::move(temp_hashes));
}
if (sync) {
co_await sst.sstable_write_io_check(sync_directory, dir_name.native());
}