GSaha567/seq_level_training_data
052
1text,length,is_long_context,metric_val,label_metric2"3//此源码被清华学神尹成大魔王专业翻译分析并修改4//尹成QQ770250775//尹成微信185103414076//尹成所在QQ群7219299807//尹成邮箱 yinc13@mails.tsinghua.edu.cn8//尹成毕业于清华大学,微软区块链领域全球最有价值专家9//https://mvp.microsoft.com/zh-cn/PublicProfile/403362010//版权所有(c)2011至今,Facebook,Inc.保留所有权利。11//此源代码在两个gplv2下都获得了许可(在12//复制根目录中的文件)和Apache2.0许可证13//(在根目录的license.apache文件中找到)。14//15//版权所有(c)2011 LevelDB作者。版权所有。16//此源代码的使用受可以17//在许可证文件中找到。有关参与者的名称,请参阅作者文件。18 19#if !defined(ROCKSDB_LITE) && !defined(OS_WIN)20 21#include <algorithm>22#include <string>23 24#include ""db/db_impl.h""25#include ""env/env_chroot.h""26#include ""port/port.h""27#include ""port/stack_trace.h""28#include ""rocksdb/rate_limiter.h""29#include ""rocksdb/transaction_log.h""30#include ""rocksdb/types.h""31#include ""rocksdb/utilities/backupable_db.h""32#include ""rocksdb/utilities/options_util.h""33#include ""util/file_reader_writer.h""34#include ""util/filename.h""35#include ""util/mutexlock.h""36#include ""util/random.h""37#include ""util/stderr_logger.h""38#include ""util/string_util.h""39#include ""util/sync_point.h""40#include ""util/testharness.h""41#include ""util/testutil.h""42 43namespace rocksdb {44 45namespace {46 47using std::unique_ptr;48 49class DummyDB : public StackableDB {50 public:51 /*隐性的*/52 DummyDB(const Options& options, const std::string& dbname)53 : StackableDB(nullptr), options_(options), dbname_(dbname),54 deletions_enabled_(true), sequence_number_(0) {}55 56 virtual SequenceNumber GetLatestSequenceNumber() const override {57 return ++sequence_number_;58 }59 60 virtual const std::string& GetName() const override {61 return dbname_;62 }63 64 virtual Env* GetEnv() const override {65 return options_.env;66 }67 68 using DB::GetOptions;69 virtual Options GetOptions(ColumnFamilyHandle* column_family) const override {70 return options_;71 }72 73 virtual DBOptions GetDBOptions() const override {74 return DBOptions(options_);75 }76 77 virtual Status EnableFileDeletions(bool force) override {78 EXPECT_TRUE(!deletions_enabled_);79 deletions_enabled_ = true;80 return Status::OK();81 }82 83 virtual Status DisableFileDeletions() override {84 EXPECT_TRUE(deletions_enabled_);85 deletions_enabled_ = false;86 return Status::OK();87 }88 89 virtual Status GetLiveFiles(std::vector<std::string>& vec, uint64_t* mfs,90 bool flush_memtable = true) override {91 EXPECT_TRUE(!deletions_enabled_);92 vec = live_files_;93 *mfs = 100;94 return Status::OK();95 }96 97 virtual ColumnFamilyHandle* DefaultColumnFamily() const override {98 return nullptr;99 }100 101 class DummyLogFile : public LogFile {102 public:103 /*隐性的*/104 DummyLogFile(const std::string& path, bool alive = true)105 : path_(path), alive_(alive) {}106 107 virtual std::string PathName() const override {108 return path_;109 }110 111 virtual uint64_t LogNumber() const override {112//你叫这个方法是干什么的?113 ADD_FAILURE();114 return 0;115 }116 117 virtual WalFileType Type() const override {118 return alive_ ? kAliveLogFile : kArchivedLogFile;119 }120 121 virtual SequenceNumber StartSequence() const override {122//此seqnum保证虚拟文件将包含在备份中。123//只要它还活着。124 return kMaxSequenceNumber;125 }126 127 virtual uint64_t SizeFileBytes() const override {128 return 0;129 }130 131 private:132 std::string path_;133 bool alive_;134}; //虚拟日志文件135 136 virtual Status GetSortedWalFiles(VectorLogPtr& files) override {137 EXPECT_TRUE(!deletions_enabled_);138 files.resize(wal_files_.size());139 for (size_t i = 0; i < files.size(); ++i) {140 files[i].reset(141 new DummyLogFile(wal_files_[i].first, wal_files_[i].second));142 }143 return Status::OK();144 }145 146//避免对堆栈db调用Flushwal,该db为nullptr147 virtual Status FlushWAL(bool sync) override { return Status::OK(); }148 149 std::vector<std::string> live_files_;150//配对<文件名,活动?>151 std::vector<std::pair<std::string, bool>> wal_files_;152 private:153 Options options_;154 std::string dbname_;155 bool deletions_enabled_;156 mutable SequenceNumber sequence_number_;157}; //DimyDB158 159class TestEnv : public EnvWrapper {160 public:161 explicit TestEnv(Env* t) : EnvWrapper(t) {}162 163 class DummySequentialFile : public SequentialFile {164 public:165 explicit DummySequentialFile(bool fail_reads)166 : SequentialFile(), rnd_(5), fail_reads_(fail_reads) {}167 virtual Status Read(size_t n, Slice* result, char* scratch) override {168 if (fail_reads_) {169 return Status::IOError();170 }171 size_t read_size = (n > size_left) ? size_left : n;172 for (size_t i = 0; i < read_size; ++i) {173 scratch[i] = rnd_.Next() & 255;174 }175 *result = Slice(scratch, read_size);176 size_left -= read_size;177 return Status::OK();178 }179 180 virtual Status Skip(uint64_t n) override {181 size_left = (n > size_left) ? size_left - n : 0;182 return Status::OK();183 }184 private:185 size_t size_left = 200;186 Random rnd_;187 bool fail_reads_;188 };189 190 Status NewSequentialFile(const std::string& f, unique_ptr<SequentialFile>* r,191 const EnvOptions& options) override {192 MutexLock l(&mutex_);193 if (dummy_sequential_file_) {194 r->reset(195 new TestEnv::DummySequentialFile(dummy_sequential_file_fail_reads_));196 return Status::OK();197 } else {198 return EnvWrapper::NewSequentialFile(f, r, options);199 }200 }201 202 Status NewWritableFile(const std::string& f, unique_ptr<WritableFile>* r,203 const EnvOptions& options) override {204 MutexLock l(&mutex_);205 written_files_.push_back(f);206 if (limit_written_files_ <= 0) {207 return Status::NotSupported(""Sorry, can't do this"");208 }209 limit_written_files_--;210 return EnvWrapper::NewWritableFile(f, r, options);211 }212 213 virtual Status DeleteFile(const std::string& fname) override {214 MutexLock l(&mutex_);215 if (fail_delete_files_) {216 return Status::IOError();217 }218 EXPECT_GT(limit_delete_files_, 0U);219 limit_delete_files_--;220 return EnvWrapper::DeleteFile(fname);221 }222 223 virtual Status DeleteDir(const std::string& dirname) override {224 MutexLock l(&mutex_);225 if (fail_delete_files_) {226 return Status::IOError();227 }228 return EnvWrapper::DeleteDir(dirname);229 }230 231 void AssertWrittenFiles(std::vector<std::string>& should_have_written) {232 MutexLock l(&mutex_);233 std::sort(should_have_written.begin(), should_have_written.end());234 std::sort(written_files_.begin(), written_files_.end());235 236 ASSERT_EQ(should_have_written, written_files_);237 }238 239 void ClearWrittenFiles() {240 MutexLock l(&mutex_);241 written_files_.clear();242 }243 244 void SetLimitWrittenFiles(uint64_t limit) {245 MutexLock l(&mutex_);246 limit_written_files_ = limit;247 }248 249 void SetLimitDeleteFiles(uint64_t limit) {250 MutexLock l(&mutex_);251 limit_delete_files_ = limit;252 }253 254 void SetDeleteFileFailure(bool fail) {255 MutexLock l(&mutex_);256 fail_delete_files_ = fail;257 }258 259 void SetDummySequentialFile(bool dummy_sequential_file) {260 MutexLock l(&mutex_);261 dummy_sequential_file_ = dummy_sequential_file;262 }263 void SetDummySequentialFileFailReads(bool dummy_sequential_file_fail_reads) {264 MutexLock l(&mutex_);265 dummy_sequential_file_fail_reads_ = dummy_sequential_file_fail_reads;266 }267 268 void SetGetChildrenFailure(bool fail) { get_children_failure_ = fail; }269 Status GetChildren(const std::string& dir,270 std::vector<std::string>* r) override {271 if (get_children_failure_) {272 return Status::IOError(""SimulatedFailure"");273 }274 return EnvWrapper::GetChildren(dir, r);275 }276 277//有些测试用例实际上并不创建测试文件(例如,请参见278//dummydb::live_files——对于这些情况,我们模拟这些文件的属性。279//因此createNewbackup()可以获取它们的属性。280 void SetFilenamesForMockedAttrs(const std::vector<std::string>& filenames) {281 filenames_for_mocked_attrs_ = filenames;282 }283 Status GetChildrenFileAttributes(284 const std::string& dir, std::vector<Env::FileAttributes>* r) override {285 if (filenames_for_mocked_attrs_.size() > 0) {286 for (const auto& filename : filenames_for_mocked_attrs_) {287 /*向后推(dir+filename,10/*大小字节*/);288 }289 返回状态::OK();290 }291 返回envwrapper::getchildrenfileattributes(dir,r);292 }293 status getfilesize(const std::string&path,uint64_t*size_bytes)override_294 if(文件名_for_mocked_attrs_.size()>0)295 auto-fname=path.substr(path.find_last_of('/');296 auto filename_iter=std::find(文件名_表示模拟的_attrs_.begin(),297 文件名_for_mocked_attrs_.end(),fname);298 如果(文件名为ITER!=文件名_for_mocked_attrs_.end())299 *大小字节=10;300 返回状态::OK();301 }302 返回状态:未找到(fname);303 }304 返回envwrapper::getfilesize(path,size_bytes);305 }306 307 void setcreatedirifmissingfailure(bool fail)308 如果缺少故障,创建目录;309 }310 状态createdirifmissing(const std::string&d)override311 if(创建_dir_if_missing_failure_312 返回状态::ioerror(“SimulatedFailure”);313 }314 返回envwrapper::createdirifmissing(d);315 }316 317 void setnewdirectoryfailure(bool fail)new_directory_failure_=fail;318 虚拟状态newdirectory(const std::string&name,319 唯一_ptr<directory>>*result)override_320 if(new_directory_failure_321 返回状态::ioerror(“SimulatedFailure”);322 }323 返回envwrapper::newdirectory(name,result);324 }325 326 私人:327 端口::mutex mutex_uu;328 bool dummy_sequential_file_uu=false;329 bool dummy_sequential_file_fail_reads_u=false;330 std::vector<std::string>written_u files;331 std::vector<std::string>文件名\\u表示模拟的\\u属性\\;332 uint64_t limit_written_files_uu1000000;333 uint64_t limit_delete_files_uu1000000;334 bool fail_delete_files_uu=false;335 336 bool get_children_failure_uu=false;337 bool create_dir_if_missing_failure_u=false;338 bool new_directory_failure_uu=false;339};// TESTNOV340 341类文件管理器:public envwrapper_342 公众:343 显式文件管理器(env*t):envwrapper(t),rnd_344 345 status deleterandomfileindir(const std::string&dir)346 std::vector<std::string>children;347 getchildren(dir和children);348 if(children.size()<=2)//。并且…349 返回状态::未找到(“”);350 }351 当(真){352 int i=rnd_u.next()%children.size();353 如果(孩子们[我]!=“”&&children[i]!=“…”){354 返回deletefile(dir+“/”+children[i]);355 }356 }357 //不应该到这里358 断言(假);359 返回状态::未找到(“”);360 }361 362 状态appendtorandomfileindir(const std::string&dir,363 const std::字符串和数据)364 std::vector<std::string>children;365 getchildren(dir和children);366 if(children.size()<=2)367 返回状态::未找到(“”);368 }369 当(真){370 int i=rnd_u.next()%children.size();371 如果(孩子们[我]!=“”&&children[i]!=“…”){372 返回writetofile(dir+“/”+children[i],data);373 }374 }375 //不应该到这里376 断言(假);377 返回状态::未找到(“”);378 }379 380 状态损坏文件(const std::string&fname,uint64_t bytes_to_corrupt)381 std::字符串文件目录;382 状态S=readfiletoString(this、fname和file_contents);383 如果(!)S.O.()){384 返回S;385 }386 s=删除文件(fname);387 如果(!)S.O.()){388 返回S;389 }390 391 for(uint64_t i=0;i<bytes_to_corrupt;++i)392 std::字符串tmp;393 测试::randomstring(&rnd_u1,&tmp);394 file_contents[rnd_.next()%file_contents.size()]=tmp[0];395 }396 返回writetofile(fname,文件目录);397 }398 399 状态corruptchecksum(const std::string&fname,bool显示为“有效”);400 std::字符串元数据;401 状态s=readfiletoString(this、fname和metadata);402 如果(!)S.O.()){403 返回S;404 }405 s=删除文件(fname);406 如果(!)S.O.()){407 返回S;408 }409 410 auto pos=metadata.find(“private”);411 if(pos==std::string::npos)412 返回状态::损坏(“需要专用文件”);413 }414 pos=metadata.find(“crc32”,pos+6);415 if(pos==std::string::npos)416 返回状态::损坏(“未找到校验和”);417 }418 419 if(metadata.size()<pos+7)420 返回状态::损坏(“CRC32校验和值错误”);421 }422 423 如果(似乎有效)424 if(元数据[pos+8]='\\n')425 //单个数字值,可以安全地再插入一个数字426 元数据。插入(pos+8,1,'0');427 }否则{428 元数据。擦除(pos+8,1);429 }430 }否则{431 元数据[pos+7]='a';432 }433 434 返回writetofile(fname,元数据);435 }436 437 状态写入文件(const std::string&fname,const std::string&data)438 唯一的文件;439 环境选项环境选项;440 env?options.use?mmap?writes=false;441 状态s=envwrapper::newwritablefile(fname,&file,env_选项);442 如果(!)S.O.()){443 返回S;444 }445 返回文件->追加(切片(数据));446 }447 448 私人:449 随机RNDI;450//文件管理器451 452//实用程序函数453静态大小_t filldb(db*db,int-from,int-to)454 大小T字节写入=0;455 对于(int i=from;i<to;++i)456 std::string key=“testkey”+to字符串(i);457 std::string value=“testvalue”+to字符串(i);458 bytes_written+=key.size()+value.size();459 460 期望_OK(db->put(writeOptions(),slice(key),slice(value)));461 }462 返回写入的字节数;463}464 465静态void断言存在(db*db,int-from,int-to)466 对于(int i=from;i<to;++i)467 std::string key=“testkey”+to字符串(i);468 std::字符串值;469 状态s=db->get(readoptions(),slice(key),&value);470 断言“eq(value,”“testvalue”+to字符串(i));471 }472}473 474静态void断言空(db*db,int-from,int-to)475 对于(int i=from;i<to;++i)476 std::string key=“testkey”+to字符串(i);477 std::string value=“testvalue”+to字符串(i);478 479 状态s=db->get(readoptions(),slice(key),&value);480 断言“真”(s.isNotFound());481 }482}483 484类backupabledbtest:公共测试::test485 公众:486 backupabledbtest()487 /设置文件488 std::string db_chroot=test::tmpdir()+“/backupable_db”;489 std::string backup_chroot=test::tmpdir()+“/backupable_db_backup”;490 env::default()->createdir(db_chroot);491 env::default()->createdir(备份目录);492 dbname_u=“/tempdb”;493 backupdir_u=“/tempbk”;494 495 /设置EVS496 db_chroot_env_u.reset(newchrootenv(env::default(),db_chroot));497 backup_chroot_env_u.reset(newchrootenv(env::default(),backup_chroot));498 test_db_env_u.reset(new test env(db_chroot_env_u.get());499 test_backup_env_u.reset(new test env(backup_chroot_env_u.get());500 文件管理器重置(new file manager(backup_chroot_env_u.get());501 502 //设置数据库选项503 选项u.create_if_missing=true;504 选项u.paranoid_checks=true;505 选项写入缓冲区大小=1<<17;//128kb506 options_u.env=test_db_env_u.get();507 选项u.wal_dir=dbname_u;508 509 //创建记录器510 dboptions logger_选项;511 logger_options.env=db_chroot_env_u.get();512 创建loggerfromoptions(dbname_uu,logger_options,&logger_u);513 514 //设置备份数据库选项515 可备份选项重置(新的可备份选项(516 backupdir_u,test_backup_env_u.get(),true,logger_u.get(),true));517 518 //大多数测试将使用多线程备份519 可备份的_Options_u->Max_background_operations=7;520 521 //删除数据库中的旧文件522 DestroyDB(dbname_uu,选项_u);523 }524 525 db*opdB(){526 DB*DB;527 期望_OK(db::open(选项_uu,dbname_u,&db));528 返回数据库;529 }530 531 void opendbandbackupengineeshareewithchecksum(532 bool destroy_old_data=false,bool dummy=false,533 bool share_table_files=true,bool share_with_checksums=false)534 可备份的_选项_->share_files_with_checksum=share_with_checksums;535 opendbandbackupengine(销毁旧数据,虚拟,与校验和共享);536 }537 538 void opendbandbackupengine(bool destroy_old_data=false,bool dummy=false,539 bool share_table_files=true)540 //重置所有默认值541 测试备份文件(1000000);542 测试_db_env_uu->setlimitwrittenfiles(1000000);543 test_db_env_u->setdummy序列文件(dummy);544 545 DB*DB;546 如果(哑){547 dummy_db_u=new dummy db(选项_uu,dbname_u);548 DB=DuMyMyBuz;549 }否则{550 断言ou ok(db::open(options_u,dbname_uu,&db));551 }552 重置(DB);553 可备份的\\选项->销毁旧的\\数据=销毁旧的\\数据;554 backupable_options_u->share_table_files=share_table_files;555 备份引擎*备份引擎;556 断言\\u OK(backupengine::open(test_db_env_u.get(),*backupable_options_,557 &backup_engine));558 备份引擎重置(备份引擎);559 }560 561 void closedbandbackupengine()562 dB.ReSET();563 备份引擎重置();564 }565 566 void openbackupengine()567 backupable_options_uu->destroy_old_data=false;568 备份引擎*备份引擎;569 断言\\u OK(backupengine::open(test_db_env_u.get(),*backupable_options_,570 &backup_engine));571 备份引擎重置(备份引擎);572 }573 574 void closebackupengine()backup_engine_u.reset(nullptr);575 576 //还原备份备份\\id并断言存在577 //[开始存在,结束存在>且不存在578 //[结束存在,结束>579 / /580 //如果backup_id==0,则表示从最新版本还原581 //如果end==0,则不检查assertEmpty582 void assertbackupconsistency(backup id backup_id,uint32_t start_exist,583 uint32_t end_exist,uint32_t end=0,584 bool keep_log_files=false)585 恢复选项恢复选项(保留日志文件);586 bool opened_backup_engine=false;587 if(备份引擎get()==nullptr)588 打开的备份引擎=真;589 openbackupengine();590 }591 如果(backup_id>0)592 断言“OK”(备份引擎)->restoredbfrombackup(备份ID、dbname、dbname)593 恢复选项);594 }否则{595 断言“OK”(备份引擎)->restoredbfromlatestbackup(dbname_uu,dbname_uu,596 恢复选项);597 }598 db*db=opendb();599 断言存在(db,start_exist,end_exist);600 如果(结束)!= 0){601 断言空(db,end_exist,end);602 }603 删除数据库;604 如果(打开的备用引擎)605 closebackupengine();606 }607 }608 609 void deletelogfiles()610 std::vector<std::string>删除日志;611 db_chroot_env_u->getchildren(dbname_uu,&delete_logs);612 for(auto f:删除日志)613 uint64_t编号;614 文件类型;615 bool ok=parseFileName(f,&number,&type);616 if(确定&&type==klogfile)617 db_chroot_env_u->deletefile(dbname_+“/”+f);618 }619 }620 }621 622 //文件623 std::字符串dbname_u;624 std::string backupdir_u;625 626 //记录器_u必须位于备用_u引擎_u之上,这样引擎的析构函数,627 //使用记录器的原始指针,首先执行。628 std::shared&ptr<logger>logger;629 630 //eNVS631 唯一_ptr<env>db_chroot_env;632 唯一_ptr<env>backup_chroot_env;633 唯一的测试634 唯一的_ptr<test env>test_backup_env;635 唯一的文件管理器636 637 /所有DBS!638 dummy db*dummy_db_;//backupabledb拥有dummy_db_639 唯一的指针<db>db;640 唯一的引擎641 642 //选项643 选项选项644 645 受保护的:646 唯一的备份选项647//备份表测试648 649void appendpath(const std::string&path,std::vector<std::string>>&v)650 对于(auto&f:v)651 f=路径+f;652 }653}654 655类backupabledbtestwithparam:public backupabledbtest,656 公共测试::withParamInterface<bool>657 公众:658 backupableDBTestWithParam()659 可备份的_options_u->share_files_with_checksum=getparam();660 }661};662 663//此测试验证verifybackup方法是否正确标识664//无效备份665测试_p(backupabledbtestwitparam,verifybackup)666 const int keys_迭代=5000;667 随机RND(6);668 状态S;669 OpenDBandBackupEngine(真);670 //创建五个备份671 对于(int i=0;i<5;+i)672 fillDB(db_u.get(),keys_迭代*i,keys_迭代*(i+1));673 断言_OK(backup_engine_u->createNewbackup(db_.get(),true));674 }675 closedbandbackupengine();676 677 opendbandbackupengine();678 //——————案例1。-有效备份-----------679 断言_true(backup_engine_uu->verifybackup(1).ok());680 681 //——————案例2。-删除文件-----------i682 文件\\u manager_u->deleterandomfileindir(backupdir_+“/private/1”);683 断言_true(backup_engine_uu->verifybackup(1).isNotFound());684 685 //——————第3种情况。-损坏文件-----------686 std::string append_data=“损坏随机文件”;687 文件\\u manager_u->appendtorandomfileindir(backupdir_+“/private/2”,688 附录数据;689 断言“真”(backup_engine_uu->verifybackup(2).iscorrution());690 691 //——————第4种情况。-无效备份-----------692 断言_true(backup_engine_uu->verifybackup(6).isNotFound());693 closedbandbackupengine();694}695 696//打开db,写入,关闭db,备份,还原,重复697测试_p(backupabledbtestwitparam,离线集成测试)698 //必须是一个大数字,以便触发memtable刷新699 const int keys_迭代=5000;700 const int max_key=keys_迭代*4+10;701 //第一个iter--备份前刷新702 //第二个iter——备份前不要刷新703 对于(int iter=0;iter<2;+iter)704 //删除旧数据705 DestroyDB(dbname_uu,选项_u);706 bool destroy_data=true;707 708 //每次迭代--709 / / 1。在数据库中插入新数据710 / / 2。备份数据库711 / / 3。销毁数据库712 / / 4。恢复数据库,检查所有内容是否仍然存在713 对于(int i=0;i<5;+i)714 //在上一次迭代中,放入较少的数据,715 int fill_up_to=std::min(keys_iteration*(i+1),max_key);716 //---插入新数据并备份----717 opendbandbackupengine(销毁数据);718 销毁数据=假;719 fillDB(db_u.get(),keys_iteration*i,fill_up_to);720 断言_OK(backup_engine_u->createNewbackup(db_.get(),iter==0));721 closedbandbackupengine();722 DestroyDB(dbname_uu,选项_u);723 724 //---确保它是空的----725 db*db=opendb();726 断言空(db,0,填充到);727 删除数据库;728 729 //---恢复数据库----730 openbackupengine();731 如果(i>=3)//测试清除旧备份732 //当i==4时,清除到只有1个备份733 //当i==3时,清除到2个备份734 断言“OK(备份引擎)”->purgeoldbackups(5-i));735 }736 //---确保数据存在---737 断言备份一致性(0,0,填充到,最大值键);738 closebackupengine();739 }740 }741}742 743//打开db,write,backup,write,backup,close,restore744测试_p(backupabledbtestwitparam,onlineintegrationtest)745 //必须是一个大数字,以便触发memtable刷新746 const int keys_迭代=5000;747 const int max_key=keys_迭代*4+10;748 随机RND(7);749 //删除旧数据750 DestroyDB(dbname_uu,选项_u);751 752 OpenDBandBackupEngine(真);753 //写一些数据,备份,重复754 对于(int i=0;i<5;+i)755 如果(i=4){756 //删除备份号2,在线删除!757 断言“OK(备份引擎)”->DeleteBackup(2));758 }759 //在上一次迭代中,放入较少的数据,760 //以便备份可以共享sst文件761 int fill_up_to=std::min(keys_iteration*(i+1),max_key);762 fillDB(db_u.get(),keys_iteration*i,fill_up_to);763 //我们应该在备份之前得到与flush一致的结果764 //同时设置为true和false765 断言_OK(backup_engine_u->createNewbackup(db_u.get(),!!(rnd.next()%2));766 }767 //关闭并销毁768 closedbandbackupengine();769 DestroyDB(dbname_uu,选项_u);770 771 //---确保它是空的----772 db*db=opendb();773 断言空(db,0,max_key);774 删除数据库;775 776 //---还原每个备份并验证所有数据是否存在----777 openbackupengine();778 对于(int i=1;i<=5;++i)779 如果(i=2){780 //我们删除了备份2781 状态S=backup_engine_u->restoredbfrombackup(2,dbname_uu,dbname_u);782 断言是真的(!);783 }否则{784 int fill_up_to=std::min(keys_iteration*i,max_key);785 断言备份一致性(i,0,fill-up-to,max-u键);786 }787 }788 789 //删除一些备份--这应该只保留备份3和5的活动状态790 断言“OK(备份引擎)”删除备份(4));791 断言_OK(备份_引擎_u->purgeoldbackups(2));792 793 std::vector<backup info>backup_info;794 backup_engine_u->getbackupinfo(&backup_info);795 断言_eq(2ul,backup_info.size());796 797 //检查备份3798 断言备份一致性(3,0,3*键迭代,最大键);799 //检查备份5800 断言备份一致性(5,0,max_key);801 802 closebackupengine();803}804 805实例化_test_case_p(backupabledbtestwitparam,backupabledbtestwitparam,806 ::测试::bool());807 808//这将确保备份不会复制同一文件两次809测试(backupabledbtest,nodoubleCopy)810 OpenDBandBackupEngine(真,真);811 812 //应该写入5 db文件+一个元文件813 测试备份文件(7);814 test_backup_env_u->clearwrittenfiles();815 测试_db_env_uu->setlimitwrittenfiles(0);816 虚拟文件u db_u->live_files_u=“/00010.sst”,“/00011.sst”,“/current”,817 “/清单-01”818 虚拟_db_->wal_文件_123;_“/00011.log”,真,“/00012.log”,假_819 测试_db_env->setfilenamesformockedattrs(虚拟_db_uu->live_文件);820 断言_OK(backup_engine_u->createNewbackup(db_.get(),false));821 std::vector<std::string>应该有822 “/shared/00010.sst.tmp”,“/shared/00011.sst.tmp”,823 “/private/1.tmp/current”,“/private/1.tmp/manifest-01”,824 “/private/1.tmp/00011.log”,“/meta/1.tmp”825 appendpath(backupdir_u,应该已经写过了);826 测试_backup_env_u->assertwrittenfiles(应_已写入);827 828 //应该写入4个新的DB文件+一个元文件829 //不应该写/复制00010.sst,因为它已经存在了!830 测试备份文件(6);831 test_backup_env_u->clearwrittenfiles();832 833 虚拟文件u db_u->live_files_u=“/00010.sst”,“/00015.sst”,“/current”,834 “/清单-01”835 虚拟_db_->wal_文件_123;_“/00011.log”,真,“/00012.log”,假_836 测试_db_env->setfilenamesformockedattrs(虚拟_db_uu->live_文件);837 断言_OK(backup_engine_u->createNewbackup(db_.get(),false));838 //不应该打开00010.sst-它已经在那里了839 840 应该有“/shared/00015.sst.tmp”,“/private/2.tmp/current”,841 “/private/2.tmp/manifest-01”,842 “/private/2.tmp/00011.log”,“/meta/2.tmp”843 appendpath(backupdir_u,应该已经写过了);844 测试_backup_env_u->assertwrittenfiles(应_已写入);845 846 断言“OK(备份引擎)”->DeleteBackup(1));847 断言_OK(test_backup_env_u->fileexists(backupdir_+“/shared/00010.sst”);848 849 //00011.sst仅在备份1中,应删除850 断言eq(状态::NotFound(),851 test_backup_env_u->fileexists(backupdir_+“/shared/00011.sst”);852 断言_OK(test_backup_env_u->fileexists(backupdir_+“/shared/00015.sst”);853 854 //清单文件大小应仅为100855 UTIN 64 t尺寸;856 测试备份环境获取文件大小(backupdir“/private/2/manifest-01”,&size);857 断言eq(100ul,大小);858 测试备份环境获取文件大小(backupdir_+“/shared/00015.sst”,&size);859 断言eq(200ul,大小);860 861 closedbandbackupengine();862}863 864//测试可能发生的各种损坏:865/ / 1。无法写入备份文件-该备份应失败,866//其他一切都能正常工作867/ / 2。备份元文件损坏或缺少备份文件-我们应该868//无法打开该备份,但所有其他备份都应869/ /罚款870/ / 3。校验和值损坏-如果校验和不是有效的uint32_t,871//db open应该失败,否则在还原过程中会中止。872测试(backupabledbtest,corruptiontest)873 const int keys_迭代=5000;874 随机RND(6);875 状态S;876 877 OpenDBandBackupEngine(真);878 //创建五个备份879 对于(int i=0;i<5;+i)880 fillDB(db_u.get(),keys_迭代*i,keys_迭代*(i+1));881 断言_OK(backup_engine_u->createNewbackup(db_u.get(),!!(rnd.next()%2));882 }883 884 //——————案例1。-写入失败-----------885 //尝试创建备份6,但写入失败886 fillDB(db_u.get(),keys_iteration*5,keys_iteration*6);887 测试备份文件(2);888 /应该失败889 s=backup_engine_u->createNewbackup(db_u.get(),!!(rnd.next()%2));890 断言是真的(!);891 测试备份文件(1000000);892 //最新备份应具有所有密钥893 closedbandbackupengine();894 断言备份一致性(0,0,keys_iteration*5,keys_iteration*6);895 896 //——————案例2。备份元数据损坏或缺少备份文件----897 断言_OK(文件_Manager_->corruptfile(backupdir_+“/meta/5”,3));898 //由于5元现在已损坏,最新备份应为4899 断言备份一致性(0,0,keys_iteration*4,keys_iteration*5);900 openbackupengine();901 S=backup_engine_u->restoredbfrombackup(5,dbname_uu,dbname_u);902 断言是真的(!);903 closebackupengine();904 断言_OK(文件_Manager_u->DeleteRandomFileIndir(backupdir_+“/private/4”));905 //4已损坏,3是最新的备份906 断言备份一致性(0,0,键迭代*3,键迭代*5);907 openbackupengine();908 S=backup_engine_u->restoredbfrombackup(4,dbname_uu,dbname_u);909 closebackupengine();910 断言是真的(!);911 912 //——————案例3。损坏的校验和值----913 断言_OK(文件_manager_u->corruptchecksum(backupdir_+“/meta/3”,false));914 //备份3的校验和是无效值,可以在915 //数据库打开时间,自动恢复到上一次备份916 断言备份一致性(0,0,keys_迭代*2,keys_迭代*5);917 //备份2的校验和似乎有效,这可能导致校验和918 //不匹配并中止还原过程919 断言_OK(文件_Manager_u->corruptchecksum(backupdir_+“/meta/2”,true));920 断言_OK(文件_Manager_u->fileexists(backupdir_+“/meta/2”));921 openbackupengine();922 断言_OK(文件_Manager_u->fileexists(backupdir_+“/meta/2”));923 S=backup_engine_u->restoredbfrombackup(2,dbname_uu,dbname_u);924 断言是真的(!);925 926 //确保没有实际删除损坏的备份!927 断言_OK(文件_Manager_u->fileexists(backupdir_+“/meta/1”));928 断言_OK(文件_Manager_u->fileexists(backupdir_+“/meta/2”));929 断言_OK(文件_Manager_u->fileexists(backupdir_+“/meta/3”));930 断言_OK(文件_Manager_u->fileexists(backupdir_+“/meta/4”));931 断言_OK(文件_Manager_u->fileexists(backupdir_+“/meta/5”));932 断言_OK(文件_Manager_u->fileexists(backupdir_+“/private/1”));933 断言_OK(文件_Manager_u->fileexists(backupdir_+“/private/2”));934 断言_OK(文件_Manager_u->fileexists(backupdir_+“/private/3”));935 断言_OK(文件_Manager_u->fileexists(backupdir_+“/private/4”));936 断言_OK(文件_Manager_u->fileexists(backupdir_+“/private/5”));937 938 //删除损坏的备份,然后确保它们确实已被删除939 断言“OK(备份引擎)”->DeleteBackup(5));940 断言“OK(备份引擎)”删除备份(4));941 断言“OK(备份引擎)”->DeleteBackup(3));942 断言“OK(备份引擎)”->DeleteBackup(2));943 (void)备份引擎_u->garbageCollect();944 断言eq(状态::NotFound(),945 文件_Manager_->fileexists(backupdir_+“/meta/5”);946 断言eq(状态::NotFound(),947 文件_Manager_->fileexists(backupdir_+“/private/5”);948 断言eq(状态::NotFound(),949 文件_Manager_->fileexists(backupdir_+“/meta/4”);950 断言eq(状态::NotFound(),951 文件_Manager_->fileexists(backupdir_+“/private/4”);952 断言eq(状态::NotFound(),953 文件_Manager_->fileexists(backupdir_+“/meta/3”);954 断言eq(状态::NotFound(),955 文件_Manager_->fileexists(backupdir_+“/private/3”);956 断言eq(状态::NotFound(),957 文件_Manager_->fileexists(backupdir_+“/meta/2”);958 断言eq(状态::NotFound(),959 文件_Manager_->fileexists(backupdir_+“/private/2”);960 961 closebackupengine();962 断言备份一致性(0,0,keys_iteration*1,keys_iteration*5);963 964 //新备份应为2!965 opendbandbackupengine();966 fillDB(db_u.get(),keys_iteration*1,keys_iteration*2);967 断言_OK(backup_engine_u->createNewbackup(db_u.get(),!!(rnd.next()%2));968 closedbandbackupengine();969 断言备份一致性(2,0,keys_迭代*2,keys_迭代*5);970}971 972测试(backupabledbtest,interruptcreationest)973 //通过失败的新写入和清除974 //部分状态。然后验证后续备份是否仍然可以成功。975 const int keys_迭代=5000;976 随机RND(6);977 978 opendbandbackupengine(真/*销毁旧数据*/);979 980 FillDB(db_.get(), 0, keys_iteration);981 test_backup_env_->SetLimitWrittenFiles(2);982 test_backup_env_->SetDeleteFileFailure(true);983//创建失败984 ASSERT_FALSE(985 backup_engine_->CreateNewBackup(db_.get(), !!(rnd.Next() % 2)).ok());986 CloseDBAndBackupEngine();987//也应清除失败,以便tmp目录保持在后面988 ASSERT_OK(backup_chroot_env_->FileExists(backupdir_ + ""/private/1.tmp/""));989 990 /*ndbandbackupengine(错误/*销毁旧的数据*/);991 测试备份文件(1000000);992 测试_backup_env_uu->setDeleteFileFailure(假);993 断言_OK(backup_engine_u->createNewbackup(db_u.get(),!!(rnd.next()%2));994 //最新备份应具有所有密钥995 closedbandbackupengine();996 断言备份一致性(0,0,键迭代);997}998 999inline std::string optionspath(std::string ret,int backupid)1000 ret+=“/private/”;1001 ret+=std::to_string(backupid);1002 RET+=“/”;1003 返回RET;1004}1005 1006//将最新的选项文件备份到1007/“<backup_dir>/private/<backup_id>/options<number>”1008 1009测试(backupabledbtest,backupoptions)1010 OpenDBandBackupEngine(真);1011 对于(int i=1;i<5;i++)1012 std::字符串名称;1013 std::vector<std::string>文件名;1014 //必须重置()才能再次重置(opendb())。1015 //当存在*db_u时调用opendb()将导致锁定问题1016 dB.ReSET();1017 数据库重置(opendb());1018 断言_OK(backup_engine_u->createNewbackup(db_.get(),true));1019 rocksdb::getlatestoptionsfilename(db_u->getname(),options_.env,&name);1020 断言_OK(文件_Manager_u->fileexists(optionspath(backupdir_u,i)+name));1021 backup_chroot_env_u->getchildren(选项空间(backupdir_uu,i),&filename);1022 for(auto-fn:文件名)1023 if(fn.比较(0,7,“选项”)==0)1024 断言eq(名称,fn);1025 }1026 }1027 }1028 1029 closedbandbackupengine();1030}1031 1032//此测试验证在只读选项为1033//集1034test_f(backupabledbtest,nodeletewithreadonly)1035 const int keys_迭代=5000;1036 随机RND(6);1037 状态S;1038 1039 OpenDBandBackupEngine(真);1040 //创建五个备份1041 对于(int i=0;i<5;+i)1042 fillDB(db_u.get(),keys_迭代*i,keys_迭代*(i+1));1043 断言_OK(backup_engine_u->createNewbackup(db_u.get(),!!(rnd.next()%2));1044 }1045 closedbandbackupengine();1046 断言_OK(文件_Manager_u->writetofile(backupdir_+“/latest_backup”,“4”));1047 1048 backupable_options_uu->destroy_old_data=false;1049 备份引擎只读*只读\\备份\\引擎;1050 断言“确定”(backupengineradonly::open(backup_chroot_env_u.get(),1051 *可备份选项1052 &read_only_backup_engine));1053 1054 //断言备份5中的数据仍然存在(即使最新的备份1055 //说4是最新的)1056 断言_OK(文件_Manager_u->fileexists(backupdir_+“/meta/5”));1057 断言_OK(文件_Manager_u->fileexists(backupdir_+“/private/5”));1058 1059 //行为更改:我们现在忽略最新的备份内容。这意味着1060 //我们应该有5个备份,即使最新的备份为4。1061 std::vector<backup info>backup_info;1062 只读\\u backup\\u engine->getbackupinfo(&backup\\u info);1063 断言_eq(5ul,backup_info.size());1064 删除只读备份引擎;1065}1066 1067测试(backupabledbtest,failoverwritingbackups)1068 选项写入缓冲区大小=1024*1024*1024;//1GB1069 选项_u.disable_auto_compactions=true;1070 1071 //创建备份1、2、3、4、51072 OpenDBandBackupEngine(真);1073 对于(int i=0;i<5;+i)1074 closedbandbackupengine();1075 删除日志文件();1076 opendbandbackupengine(错误);1077 fillDB(db_.get(),100*i,100*(i+1));1078 断言_OK(backup_engine_u->createNewbackup(db_.get(),true));1079 }1080 closedbandbackupengine();1081 1082 //恢复31083 openbackupengine();1084 断言_OK(备份引擎_u->restoredbfrombackup(3,dbname_u,dbname_u));1085 closebackupengine();1086 1087 opendbandbackupengine(错误);1088 FillDB(db_u.get(),0,300);1089 状态S=backup_engine_u->createNewbackup(db_.get(),true);1090 //新备份失败,因为新表文件1091 //与备份4和5中的旧表文件冲突1092 /(由于写缓冲区的大小很大,我们可以确定1093 //每个备份只生成一个sst文件,1094 //新备份生成的文件与1095 //由备份4生成的sst文件)1096 断言“真”(s.iscorrution());1097 断言“OK(备份引擎)”删除备份(4));1098 断言“OK(备份引擎)”->DeleteBackup(5));1099 //现在,备份可以成功1100 断言_OK(backup_engine_u->createNewbackup(db_.get(),true));1101 closedbandbackupengine();1102}1103 1104测试(backupabledbtest,nosharetablefiles)1105 const int keys_迭代=5000;1106 OpenDBandBackupEngine(真、假、假);1107 对于(int i=0;i<5;+i)1108 fillDB(db_u.get(),keys_迭代*i,keys_迭代*(i+1));1109 断言_OK(backup_engine_u->createNewbackup(db_u.get(),!!(i % 2));1110 }1111 closedbandbackupengine();1112 1113 对于(int i=0;i<5;+i)1114 断言备份一致性(i+1,0,键迭代*(i+1)1115 键_迭代*6);1116 }1117}1118 1119//验证您是否可以使用共享文件进行备份和还原,并启用校验和1120测试(backupabledbtest,shareTablefilewithchecksums)1121 const int keys_迭代=5000;1122 OpenDBandBackupEngineShareWith校验和(真、假、真、真);1123 对于(int i=0;i<5;+i)1124 fillDB(db_u.get(),keys_迭代*i,keys_迭代*(i+1));1125 断言_OK(backup_engine_u->createNewbackup(db_u.get(),!!(i % 2));1126 }1127 closedbandbackupengine();1128 1129 对于(int i=0;i<5;+i)1130 断言备份一致性(i+1,0,键迭代*(i+1)1131 键_迭代*6);1132 }1133}1134 1135//验证是否可以使用共享文件进行备份和还原,并将校验和设置为1136//false,然后将此选项转换为true1137test_f(backupabledbtest,shareTablefilewithchecksumstration)1138 const int keys_迭代=5000;1139 //将share_files_with_checksum设置为false1140 OpenDBandBackupEngineShareWith校验和(真、假、真、假);1141 对于(int i=0;i<5;+i)1142 fillDB(db_u.get(),keys_迭代*i,keys_迭代*(i+1));1143 断言_OK(backup_engine_u->createNewbackup(db_.get(),true));1144 }1145 closedbandbackupengine();1146 1147 对于(int i=0;i<5;+i)1148 断言备份一致性(i+1,0,键迭代*(i+1)1149 键_迭代*6);1150 }1151 1152 //将share_files_with_checksum设置为true并执行更多备份1153 OpenDBandBackupEngineShareWith校验和(真、假、真、真);1154 对于(int i=5;i<10;+i)1155 fillDB(db_u.get(),keys_迭代*i,keys_迭代*(i+1));1156 断言_OK(backup_engine_u->createNewbackup(db_.get(),true));1157 }1158 closedbandbackupengine();1159 1160 对于(int i=0;i<5;+i)1161 断言备份一致性(i+1,0,键迭代*(i+5+1)1162 按键重复*11);1163 }1164}1165 1166测试(backupabledbtest,deletetmpfiles)1167 for(bool shared_checksum:false,true)1168 if(共享校验和)1169 opendbandbackupengineeshareewithchecksum(1170 错误/*销毁旧数据*/, false /* dummy */,1171 1172 /*e/*共享_table_files*/,true/*与_checksums*/)共享_;1173 }否则{1174 opendbandbackupengine();1175 }1176 closedbandbackupengine();1177 std::string shared_tmp=backupdir_u;1178 if(共享校验和)1179 shared_tmp+=“/shared_checksum”;1180 }否则{1181 shared_tmp+=“/shared”;1182 }1183 shared_tmp+=“/00006.sst.tmp”;1184 std::string private_tmp_dir=backupdir_+“/private/10.tmp”;1185 std::string private_tmp_file=private_tmp_dir+“/00003.sst”;1186 文件管理器->writetofile(shared_tmp,“tmp”);1187 文件管理器创建目录(private目录);1188 file_manager_u->writetofile(private_tmp_file,“tmp”);1189 断言_OK(文件_manager_u->fileexists(private_tmp_dir));1190 if(共享校验和)1191 opendbandbackupengineeshareewithchecksum(1192 错误/*销毁旧数据*/, false /* dummy */,1193 1194 /*e/*共享_table_files*/,true/*与_checksums*/)共享_;1195 }否则{1196 opendbandbackupengine();1197 }1198 //需要显式调用此函数来删除tmp文件1199 (void)备份引擎_u->garbageCollect();1200 closedbandbackupengine();