| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058 |
- // Copyright (c) Meta Platforms, Inc. and affiliates.
- //
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- #include <functional>
- #include "db/db_test_util.h"
- #include "port/port.h"
- #include "port/stack_trace.h"
- #include "rocksdb/sst_file_writer.h"
- #include "test_util/testutil.h"
- #include "util/random.h"
- namespace ROCKSDB_NAMESPACE {
- class ImportColumnFamilyTest : public DBTestBase {
- public:
- ImportColumnFamilyTest()
- : DBTestBase("import_column_family_test", /*env_do_fsync=*/true) {
- sst_files_dir_ = dbname_ + "/sst_files/";
- export_files_dir_ = test::PerThreadDBPath(env_, "export");
- export_files_dir2_ = test::PerThreadDBPath(env_, "export2");
- DestroyAndRecreateExternalSSTFilesDir();
- import_cfh_ = nullptr;
- import_cfh2_ = nullptr;
- metadata_ptr_ = nullptr;
- metadata_ptr2_ = nullptr;
- }
- ~ImportColumnFamilyTest() {
- if (import_cfh_) {
- EXPECT_OK(db_->DropColumnFamily(import_cfh_));
- EXPECT_OK(db_->DestroyColumnFamilyHandle(import_cfh_));
- import_cfh_ = nullptr;
- }
- if (import_cfh2_) {
- EXPECT_OK(db_->DropColumnFamily(import_cfh2_));
- EXPECT_OK(db_->DestroyColumnFamilyHandle(import_cfh2_));
- import_cfh2_ = nullptr;
- }
- if (metadata_ptr_) {
- delete metadata_ptr_;
- metadata_ptr_ = nullptr;
- }
- if (metadata_ptr2_) {
- delete metadata_ptr2_;
- metadata_ptr2_ = nullptr;
- }
- EXPECT_OK(DestroyDir(env_, sst_files_dir_));
- EXPECT_OK(DestroyDir(env_, export_files_dir_));
- EXPECT_OK(DestroyDir(env_, export_files_dir2_));
- }
- void DestroyAndRecreateExternalSSTFilesDir() {
- EXPECT_OK(DestroyDir(env_, sst_files_dir_));
- EXPECT_OK(env_->CreateDir(sst_files_dir_));
- EXPECT_OK(DestroyDir(env_, export_files_dir_));
- EXPECT_OK(DestroyDir(env_, export_files_dir2_));
- }
- LiveFileMetaData LiveFileMetaDataInit(std::string name, std::string path,
- int level,
- SequenceNumber smallest_seqno,
- SequenceNumber largest_seqno) {
- LiveFileMetaData metadata;
- metadata.name = name;
- metadata.db_path = path;
- metadata.smallest_seqno = smallest_seqno;
- metadata.largest_seqno = largest_seqno;
- metadata.level = level;
- return metadata;
- }
- protected:
- std::string sst_files_dir_;
- std::string export_files_dir_;
- std::string export_files_dir2_;
- ColumnFamilyHandle* import_cfh_;
- ColumnFamilyHandle* import_cfh2_;
- ExportImportFilesMetaData* metadata_ptr_;
- ExportImportFilesMetaData* metadata_ptr2_;
- };
- TEST_F(ImportColumnFamilyTest, ImportSSTFileWriterFiles) {
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
- SstFileWriter sfw_unknown(EnvOptions(), options);
- // cf1.sst
- const std::string cf1_sst_name = "cf1.sst";
- const std::string cf1_sst = sst_files_dir_ + cf1_sst_name;
- ASSERT_OK(sfw_cf1.Open(cf1_sst));
- ASSERT_OK(sfw_cf1.Put("K1", "V1"));
- ASSERT_OK(sfw_cf1.Put("K2", "V2"));
- ASSERT_OK(sfw_cf1.Finish());
- // cf_unknown.sst
- const std::string unknown_sst_name = "cf_unknown.sst";
- const std::string unknown_sst = sst_files_dir_ + unknown_sst_name;
- ASSERT_OK(sfw_unknown.Open(unknown_sst));
- ASSERT_OK(sfw_unknown.Put("K3", "V1"));
- ASSERT_OK(sfw_unknown.Put("K4", "V2"));
- ASSERT_OK(sfw_unknown.Finish());
- {
- // Import sst file corresponding to cf1 onto a new cf and verify
- ExportImportFilesMetaData metadata;
- metadata.files.push_back(
- LiveFileMetaDataInit(cf1_sst_name, sst_files_dir_, 0, 10, 19));
- metadata.db_comparator_name = options.comparator->Name();
- ASSERT_OK(db_->CreateColumnFamilyWithImport(
- options, "toto", ImportColumnFamilyOptions(), metadata, &import_cfh_));
- ASSERT_NE(import_cfh_, nullptr);
- std::string value;
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, "K1", &value));
- ASSERT_EQ(value, "V1");
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, "K2", &value));
- ASSERT_EQ(value, "V2");
- ASSERT_OK(db_->DropColumnFamily(import_cfh_));
- ASSERT_OK(db_->DestroyColumnFamilyHandle(import_cfh_));
- import_cfh_ = nullptr;
- }
- {
- // Import sst file corresponding to unknown cf onto a new cf and verify
- ExportImportFilesMetaData metadata;
- metadata.files.push_back(
- LiveFileMetaDataInit(unknown_sst_name, sst_files_dir_, 0, 20, 29));
- metadata.db_comparator_name = options.comparator->Name();
- ASSERT_OK(db_->CreateColumnFamilyWithImport(
- options, "yoyo", ImportColumnFamilyOptions(), metadata, &import_cfh_));
- ASSERT_NE(import_cfh_, nullptr);
- std::string value;
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, "K3", &value));
- ASSERT_EQ(value, "V1");
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, "K4", &value));
- ASSERT_EQ(value, "V2");
- }
- EXPECT_OK(db_->DestroyColumnFamilyHandle(import_cfh_));
- import_cfh_ = nullptr;
- // verify sst unique id during reopen
- options.verify_sst_unique_id_in_manifest = true;
- ReopenWithColumnFamilies({"default", "koko", "yoyo"}, options);
- }
- TEST_F(ImportColumnFamilyTest, ImportSSTFileWriterFilesWithOverlap) {
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
- // file3.sst
- const std::string file3_sst_name = "file3.sst";
- const std::string file3_sst = sst_files_dir_ + file3_sst_name;
- ASSERT_OK(sfw_cf1.Open(file3_sst));
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(sfw_cf1.Put(Key(i), Key(i) + "_val"));
- }
- ASSERT_OK(sfw_cf1.Finish());
- // file2.sst
- const std::string file2_sst_name = "file2.sst";
- const std::string file2_sst = sst_files_dir_ + file2_sst_name;
- ASSERT_OK(sfw_cf1.Open(file2_sst));
- for (int i = 0; i < 100; i += 2) {
- ASSERT_OK(sfw_cf1.Put(Key(i), Key(i) + "_overwrite1"));
- }
- ASSERT_OK(sfw_cf1.Finish());
- // file1a.sst
- const std::string file1a_sst_name = "file1a.sst";
- const std::string file1a_sst = sst_files_dir_ + file1a_sst_name;
- ASSERT_OK(sfw_cf1.Open(file1a_sst));
- for (int i = 0; i < 52; i += 4) {
- ASSERT_OK(sfw_cf1.Put(Key(i), Key(i) + "_overwrite2"));
- }
- ASSERT_OK(sfw_cf1.Finish());
- // file1b.sst
- const std::string file1b_sst_name = "file1b.sst";
- const std::string file1b_sst = sst_files_dir_ + file1b_sst_name;
- ASSERT_OK(sfw_cf1.Open(file1b_sst));
- for (int i = 52; i < 100; i += 4) {
- ASSERT_OK(sfw_cf1.Put(Key(i), Key(i) + "_overwrite2"));
- }
- ASSERT_OK(sfw_cf1.Finish());
- // file0a.sst
- const std::string file0a_sst_name = "file0a.sst";
- const std::string file0a_sst = sst_files_dir_ + file0a_sst_name;
- ASSERT_OK(sfw_cf1.Open(file0a_sst));
- for (int i = 0; i < 100; i += 16) {
- ASSERT_OK(sfw_cf1.Put(Key(i), Key(i) + "_overwrite3"));
- }
- ASSERT_OK(sfw_cf1.Finish());
- // file0b.sst
- const std::string file0b_sst_name = "file0b.sst";
- const std::string file0b_sst = sst_files_dir_ + file0b_sst_name;
- ASSERT_OK(sfw_cf1.Open(file0b_sst));
- for (int i = 0; i < 100; i += 16) {
- ASSERT_OK(sfw_cf1.Put(Key(i), Key(i) + "_overwrite4"));
- }
- ASSERT_OK(sfw_cf1.Finish());
- // Import sst files and verify
- ExportImportFilesMetaData metadata;
- metadata.files.push_back(
- LiveFileMetaDataInit(file3_sst_name, sst_files_dir_, 3, 10, 19));
- metadata.files.push_back(
- LiveFileMetaDataInit(file2_sst_name, sst_files_dir_, 2, 20, 29));
- metadata.files.push_back(
- LiveFileMetaDataInit(file1a_sst_name, sst_files_dir_, 1, 30, 34));
- metadata.files.push_back(
- LiveFileMetaDataInit(file1b_sst_name, sst_files_dir_, 1, 35, 39));
- metadata.files.push_back(
- LiveFileMetaDataInit(file0a_sst_name, sst_files_dir_, 0, 40, 49));
- metadata.files.push_back(
- LiveFileMetaDataInit(file0b_sst_name, sst_files_dir_, 0, 50, 59));
- metadata.db_comparator_name = options.comparator->Name();
- ASSERT_OK(db_->CreateColumnFamilyWithImport(
- options, "toto", ImportColumnFamilyOptions(), metadata, &import_cfh_));
- ASSERT_NE(import_cfh_, nullptr);
- for (int i = 0; i < 100; i++) {
- std::string value;
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value));
- if (i % 16 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite4");
- } else if (i % 4 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite2");
- } else if (i % 2 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite1");
- } else {
- ASSERT_EQ(value, Key(i) + "_val");
- }
- }
- for (int i = 0; i < 100; i += 5) {
- ASSERT_OK(
- db_->Put(WriteOptions(), import_cfh_, Key(i), Key(i) + "_overwrite5"));
- }
- // Flush and check again
- ASSERT_OK(db_->Flush(FlushOptions(), import_cfh_));
- for (int i = 0; i < 100; i++) {
- std::string value;
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value));
- if (i % 5 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite5");
- } else if (i % 16 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite4");
- } else if (i % 4 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite2");
- } else if (i % 2 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite1");
- } else {
- ASSERT_EQ(value, Key(i) + "_val");
- }
- }
- // Compact and check again.
- ASSERT_OK(
- db_->CompactRange(CompactRangeOptions(), import_cfh_, nullptr, nullptr));
- for (int i = 0; i < 100; i++) {
- std::string value;
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value));
- if (i % 5 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite5");
- } else if (i % 16 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite4");
- } else if (i % 4 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite2");
- } else if (i % 2 == 0) {
- ASSERT_EQ(value, Key(i) + "_overwrite1");
- } else {
- ASSERT_EQ(value, Key(i) + "_val");
- }
- }
- }
- TEST_F(ImportColumnFamilyTest, ImportSSTFileWriterFilesWithRangeTombstone) {
- // Test for a bug where import file's smallest and largest key did not
- // consider range tombstone.
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
- // cf1.sst
- const std::string cf1_sst_name = "cf1.sst";
- const std::string cf1_sst = sst_files_dir_ + cf1_sst_name;
- ASSERT_OK(sfw_cf1.Open(cf1_sst));
- ASSERT_OK(sfw_cf1.Put("K1", "V1"));
- ASSERT_OK(sfw_cf1.Put("K2", "V2"));
- ASSERT_OK(sfw_cf1.DeleteRange("K3", "K4"));
- ASSERT_OK(sfw_cf1.DeleteRange("K7", "K9"));
- ASSERT_OK(sfw_cf1.Finish());
- // Import sst file corresponding to cf1 onto a new cf and verify
- ExportImportFilesMetaData metadata;
- metadata.files.push_back(
- LiveFileMetaDataInit(cf1_sst_name, sst_files_dir_, 0, 0, 19));
- metadata.db_comparator_name = options.comparator->Name();
- ASSERT_OK(db_->CreateColumnFamilyWithImport(
- options, "toto", ImportColumnFamilyOptions(), metadata, &import_cfh_));
- ASSERT_NE(import_cfh_, nullptr);
- ColumnFamilyMetaData import_cf_meta;
- db_->GetColumnFamilyMetaData(import_cfh_, &import_cf_meta);
- ASSERT_EQ(import_cf_meta.file_count, 1);
- const SstFileMetaData* file_meta = nullptr;
- for (const auto& level_meta : import_cf_meta.levels) {
- if (!level_meta.files.empty()) {
- file_meta = level_meta.files.data();
- break;
- }
- }
- ASSERT_TRUE(file_meta != nullptr);
- InternalKey largest;
- largest.DecodeFrom(file_meta->largest);
- ASSERT_EQ(largest.user_key(), "K9");
- std::string value;
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, "K1", &value));
- ASSERT_EQ(value, "V1");
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, "K2", &value));
- ASSERT_EQ(value, "V2");
- ASSERT_OK(db_->DropColumnFamily(import_cfh_));
- ASSERT_OK(db_->DestroyColumnFamilyHandle(import_cfh_));
- import_cfh_ = nullptr;
- }
- TEST_F(ImportColumnFamilyTest, ImportExportedSSTFromAnotherCF) {
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- }
- ASSERT_OK(Flush(1));
- ASSERT_OK(
- db_->CompactRange(CompactRangeOptions(), handles_[1], nullptr, nullptr));
- // Overwrite the value in the same set of keys.
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_overwrite"));
- }
- // Flush to create L0 file.
- ASSERT_OK(Flush(1));
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_overwrite2"));
- }
- // Flush again to create another L0 file. It should have higher sequencer.
- ASSERT_OK(Flush(1));
- Checkpoint* checkpoint;
- ASSERT_OK(Checkpoint::Create(db_, &checkpoint));
- ASSERT_OK(checkpoint->ExportColumnFamily(handles_[1], export_files_dir_,
- &metadata_ptr_));
- ASSERT_NE(metadata_ptr_, nullptr);
- delete checkpoint;
- ImportColumnFamilyOptions import_options;
- import_options.move_files = false;
- ASSERT_OK(db_->CreateColumnFamilyWithImport(options, "toto", import_options,
- *metadata_ptr_, &import_cfh_));
- ASSERT_NE(import_cfh_, nullptr);
- import_options.move_files = true;
- ASSERT_OK(db_->CreateColumnFamilyWithImport(options, "yoyo", import_options,
- *metadata_ptr_, &import_cfh2_));
- ASSERT_NE(import_cfh2_, nullptr);
- delete metadata_ptr_;
- metadata_ptr_ = nullptr;
- std::string value1, value2;
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value1));
- ASSERT_EQ(Get(1, Key(i)), value1);
- }
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh2_, Key(i), &value2));
- ASSERT_EQ(Get(1, Key(i)), value2);
- }
- // Modify keys in cf1 and verify.
- for (int i = 0; i < 25; i++) {
- ASSERT_OK(db_->Delete(WriteOptions(), import_cfh_, Key(i)));
- }
- for (int i = 25; i < 50; i++) {
- ASSERT_OK(
- db_->Put(WriteOptions(), import_cfh_, Key(i), Key(i) + "_overwrite3"));
- }
- for (int i = 0; i < 25; ++i) {
- ASSERT_TRUE(
- db_->Get(ReadOptions(), import_cfh_, Key(i), &value1).IsNotFound());
- }
- for (int i = 25; i < 50; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value1));
- ASSERT_EQ(Key(i) + "_overwrite3", value1);
- }
- for (int i = 50; i < 100; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value1));
- ASSERT_EQ(Key(i) + "_overwrite2", value1);
- }
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh2_, Key(i), &value2));
- ASSERT_EQ(Get(1, Key(i)), value2);
- }
- // Compact and check again.
- ASSERT_OK(db_->Flush(FlushOptions(), import_cfh_));
- ASSERT_OK(
- db_->CompactRange(CompactRangeOptions(), import_cfh_, nullptr, nullptr));
- for (int i = 0; i < 25; ++i) {
- ASSERT_TRUE(
- db_->Get(ReadOptions(), import_cfh_, Key(i), &value1).IsNotFound());
- }
- for (int i = 25; i < 50; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value1));
- ASSERT_EQ(Key(i) + "_overwrite3", value1);
- }
- for (int i = 50; i < 100; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value1));
- ASSERT_EQ(Key(i) + "_overwrite2", value1);
- }
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh2_, Key(i), &value2));
- ASSERT_EQ(Get(1, Key(i)), value2);
- }
- }
- TEST_F(ImportColumnFamilyTest, ImportExportedSSTFromAnotherDB) {
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- }
- ASSERT_OK(Flush(1));
- // Compact to create a L1 file.
- ASSERT_OK(
- db_->CompactRange(CompactRangeOptions(), handles_[1], nullptr, nullptr));
- // Overwrite the value in the same set of keys.
- for (int i = 0; i < 50; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_overwrite"));
- }
- // Flush to create L0 file.
- ASSERT_OK(Flush(1));
- for (int i = 0; i < 25; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_overwrite2"));
- }
- // Flush again to create another L0 file. It should have higher sequencer.
- ASSERT_OK(Flush(1));
- Checkpoint* checkpoint;
- ASSERT_OK(Checkpoint::Create(db_, &checkpoint));
- ASSERT_OK(checkpoint->ExportColumnFamily(handles_[1], export_files_dir_,
- &metadata_ptr_));
- ASSERT_NE(metadata_ptr_, nullptr);
- delete checkpoint;
- // Create a new db and import the files.
- DB* db_copy;
- ASSERT_OK(DestroyDir(env_, dbname_ + "/db_copy"));
- ASSERT_OK(DB::Open(options, dbname_ + "/db_copy", &db_copy));
- ColumnFamilyHandle* cfh = nullptr;
- ASSERT_OK(db_copy->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
- ImportColumnFamilyOptions(),
- *metadata_ptr_, &cfh));
- ASSERT_NE(cfh, nullptr);
- for (int i = 0; i < 100; ++i) {
- std::string value;
- ASSERT_OK(db_copy->Get(ReadOptions(), cfh, Key(i), &value));
- ASSERT_EQ(Get(1, Key(i)), value);
- }
- ASSERT_OK(db_copy->DropColumnFamily(cfh));
- ASSERT_OK(db_copy->DestroyColumnFamilyHandle(cfh));
- delete db_copy;
- ASSERT_OK(DestroyDir(env_, dbname_ + "/db_copy"));
- }
- TEST_F(ImportColumnFamilyTest,
- ImportExportedSSTFromAnotherCFWithRangeTombstone) {
- // Test for a bug where import file's smallest and largest key did not
- // consider range tombstone.
- Options options = CurrentOptions();
- options.disable_auto_compactions = true;
- CreateAndReopenWithCF({"koko"}, options);
- for (int i = 10; i < 20; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- }
- ASSERT_OK(Flush(1 /* cf */));
- MoveFilesToLevel(1 /* level */, 1 /* cf */);
- const Snapshot* snapshot = db_->GetSnapshot();
- ASSERT_OK(db_->DeleteRange(WriteOptions(), handles_[1], Key(0), Key(25)));
- ASSERT_OK(Put(1, Key(1), "t"));
- ASSERT_OK(Flush(1));
- // Tests importing a range tombstone only file
- ASSERT_OK(db_->DeleteRange(WriteOptions(), handles_[1], Key(0), Key(2)));
- Checkpoint* checkpoint;
- ASSERT_OK(Checkpoint::Create(db_, &checkpoint));
- ASSERT_OK(checkpoint->ExportColumnFamily(handles_[1], export_files_dir_,
- &metadata_ptr_));
- ASSERT_NE(metadata_ptr_, nullptr);
- delete checkpoint;
- ImportColumnFamilyOptions import_options;
- import_options.move_files = false;
- ASSERT_OK(db_->CreateColumnFamilyWithImport(options, "toto", import_options,
- *metadata_ptr_, &import_cfh_));
- ASSERT_NE(import_cfh_, nullptr);
- import_options.move_files = true;
- ASSERT_OK(db_->CreateColumnFamilyWithImport(options, "yoyo", import_options,
- *metadata_ptr_, &import_cfh2_));
- ASSERT_NE(import_cfh2_, nullptr);
- delete metadata_ptr_;
- metadata_ptr_ = nullptr;
- std::string value1, value2;
- ReadOptions ro_latest;
- ReadOptions ro_snapshot;
- ro_snapshot.snapshot = snapshot;
- for (int i = 10; i < 20; ++i) {
- ASSERT_TRUE(db_->Get(ro_latest, import_cfh_, Key(i), &value1).IsNotFound());
- ASSERT_OK(db_->Get(ro_snapshot, import_cfh_, Key(i), &value1));
- ASSERT_EQ(Get(1, Key(i), snapshot), value1);
- }
- ASSERT_TRUE(db_->Get(ro_latest, import_cfh_, Key(1), &value1).IsNotFound());
- for (int i = 10; i < 20; ++i) {
- ASSERT_TRUE(
- db_->Get(ro_latest, import_cfh2_, Key(i), &value1).IsNotFound());
- ASSERT_OK(db_->Get(ro_snapshot, import_cfh2_, Key(i), &value2));
- ASSERT_EQ(Get(1, Key(i), snapshot), value2);
- }
- ASSERT_TRUE(db_->Get(ro_latest, import_cfh2_, Key(1), &value1).IsNotFound());
- db_->ReleaseSnapshot(snapshot);
- }
- TEST_F(ImportColumnFamilyTest, LevelFilesOverlappingAtEndpoints) {
- // Imports a column family containing a level where two files overlap at their
- // endpoints. "Overlap" means the largest user key in one file is the same as
- // the smallest user key in the second file.
- const int kFileBytes = 128 << 10; // 128KB
- const int kValueBytes = 1 << 10; // 1KB
- const int kNumFiles = 4;
- Options options = CurrentOptions();
- options.disable_auto_compactions = true;
- options.num_levels = 2;
- CreateAndReopenWithCF({"koko"}, options);
- Random rnd(301);
- // Every key is snapshot protected to ensure older versions will not be
- // dropped during compaction.
- std::vector<const Snapshot*> snapshots;
- snapshots.reserve(kFileBytes / kValueBytes * kNumFiles);
- for (int i = 0; i < kNumFiles; ++i) {
- for (int j = 0; j < kFileBytes / kValueBytes; ++j) {
- auto value = rnd.RandomString(kValueBytes);
- ASSERT_OK(Put(1, "key", value));
- snapshots.push_back(db_->GetSnapshot());
- }
- ASSERT_OK(Flush(1));
- }
- // Compact to create overlapping L1 files.
- ASSERT_OK(
- db_->CompactRange(CompactRangeOptions(), handles_[1], nullptr, nullptr));
- ASSERT_GT(NumTableFilesAtLevel(1, 1), 1);
- Checkpoint* checkpoint;
- ASSERT_OK(Checkpoint::Create(db_, &checkpoint));
- ASSERT_OK(checkpoint->ExportColumnFamily(handles_[1], export_files_dir_,
- &metadata_ptr_));
- ASSERT_NE(metadata_ptr_, nullptr);
- delete checkpoint;
- // Create a new db and import the files.
- DB* db_copy;
- ASSERT_OK(DestroyDir(env_, dbname_ + "/db_copy"));
- ASSERT_OK(DB::Open(options, dbname_ + "/db_copy", &db_copy));
- ColumnFamilyHandle* cfh = nullptr;
- ASSERT_OK(db_copy->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
- ImportColumnFamilyOptions(),
- *metadata_ptr_, &cfh));
- ASSERT_NE(cfh, nullptr);
- {
- std::string value;
- ASSERT_OK(db_copy->Get(ReadOptions(), cfh, "key", &value));
- }
- ASSERT_OK(db_copy->DropColumnFamily(cfh));
- ASSERT_OK(db_copy->DestroyColumnFamilyHandle(cfh));
- delete db_copy;
- ASSERT_OK(DestroyDir(env_, dbname_ + "/db_copy"));
- for (const Snapshot* snapshot : snapshots) {
- db_->ReleaseSnapshot(snapshot);
- }
- }
- TEST_F(ImportColumnFamilyTest, ImportColumnFamilyNegativeTest) {
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- {
- // Create column family with existing cf name.
- ExportImportFilesMetaData metadata;
- metadata.db_comparator_name = options.comparator->Name();
- Status s = db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "koko",
- ImportColumnFamilyOptions(),
- metadata, &import_cfh_);
- ASSERT_TRUE(std::strstr(s.getState(), "Column family already exists"));
- ASSERT_EQ(import_cfh_, nullptr);
- }
- {
- // Import with no files specified.
- ExportImportFilesMetaData metadata;
- metadata.db_comparator_name = options.comparator->Name();
- Status s = db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
- ImportColumnFamilyOptions(),
- metadata, &import_cfh_);
- ASSERT_TRUE(std::strstr(s.getState(), "The list of files is empty"));
- ASSERT_EQ(import_cfh_, nullptr);
- }
- {
- // Import with overlapping keys in sst files.
- ExportImportFilesMetaData metadata;
- SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
- const std::string file1_sst_name = "file1.sst";
- const std::string file1_sst = sst_files_dir_ + file1_sst_name;
- ASSERT_OK(sfw_cf1.Open(file1_sst));
- ASSERT_OK(sfw_cf1.Put("K1", "V1"));
- ASSERT_OK(sfw_cf1.Put("K2", "V2"));
- ASSERT_OK(sfw_cf1.Finish());
- const std::string file2_sst_name = "file2.sst";
- const std::string file2_sst = sst_files_dir_ + file2_sst_name;
- ASSERT_OK(sfw_cf1.Open(file2_sst));
- ASSERT_OK(sfw_cf1.Put("K2", "V2"));
- ASSERT_OK(sfw_cf1.Put("K3", "V3"));
- ASSERT_OK(sfw_cf1.Finish());
- metadata.files.push_back(
- LiveFileMetaDataInit(file1_sst_name, sst_files_dir_, 1, 10, 19));
- metadata.files.push_back(
- LiveFileMetaDataInit(file2_sst_name, sst_files_dir_, 1, 10, 19));
- metadata.db_comparator_name = options.comparator->Name();
- ASSERT_NOK(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
- ImportColumnFamilyOptions(),
- metadata, &import_cfh_));
- ASSERT_EQ(import_cfh_, nullptr);
- }
- {
- // Import with a mismatching comparator, should fail with appropriate error.
- ExportImportFilesMetaData metadata;
- Options mismatch_options = CurrentOptions();
- mismatch_options.comparator = ReverseBytewiseComparator();
- SstFileWriter sfw_cf1(EnvOptions(), mismatch_options, handles_[1]);
- const std::string file1_sst_name = "file1.sst";
- const std::string file1_sst = sst_files_dir_ + file1_sst_name;
- ASSERT_OK(sfw_cf1.Open(file1_sst));
- ASSERT_OK(sfw_cf1.Put("K2", "V2"));
- ASSERT_OK(sfw_cf1.Put("K1", "V1"));
- ASSERT_OK(sfw_cf1.Finish());
- metadata.files.push_back(
- LiveFileMetaDataInit(file1_sst_name, sst_files_dir_, 1, 10, 19));
- metadata.db_comparator_name = mismatch_options.comparator->Name();
- Status s = db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "coco",
- ImportColumnFamilyOptions(),
- metadata, &import_cfh_);
- ASSERT_TRUE(std::strstr(s.getState(), "Comparator name mismatch"));
- ASSERT_EQ(import_cfh_, nullptr);
- }
- {
- // Import with non existent sst file should fail with appropriate error
- ExportImportFilesMetaData metadata;
- SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
- const std::string file1_sst_name = "file1.sst";
- const std::string file1_sst = sst_files_dir_ + file1_sst_name;
- ASSERT_OK(sfw_cf1.Open(file1_sst));
- ASSERT_OK(sfw_cf1.Put("K1", "V1"));
- ASSERT_OK(sfw_cf1.Put("K2", "V2"));
- ASSERT_OK(sfw_cf1.Finish());
- const std::string file3_sst_name = "file3.sst";
- metadata.files.push_back(
- LiveFileMetaDataInit(file1_sst_name, sst_files_dir_, 1, 10, 19));
- metadata.files.push_back(
- LiveFileMetaDataInit(file3_sst_name, sst_files_dir_, 1, 10, 19));
- metadata.db_comparator_name = options.comparator->Name();
- Status s = db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
- ImportColumnFamilyOptions(),
- metadata, &import_cfh_);
- ASSERT_TRUE(std::strstr(s.getState(), "No such file or directory"));
- ASSERT_EQ(import_cfh_, nullptr);
- // Test successful import after a failure with the same CF name. Ensures
- // there is no side effect with CF when there is a failed import
- metadata.files.pop_back();
- metadata.db_comparator_name = options.comparator->Name();
- ASSERT_OK(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
- ImportColumnFamilyOptions(),
- metadata, &import_cfh_));
- ASSERT_NE(import_cfh_, nullptr);
- }
- }
- TEST_F(ImportColumnFamilyTest, ImportMultiColumnFamilyTest) {
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- }
- ASSERT_OK(Flush(1));
- ASSERT_OK(
- db_->CompactRange(CompactRangeOptions(), handles_[1], nullptr, nullptr));
- // Overwrite the value in the same set of keys.
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_overwrite"));
- }
- // Flush again to create another L0 file. It should have higher sequencer.
- ASSERT_OK(Flush(1));
- Checkpoint* checkpoint1;
- Checkpoint* checkpoint2;
- ASSERT_OK(Checkpoint::Create(db_, &checkpoint1));
- ASSERT_OK(checkpoint1->ExportColumnFamily(handles_[1], export_files_dir_,
- &metadata_ptr_));
- // Create a new db and import the files.
- DB* db_copy;
- ASSERT_OK(DestroyDir(env_, dbname_ + "/db_copy"));
- ASSERT_OK(DB::Open(options, dbname_ + "/db_copy", &db_copy));
- ColumnFamilyHandle* copy_cfh = nullptr;
- ASSERT_OK(db_copy->CreateColumnFamily(options, "koko", ©_cfh));
- WriteOptions wo;
- for (int i = 100; i < 200; ++i) {
- ASSERT_OK(db_copy->Put(wo, copy_cfh, Key(i), Key(i) + "_val"));
- }
- ASSERT_OK(db_copy->Flush(FlushOptions()));
- for (int i = 100; i < 200; ++i) {
- ASSERT_OK(db_copy->Put(wo, copy_cfh, Key(i), Key(i) + "_overwrite"));
- }
- ASSERT_OK(db_copy->Flush(FlushOptions()));
- for (int i = 100; i < 200; ++i) {
- ASSERT_OK(db_copy->Put(wo, copy_cfh, Key(i), Key(i) + "_overwrite2"));
- }
- ASSERT_OK(db_copy->Flush(FlushOptions()));
- // Flush again to create another L0 file. It should have higher sequencer.
- ASSERT_OK(Checkpoint::Create(db_copy, &checkpoint2));
- ASSERT_OK(checkpoint2->ExportColumnFamily(copy_cfh, export_files_dir2_,
- &metadata_ptr2_));
- ASSERT_NE(metadata_ptr_, nullptr);
- ASSERT_NE(metadata_ptr2_, nullptr);
- delete checkpoint1;
- delete checkpoint2;
- ImportColumnFamilyOptions import_options;
- import_options.move_files = false;
- std::vector<const ExportImportFilesMetaData*> metadatas = {metadata_ptr_,
- metadata_ptr2_};
- ASSERT_OK(db_->CreateColumnFamilyWithImport(options, "toto", import_options,
- metadatas, &import_cfh_));
- std::string value1, value2;
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value1));
- ASSERT_EQ(Get(1, Key(i)), value1);
- }
- for (int i = 100; i < 200; ++i) {
- ASSERT_OK(db_->Get(ReadOptions(), import_cfh_, Key(i), &value1));
- ASSERT_OK(db_copy->Get(ReadOptions(), copy_cfh, Key(i), &value2));
- ASSERT_EQ(value1, value2);
- }
- ASSERT_OK(db_copy->DropColumnFamily(copy_cfh));
- ASSERT_OK(db_copy->DestroyColumnFamilyHandle(copy_cfh));
- delete db_copy;
- ASSERT_OK(DestroyDir(env_, dbname_ + "/db_copy"));
- }
- TEST_F(ImportColumnFamilyTest, ImportMultiColumnFamilyWithOverlap) {
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- }
- Checkpoint* checkpoint1;
- Checkpoint* checkpoint2;
- ASSERT_OK(Checkpoint::Create(db_, &checkpoint1));
- ASSERT_OK(checkpoint1->ExportColumnFamily(handles_[1], export_files_dir_,
- &metadata_ptr_));
- // Create a new db and import the files.
- DB* db_copy;
- ASSERT_OK(DestroyDir(env_, dbname_ + "/db_copy"));
- ASSERT_OK(DB::Open(options, dbname_ + "/db_copy", &db_copy));
- ColumnFamilyHandle* copy_cfh = nullptr;
- ASSERT_OK(db_copy->CreateColumnFamily(options, "koko", ©_cfh));
- WriteOptions wo;
- for (int i = 50; i < 150; ++i) {
- ASSERT_OK(db_copy->Put(wo, copy_cfh, Key(i), Key(i) + "_val"));
- }
- ASSERT_OK(db_copy->Flush(FlushOptions()));
- // Flush again to create another L0 file. It should have higher sequencer.
- ASSERT_OK(Checkpoint::Create(db_copy, &checkpoint2));
- ASSERT_OK(checkpoint2->ExportColumnFamily(copy_cfh, export_files_dir2_,
- &metadata_ptr2_));
- ASSERT_NE(metadata_ptr_, nullptr);
- ASSERT_NE(metadata_ptr2_, nullptr);
- delete checkpoint1;
- delete checkpoint2;
- ImportColumnFamilyOptions import_options;
- import_options.move_files = false;
- std::vector<const ExportImportFilesMetaData*> metadatas = {metadata_ptr_,
- metadata_ptr2_};
- ASSERT_EQ(db_->CreateColumnFamilyWithImport(options, "toto", import_options,
- metadatas, &import_cfh_),
- Status::InvalidArgument("CFs have overlapping ranges"));
- ASSERT_OK(db_copy->DropColumnFamily(copy_cfh));
- ASSERT_OK(db_copy->DestroyColumnFamilyHandle(copy_cfh));
- delete db_copy;
- ASSERT_OK(DestroyDir(env_, dbname_ + "/db_copy"));
- }
- TEST_F(ImportColumnFamilyTest, ImportMultiColumnFamilySeveralFilesWithOverlap) {
- Options options = CurrentOptions();
- CreateAndReopenWithCF({"koko"}, options);
- SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
- const std::string file1_sst_name = "file1.sst";
- const std::string file1_sst = sst_files_dir_ + file1_sst_name;
- ASSERT_OK(sfw_cf1.Open(file1_sst));
- ASSERT_OK(sfw_cf1.Put("K1", "V1"));
- ASSERT_OK(sfw_cf1.Put("K2", "V2"));
- ASSERT_OK(sfw_cf1.Finish());
- SstFileWriter sfw_cf2(EnvOptions(), options, handles_[1]);
- const std::string file2_sst_name = "file2.sst";
- const std::string file2_sst = sst_files_dir_ + file2_sst_name;
- ASSERT_OK(sfw_cf2.Open(file2_sst));
- ASSERT_OK(sfw_cf2.Put("K2", "V2"));
- ASSERT_OK(sfw_cf2.Put("K3", "V3"));
- ASSERT_OK(sfw_cf2.Finish());
- ColumnFamilyHandle* second_cfh = nullptr;
- ASSERT_OK(db_->CreateColumnFamily(options, "toto", &second_cfh));
- SstFileWriter sfw_cf3(EnvOptions(), options, second_cfh);
- const std::string file3_sst_name = "file3.sst";
- const std::string file3_sst = sst_files_dir_ + file3_sst_name;
- ASSERT_OK(sfw_cf3.Open(file3_sst));
- ASSERT_OK(sfw_cf3.Put("K3", "V3"));
- ASSERT_OK(sfw_cf3.Put("K4", "V4"));
- ASSERT_OK(sfw_cf3.Finish());
- SstFileWriter sfw_cf4(EnvOptions(), options, second_cfh);
- const std::string file4_sst_name = "file4.sst";
- const std::string file4_sst = sst_files_dir_ + file4_sst_name;
- ASSERT_OK(sfw_cf4.Open(file4_sst));
- ASSERT_OK(sfw_cf4.Put("K4", "V4"));
- ASSERT_OK(sfw_cf4.Put("K5", "V5"));
- ASSERT_OK(sfw_cf4.Finish());
- ExportImportFilesMetaData metadata1, metadata2;
- metadata1.files.push_back(
- LiveFileMetaDataInit(file1_sst_name, sst_files_dir_, 1, 1, 2));
- metadata1.files.push_back(
- LiveFileMetaDataInit(file2_sst_name, sst_files_dir_, 1, 3, 4));
- metadata1.db_comparator_name = options.comparator->Name();
- metadata2.files.push_back(
- LiveFileMetaDataInit(file3_sst_name, sst_files_dir_, 1, 1, 2));
- metadata2.files.push_back(
- LiveFileMetaDataInit(file4_sst_name, sst_files_dir_, 1, 3, 4));
- metadata2.db_comparator_name = options.comparator->Name();
- std::vector<const ExportImportFilesMetaData*> metadatas{&metadata1,
- &metadata2};
- ASSERT_EQ(db_->CreateColumnFamilyWithImport(ColumnFamilyOptions(), "yoyo",
- ImportColumnFamilyOptions(),
- metadatas, &import_cfh_),
- Status::InvalidArgument("CFs have overlapping ranges"));
- ASSERT_EQ(import_cfh_, nullptr);
- ASSERT_OK(db_->DropColumnFamily(second_cfh));
- ASSERT_OK(db_->DestroyColumnFamilyHandle(second_cfh));
- }
- TEST_F(ImportColumnFamilyTest, AssignEpochNumberToMultipleCF) {
- // Test ingesting CFs where L0 files could have the same epoch number.
- Options options = CurrentOptions();
- options.level_compaction_dynamic_level_bytes = true;
- options.max_background_jobs = 8;
- // Always allow parallel compaction
- options.soft_pending_compaction_bytes_limit = 10;
- env_->SetBackgroundThreads(2, Env::LOW);
- env_->SetBackgroundThreads(0, Env::BOTTOM);
- CreateAndReopenWithCF({"CF1", "CF2"}, options);
- // CF1:
- // L6: [0, 99], [100, 199]
- // CF2:
- // L6: [1000, 1099], [1100, 1199]
- for (int i = 100; i < 200; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- ASSERT_OK(Put(2, Key(1000 + i), Key(1000 + i) + "_val"));
- }
- ASSERT_OK(Flush(1));
- ASSERT_OK(Flush(2));
- for (int i = 0; i < 100; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- ASSERT_OK(Put(2, Key(1000 + i), Key(1000 + i) + "_val"));
- }
- ASSERT_OK(Flush(1));
- ASSERT_OK(Flush(2));
- MoveFilesToLevel(6, 1);
- MoveFilesToLevel(6, 2);
- // CF1:
- // level 0 epoch: 5 file num 30 smallest key000010 - key000019
- // level 0 epoch: 4 file num 27 smallest key000000 - key000009
- // level 0 epoch: 3 file num 23 smallest key000100 - key000199
- // level 6 epoch: 2 file num 20 smallest key000000 - key000099
- // level 6 epoch: 1 file num 17 smallest key000100 - key000199
- // CF2:
- // level 0 epoch: 5 file num 31 smallest key001010 - key001019
- // level 0 epoch: 4 file num 28 smallest key001000 - key001009
- // level 0 epoch: 3 file num 25 smallest key001020 - key001029
- // level 6 epoch: 2 file num 21 smallest key001000 - key001099
- // level 6 epoch: 1 file num 18 smallest key001100 - key001199
- for (int i = 100; i < 200; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- }
- ASSERT_OK(Flush(1));
- for (int i = 20; i < 30; ++i) {
- ASSERT_OK(Put(2, Key(i + 1000), Key(i + 1000) + "_val"));
- }
- ASSERT_OK(Flush(2));
- for (int i = 0; i < 20; ++i) {
- ASSERT_OK(Put(1, Key(i), Key(i) + "_val"));
- ASSERT_OK(Put(2, Key(i + 1000), Key(i + 1000) + "_val"));
- if (i % 10 == 9) {
- ASSERT_OK(Flush(1));
- ASSERT_OK(Flush(2));
- }
- }
- ASSERT_OK(Flush(1));
- ASSERT_OK(Flush(2));
- // Create a CF by importing these two CF1 and CF2.
- // Then two compactions will be triggerred, one to compact from L0
- // to L6 (files #23 and #17), and another to do intra-L0 compaction
- // for the rest of the L0 files. Before a bug fix, we used to
- // directly use the epoch numbers from the ingested files in the new CF.
- // This means different files from different CFs can have the same epoch
- // number. If the intra-L0 compaction finishes first, it can cause a
- // corruption where two L0 files can have the same epoch number but
- // with overlapping key range.
- Checkpoint* checkpoint1;
- ASSERT_OK(Checkpoint::Create(db_, &checkpoint1));
- ASSERT_OK(checkpoint1->ExportColumnFamily(handles_[1], export_files_dir_,
- &metadata_ptr_));
- ASSERT_OK(checkpoint1->ExportColumnFamily(handles_[2], export_files_dir2_,
- &metadata_ptr2_));
- ASSERT_NE(metadata_ptr_, nullptr);
- ASSERT_NE(metadata_ptr2_, nullptr);
- std::atomic_int compaction_counter = 0;
- SyncPoint::GetInstance()->SetCallBack(
- "DBImpl::BackgroundCompaction:NonTrivial:BeforeRun",
- [&compaction_counter](void*) {
- compaction_counter++;
- if (compaction_counter == 1) {
- // Wait for the next compaction to finish
- TEST_SYNC_POINT("WaitForSecondCompaction");
- }
- });
- SyncPoint::GetInstance()->LoadDependency(
- {{"DBImpl::BackgroundCompaction:AfterCompaction",
- "WaitForSecondCompaction"}});
- SyncPoint::GetInstance()->EnableProcessing();
- ImportColumnFamilyOptions import_options;
- import_options.move_files = false;
- std::vector<const ExportImportFilesMetaData*> metadatas = {metadata_ptr_,
- metadata_ptr2_};
- ASSERT_OK(db_->CreateColumnFamilyWithImport(options, "CF3", import_options,
- metadatas, &import_cfh_));
- WaitForCompactOptions o;
- ASSERT_OK(db_->WaitForCompact(o));
- delete checkpoint1;
- }
- } // namespace ROCKSDB_NAMESPACE
- int main(int argc, char** argv) {
- ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
- }
|