fix: optimize after crash recovery without opening wal (#600)

This commit is contained in:
feihongxu0824 2026-07-17 16:56:21 +08:00 committed by GitHub
parent a5dfec6a65
commit e89be98bb3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 3 deletions

View File

@ -4224,8 +4224,6 @@ Status SegmentImpl::recover() {
wal_file_path.c_str());
return Status::OK();
}
AILEGO_DEFER([&]() { recover_wal_file->close(); });
std::array<uint64_t, static_cast<size_t>(Operator::DELETE) + 1>
recovered_doc_count{};
uint64_t total_recovered_doc_count{0};
@ -4309,7 +4307,17 @@ Status SegmentImpl::recover() {
(size_t)recovered_doc_count[3] // DELETE
);
return Status::OK();
if (recover_wal_file->close() != 0) {
return Status::InternalError("Failed to close recovered wal file: ",
wal_file_path);
}
recover_wal_file.reset();
// Keep the recovered WAL attached to the segment. Operations such as
// optimize() flush the writing segment before sealing it; without an open
// member WAL, flush() treats the recovered memory components as empty and
// returns without persisting them.
return open_wal_file();
}
Status SegmentImpl::open_wal_file() {

View File

@ -218,6 +218,39 @@ TEST_F(CrashRecoveryTest, CrashRecoveryDuringInsertion) {
}
TEST_F(CrashRecoveryTest, OptimizeAfterCrashRecoveryPersistsReplayedData) {
{
auto schema = CreateTestSchema(collection_name_);
auto result = Collection::CreateAndOpen(dir_path_, *schema, options_);
ASSERT_TRUE(result.has_value()) << result.error().message();
}
RunGeneratorAndCrash("0", "10000", "insert", "0", 1);
uint64_t recovered_doc_count = 0;
{
auto result = Collection::Open(dir_path_, options_);
ASSERT_TRUE(result.has_value())
<< "Failed to reopen collection after crash recovery";
auto collection = result.value();
recovered_doc_count = collection->Stats().value().doc_count;
ASSERT_GT(recovered_doc_count, 0)
<< "No documents were recovered from the WAL";
auto status = collection->Optimize();
ASSERT_TRUE(status.ok()) << status.message();
ASSERT_EQ(collection->Stats().value().doc_count, recovered_doc_count);
}
auto result = Collection::Open(dir_path_, options_);
ASSERT_TRUE(result.has_value())
<< "Failed to reopen collection after optimizing recovered data";
ASSERT_EQ(result.value()->Stats().value().doc_count, recovered_doc_count)
<< "Optimize discarded documents restored from the WAL";
}
TEST_F(CrashRecoveryTest, CrashRecoveryDuringUpsert) {
{
auto schema = CreateTestSchema(collection_name_);