Skip to content

Commit e89be98

Browse files
fix: optimize after crash recovery without opening wal (#600)
1 parent a5dfec6 commit e89be98

2 files changed

Lines changed: 44 additions & 3 deletions

File tree

src/db/index/segment/segment.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4224,8 +4224,6 @@ Status SegmentImpl::recover() {
42244224
wal_file_path.c_str());
42254225
return Status::OK();
42264226
}
4227-
AILEGO_DEFER([&]() { recover_wal_file->close(); });
4228-
42294227
std::array<uint64_t, static_cast<size_t>(Operator::DELETE) + 1>
42304228
recovered_doc_count{};
42314229
uint64_t total_recovered_doc_count{0};
@@ -4309,7 +4307,17 @@ Status SegmentImpl::recover() {
43094307
(size_t)recovered_doc_count[3] // DELETE
43104308
);
43114309

4312-
return Status::OK();
4310+
if (recover_wal_file->close() != 0) {
4311+
return Status::InternalError("Failed to close recovered wal file: ",
4312+
wal_file_path);
4313+
}
4314+
recover_wal_file.reset();
4315+
4316+
// Keep the recovered WAL attached to the segment. Operations such as
4317+
// optimize() flush the writing segment before sealing it; without an open
4318+
// member WAL, flush() treats the recovered memory components as empty and
4319+
// returns without persisting them.
4320+
return open_wal_file();
43134321
}
43144322

43154323
Status SegmentImpl::open_wal_file() {

tests/db/crash_recovery/write_recovery_test.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,39 @@ TEST_F(CrashRecoveryTest, CrashRecoveryDuringInsertion) {
218218
}
219219

220220

221+
TEST_F(CrashRecoveryTest, OptimizeAfterCrashRecoveryPersistsReplayedData) {
222+
{
223+
auto schema = CreateTestSchema(collection_name_);
224+
auto result = Collection::CreateAndOpen(dir_path_, *schema, options_);
225+
ASSERT_TRUE(result.has_value()) << result.error().message();
226+
}
227+
228+
RunGeneratorAndCrash("0", "10000", "insert", "0", 1);
229+
230+
uint64_t recovered_doc_count = 0;
231+
{
232+
auto result = Collection::Open(dir_path_, options_);
233+
ASSERT_TRUE(result.has_value())
234+
<< "Failed to reopen collection after crash recovery";
235+
auto collection = result.value();
236+
237+
recovered_doc_count = collection->Stats().value().doc_count;
238+
ASSERT_GT(recovered_doc_count, 0)
239+
<< "No documents were recovered from the WAL";
240+
241+
auto status = collection->Optimize();
242+
ASSERT_TRUE(status.ok()) << status.message();
243+
ASSERT_EQ(collection->Stats().value().doc_count, recovered_doc_count);
244+
}
245+
246+
auto result = Collection::Open(dir_path_, options_);
247+
ASSERT_TRUE(result.has_value())
248+
<< "Failed to reopen collection after optimizing recovered data";
249+
ASSERT_EQ(result.value()->Stats().value().doc_count, recovered_doc_count)
250+
<< "Optimize discarded documents restored from the WAL";
251+
}
252+
253+
221254
TEST_F(CrashRecoveryTest, CrashRecoveryDuringUpsert) {
222255
{
223256
auto schema = CreateTestSchema(collection_name_);

0 commit comments

Comments
 (0)