From aa42bfeda876ef87d71b6d26ae57de773aaf9fe3 Mon Sep 17 00:00:00 2001 From: alexfisher <1823748191@qq.com> Date: Mon, 6 Jan 2025 23:38:56 +0800 Subject: [PATCH] add a unique test --- db/db_impl.cc | 5 +++-- include/leveldb/options.h | 2 ++ test/test.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 设计文档.md | 6 +++--- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/db/db_impl.cc b/db/db_impl.cc index 95249f3..4680c0d 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -1388,8 +1388,9 @@ Status DBImpl::Write(const WriteOptions& options, WriteBatch* updates) { // into mem_. { mutex_.Unlock(); - - status = log_->AddRecord(WriteBatchInternal::Contents(write_batch)); + if(!options.crash_test) + status = log_->AddRecord(WriteBatchInternal::Contents(write_batch)); + else status=Status::Corruption("test"); bool sync_error = false; if (status.ok() && options.sync) { status = logfile_->Sync(); diff --git a/include/leveldb/options.h b/include/leveldb/options.h index a99823a..ceab0b3 100644 --- a/include/leveldb/options.h +++ b/include/leveldb/options.h @@ -208,6 +208,8 @@ struct LEVELDB_EXPORT WriteOptions { // system call followed by "fsync()". bool sync = false; bool valuelog_write=false; + + bool crash_test=false; }; } // namespace leveldb diff --git a/test/test.cpp b/test/test.cpp index cd21cd0..4317f27 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -73,7 +73,7 @@ std::string GenKeyByNum(int num,int len){ std::string GenValueByNum(int num,int len){ std::string value; for(int i=0;i a, std::vector b) { return true; } +TEST(Test, valuelog_corrupt_in_write_test){ + DB *db; + WriteOptions writeOptions; + ReadOptions readOptions; + Options dboptions; + std::vector values; + dboptions.use_valuelog_length=100; + writeOptions.sync=true; + if(OpenDB(&db,dboptions).ok() == false) { + std::cerr << "open db failed" << std::endl; + abort(); + } + for(int i=0;i<5;i++){ + std::string key=GenKeyByNum(i,5); + std::string value=GenValueByNum(i,5000); + values.push_back(value); + if(i==4)writeOptions.crash_test=true; + else writeOptions.crash_test=false; + Status s=db->Put(writeOptions,key,value); + if(i<4)assert(s.ok()); + else assert(!s.ok()); + } + delete db; + if(OpenDB(&db,dboptions,false).ok() == false) { + std::cerr << "open db failed" << std::endl; + abort(); + } + for(int i=0;i<5;i++){ + std::string key=GenKeyByNum(i,5); + std::string value; + Status s=db->Get(readOptions,key,&value); + if(i<4)assert(s.ok()); + else assert(s.IsNotFound()); + } + delete db; +} + TEST(Test, valuelog_iterator_test) { DB *db; WriteOptions writeOptions; diff --git a/设计文档.md b/设计文档.md index 03d7b65..49dbe44 100644 --- a/设计文档.md +++ b/设计文档.md @@ -210,7 +210,7 @@ Value设计为:1字节标志位+Varint64文件ID+Varint64偏移量+Varint64长 **Using count在Value Log添加键值对时进行+1**。 -**Using count**在**其中任意键值对被合并**,**并且 该键值对由于合并时被更加新的键值对覆盖 或者 该键值对的True using Sign=False**时,进行**-1**。 +**Using count**在**其中任意键值对被合并**,**并且 该键值对由于合并时被更加新的键值对覆盖 或者 该键值对的True using Sign=False**时,进行 **-1** 。 在一个Value通过SSTable索引到Value Log后,其索引到的开头是一个**Value True Using Sign**。该标志位同样是一字节,标志了当前该Value是否是真正的Value。 @@ -270,7 +270,7 @@ Value设计为:1字节标志位+Varint64文件ID+Varint64偏移量+Varint64长 在sstable中key对应的value位置存储了对应valuelog文件的id和在文件中的offset。 -**trick1:在valueLog中重复存key会导致写方法,但是是有必要的,详见GC过程** +**trick1:在valueLog中重复存key会导致写放大,但是是有必要的,详见GC过程** **trick2:将Key放在Value后,使得不启用CRC校验码时可以无需读取key_len和key,加速read** @@ -787,7 +787,7 @@ WriteOptions新增: 我们写了共九个大测试。 分别为: - +- 写ValueLog完成后未进入WAL日志的崩溃恢复测试(通过查看ValueLog内部可以看到恢复后未完成的数据从ValueLog中删除) - 数据全部处于valueLog 的iterator测试 - 数据部分处于valueLog 的iterator测试 - Unordered iterator测试