diff --git a/fielddb/field_db.cpp b/fielddb/field_db.cpp index a83960f..9bd93f1 100644 --- a/fielddb/field_db.cpp +++ b/fielddb/field_db.cpp @@ -82,15 +82,18 @@ Status FieldDB::Recover() { MetaValue = Iter->key(); MetaType type = MetaType(DecodeFixed32(MetaValue.data())); MetaValue.remove_prefix(4);//移除头上的metaType的部分 + Slice extractKey; + GetLengthPrefixedSlice(&MetaValue, &extractKey); if(type == KV_Creating) { FieldArray fields; ParseValue(Iter->value().ToString(), &fields); - PutFields(WriteOptions(), MetaValue, fields); + PutFields(WriteOptions(), extractKey, fields); } else if(type == KV_Deleting) { - Delete(WriteOptions(), MetaValue); + Delete(WriteOptions(), extractKey); } else { assert(0 && "Invalid MetaType"); } + Iter->Next(); } delete Iter; //在所有的请求完成后,会自动把metaDB的内容清空。 diff --git a/test/recover_test.cc b/test/recover_test.cc index 4b05c1d..47cc731 100644 --- a/test/recover_test.cc +++ b/test/recover_test.cc @@ -8,12 +8,6 @@ #include using namespace fielddb; -// std::atomic thread_has_error(false); - -// void signalHandler(int signum) { -// // 捕捉段错误 -// } - TEST(TestNormalRecover, Recover) { fielddb::DestroyDB("testdb3.1",Options()); FieldDB *db = new FieldDB(); @@ -42,42 +36,47 @@ TEST(TestNormalRecover, Recover) { findKeysByAgeIndex(db, true); } -// TEST(TestParalPutRecover, Recover) { -// signal(SIGSEGV, signalHandler); -// fielddb::DestroyDB("testdb3.2",Options()); -// FieldDB *db = new FieldDB(); +TEST(TestParalPutRecover, Recover) { + //第一次运行 + // fielddb::DestroyDB("testdb3.2",Options()); + // FieldDB *db = new FieldDB(); -// if(OpenDB("testdb3.2", &db).ok() == false) { -// std::cerr << "open db failed" << std::endl; -// abort(); -// } -// db->CreateIndexOnField("address"); -// db->CreateIndexOnField("age"); -// shanghaiKeys.clear(); -// age20Keys.clear(); -// int thread_num_ = 2; -// std::vector threads(thread_num_); -// threads[0] = std::thread([db](){ -// InsertFieldData(db); -// }); -// threads[1] = std::thread([db](){ -// InsertOneField(db); -// delete db; -// }); + // if(OpenDB("testdb3.2", &db).ok() == false) { + // std::cerr << "open db failed" << std::endl; + // abort(); + // } + // db->CreateIndexOnField("address"); + // db->CreateIndexOnField("age"); + // shanghaiKeys.clear(); + // age20Keys.clear(); + // int thread_num_ = 2; + // std::vector threads(thread_num_); + // threads[0] = std::thread([db](){ + // InsertFieldData(db); + // }); + // threads[1] = std::thread([db](){ + // InsertOneField(db); + // delete db; + // }); + // for (auto& t : threads) { + // if (t.joinable()) { + // t.join(); + // } + // } + //线程1导致了线程0错误,测试会终止(模拟数据库崩溃) + //这会导致线程0在写入的各种奇怪的时间点崩溃 + //第二次运行注释掉上面的代码,运行下面的代码测试恢复 - -// if (threads[1].joinable()) { -// threads[1].join(); -// } - -// db = new FieldDB(); -// if(OpenDB("testdb3.2", &db).ok() == false) { -// std::cerr << "open db failed" << std::endl; -// abort(); -// } -// GetOneField(db); -// checkDataInKVAndIndex(db); -// } + + //第二次运行 + FieldDB *db = new FieldDB(); + if(OpenDB("testdb3.2", &db).ok() == false) { + std::cerr << "open db failed" << std::endl; + abort(); + } + GetOneField(db); + checkDataInKVAndIndex(db); +} int main(int argc, char** argv) { // All tests currently run with the same read-only file limits.