fix(buffer_storage): vector block leak (#434)

This commit is contained in:
ZeFeng Yin 2026-06-02 10:19:38 +08:00 committed by GitHub
parent 8ce8e3e228
commit 0807adeec5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 32 additions and 2 deletions

View File

@ -208,8 +208,14 @@ class BufferStorage : public IndexStorage {
}
*data = raw;
// Pin held until close_index() per the never-released contract
// of this overload.
(void)page_id;
// of this overload. Record the page so close_index() can release
// the pin before tearing down the pool; otherwise the lingering
// ref_count would trip ~VecBufferPool's "all blocks released"
// assertion.
{
std::lock_guard<std::mutex> pin_latch(owner_->pinned_pages_mutex_);
owner_->pinned_pages_.push_back(page_id);
}
return len;
}
// Cross-page path: see file-level banner. C11 aligned_alloc requires
@ -1011,6 +1017,20 @@ class BufferStorage : public IndexStorage {
}
tmp_buffers_.clear();
}
// Release every page pinned by the single-page read(const void**)
// overload (the never-released contract holds the pin until here).
// Each pin incremented the page table ref_count, so we must drop the
// matching reference before resetting the pool, otherwise
// ~VecBufferPool asserts that all blocks were released.
{
std::lock_guard<std::mutex> pin_latch(pinned_pages_mutex_);
if (buffer_pool_handle_) {
for (size_t pid : pinned_pages_) {
buffer_pool_handle_->release_one(pid);
}
}
pinned_pages_.clear();
}
buffer_pool_handle_.reset();
buffer_pool_.reset();
max_segment_size_ = 0;
@ -1476,6 +1496,16 @@ class BufferStorage : public IndexStorage {
std::vector<ArenaBlock> tmp_buffers_{};
mutable std::mutex tmp_buffers_mutex_{};
// Page ids pinned by the single-page read(const void**) overload, which
// keeps the pin alive until close_index() (the never-released contract).
// Each pin increments the page table ref_count, so close_index() must
// release every recorded pin before tearing down the pool; otherwise
// ~VecBufferPool fires its "all blocks released" assertion. Duplicates are
// allowed: repeated single-page reads of the same page each take a pin and
// therefore each need a matching release.
std::vector<size_t> pinned_pages_{};
mutable std::mutex pinned_pages_mutex_{};
// buffer manager
std::string file_name_;
// Per-chain owning copies of MetaHeader. segments_[name].segment_header