@nxtedition/rocksdb 8.0.4 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BUILDING.md +2 -2
- package/binding.cc +72 -2
- package/deps/rocksdb/rocksdb/CMakeLists.txt +7 -0
- package/deps/rocksdb/rocksdb/Makefile +13 -1
- package/deps/rocksdb/rocksdb/db/builder.cc +13 -4
- package/deps/rocksdb/rocksdb/db/builder.h +2 -1
- package/deps/rocksdb/rocksdb/db/c.cc +6 -0
- package/deps/rocksdb/rocksdb/db/column_family.cc +1 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +18 -4
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +2 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +2 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +22 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +5 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +14 -14
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +1 -2
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +2 -3
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +225 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +8 -9
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +0 -8
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +63 -23
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +2 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +12 -8
- package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +115 -2
- package/deps/rocksdb/rocksdb/db/experimental.cc +2 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +1 -0
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +88 -12
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +38 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +14 -110
- package/deps/rocksdb/rocksdb/db/flush_job.cc +2 -3
- package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +1 -1
- package/deps/rocksdb/rocksdb/db/repair.cc +2 -1
- package/deps/rocksdb/rocksdb/db/version_builder_test.cc +41 -39
- package/deps/rocksdb/rocksdb/db/version_edit.cc +12 -0
- package/deps/rocksdb/rocksdb/db/version_edit.h +18 -6
- package/deps/rocksdb/rocksdb/db/version_edit_test.cc +9 -9
- package/deps/rocksdb/rocksdb/db/version_set.cc +12 -6
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +23 -9
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +4 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/c.h +4 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +7 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +2 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/backup_engine.h +69 -9
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +245 -74
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +195 -4
- package/index.js +17 -0
- package/max_rev_operator.h +100 -0
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/darwin-x64/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
|
@@ -800,6 +800,7 @@ TEST_P(ExternalSSTFileBasicTest, IngestFileWithMultipleValueType) {
|
|
|
800
800
|
bool verify_checksums_before_ingest = std::get<1>(GetParam());
|
|
801
801
|
do {
|
|
802
802
|
Options options = CurrentOptions();
|
|
803
|
+
options.disable_auto_compactions = true;
|
|
803
804
|
options.merge_operator.reset(new TestPutOperator());
|
|
804
805
|
DestroyAndReopen(options);
|
|
805
806
|
std::map<std::string, std::string> true_data;
|
|
@@ -473,13 +473,86 @@ Status ExternalSstFileIngestionJob::Run() {
|
|
|
473
473
|
ingestion_options_.ingest_behind
|
|
474
474
|
? kReservedEpochNumberForFileIngestedBehind
|
|
475
475
|
: cfd_->NewEpochNumber(),
|
|
476
|
-
f.file_checksum, f.file_checksum_func_name, f.unique_id);
|
|
476
|
+
f.file_checksum, f.file_checksum_func_name, f.unique_id, 0);
|
|
477
477
|
f_metadata.temperature = f.file_temperature;
|
|
478
478
|
edit_.AddFile(f.picked_level, f_metadata);
|
|
479
479
|
}
|
|
480
|
+
|
|
481
|
+
CreateEquivalentFileIngestingCompactions();
|
|
480
482
|
return status;
|
|
481
483
|
}
|
|
482
484
|
|
|
485
|
+
void ExternalSstFileIngestionJob::CreateEquivalentFileIngestingCompactions() {
|
|
486
|
+
// A map from output level to input of compactions equivalent to this
|
|
487
|
+
// ingestion job.
|
|
488
|
+
// TODO: simplify below logic to creating compaction per ingested file
|
|
489
|
+
// instead of per output level, once we figure out how to treat ingested files
|
|
490
|
+
// with adjacent range deletion tombstones to same output level in the same
|
|
491
|
+
// job as non-overlapping compactions.
|
|
492
|
+
std::map<int, CompactionInputFiles>
|
|
493
|
+
output_level_to_file_ingesting_compaction_input;
|
|
494
|
+
|
|
495
|
+
for (const auto& pair : edit_.GetNewFiles()) {
|
|
496
|
+
int output_level = pair.first;
|
|
497
|
+
const FileMetaData& f_metadata = pair.second;
|
|
498
|
+
|
|
499
|
+
CompactionInputFiles& input =
|
|
500
|
+
output_level_to_file_ingesting_compaction_input[output_level];
|
|
501
|
+
if (input.files.empty()) {
|
|
502
|
+
// Treat the source level of ingested files to be level 0
|
|
503
|
+
input.level = 0;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
compaction_input_metdatas_.push_back(new FileMetaData(f_metadata));
|
|
507
|
+
input.files.push_back(compaction_input_metdatas_.back());
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
for (const auto& pair : output_level_to_file_ingesting_compaction_input) {
|
|
511
|
+
int output_level = pair.first;
|
|
512
|
+
const CompactionInputFiles& input = pair.second;
|
|
513
|
+
|
|
514
|
+
const auto& mutable_cf_options = *(cfd_->GetLatestMutableCFOptions());
|
|
515
|
+
file_ingesting_compactions_.push_back(new Compaction(
|
|
516
|
+
cfd_->current()->storage_info(), *cfd_->ioptions(), mutable_cf_options,
|
|
517
|
+
mutable_db_options_, {input}, output_level,
|
|
518
|
+
MaxFileSizeForLevel(
|
|
519
|
+
mutable_cf_options, output_level,
|
|
520
|
+
cfd_->ioptions()->compaction_style) /* output file size
|
|
521
|
+
limit,
|
|
522
|
+
* not applicable
|
|
523
|
+
*/
|
|
524
|
+
,
|
|
525
|
+
LLONG_MAX /* max compaction bytes, not applicable */,
|
|
526
|
+
0 /* output path ID, not applicable */, mutable_cf_options.compression,
|
|
527
|
+
mutable_cf_options.compression_opts, Temperature::kUnknown,
|
|
528
|
+
0 /* max_subcompaction, not applicable */,
|
|
529
|
+
{} /* grandparents, not applicable */, false /* is manual */,
|
|
530
|
+
"" /* trim_ts */, -1 /* score, not applicable */,
|
|
531
|
+
false /* is deletion compaction, not applicable */,
|
|
532
|
+
files_overlap_ /* l0_files_might_overlap, not applicable */,
|
|
533
|
+
CompactionReason::kExternalSstIngestion));
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
void ExternalSstFileIngestionJob::RegisterRange() {
|
|
538
|
+
for (const auto& c : file_ingesting_compactions_) {
|
|
539
|
+
cfd_->compaction_picker()->RegisterCompaction(c);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
void ExternalSstFileIngestionJob::UnregisterRange() {
|
|
544
|
+
for (const auto& c : file_ingesting_compactions_) {
|
|
545
|
+
cfd_->compaction_picker()->UnregisterCompaction(c);
|
|
546
|
+
delete c;
|
|
547
|
+
}
|
|
548
|
+
file_ingesting_compactions_.clear();
|
|
549
|
+
|
|
550
|
+
for (const auto& f : compaction_input_metdatas_) {
|
|
551
|
+
delete f;
|
|
552
|
+
}
|
|
553
|
+
compaction_input_metdatas_.clear();
|
|
554
|
+
}
|
|
555
|
+
|
|
483
556
|
void ExternalSstFileIngestionJob::UpdateStats() {
|
|
484
557
|
// Update internal stats for new ingested files
|
|
485
558
|
uint64_t total_keys = 0;
|
|
@@ -798,8 +871,16 @@ Status ExternalSstFileIngestionJob::AssignLevelAndSeqnoForIngestedFile(
|
|
|
798
871
|
if (lvl > 0 && lvl < vstorage->base_level()) {
|
|
799
872
|
continue;
|
|
800
873
|
}
|
|
801
|
-
|
|
802
|
-
|
|
874
|
+
if (cfd_->RangeOverlapWithCompaction(
|
|
875
|
+
file_to_ingest->smallest_internal_key.user_key(),
|
|
876
|
+
file_to_ingest->largest_internal_key.user_key(), lvl)) {
|
|
877
|
+
// We must use L0 or any level higher than `lvl` to be able to overwrite
|
|
878
|
+
// the compaction output keys that we overlap with in this level, We also
|
|
879
|
+
// need to assign this file a seqno to overwrite the compaction output
|
|
880
|
+
// keys in level `lvl`
|
|
881
|
+
overlap_with_db = true;
|
|
882
|
+
break;
|
|
883
|
+
} else if (vstorage->NumLevelFiles(lvl) > 0) {
|
|
803
884
|
bool overlap_with_level = false;
|
|
804
885
|
status = sv->current->OverlapWithLevelIterator(
|
|
805
886
|
ro, env_options_, file_to_ingest->smallest_internal_key.user_key(),
|
|
@@ -856,6 +937,7 @@ Status ExternalSstFileIngestionJob::AssignLevelAndSeqnoForIngestedFile(
|
|
|
856
937
|
target_level < cfd_->NumberLevels() - 1) {
|
|
857
938
|
status = Status::TryAgain(
|
|
858
939
|
"Files cannot be ingested to Lmax. Please make sure key range of Lmax "
|
|
940
|
+
"and ongoing compaction's output to Lmax"
|
|
859
941
|
"does not overlap with files to ingest.");
|
|
860
942
|
return status;
|
|
861
943
|
}
|
|
@@ -873,7 +955,7 @@ Status ExternalSstFileIngestionJob::AssignLevelAndSeqnoForIngestedFile(
|
|
|
873
955
|
Status ExternalSstFileIngestionJob::CheckLevelForIngestedBehindFile(
|
|
874
956
|
IngestedFileInfo* file_to_ingest) {
|
|
875
957
|
auto* vstorage = cfd_->current()->storage_info();
|
|
876
|
-
//
|
|
958
|
+
// First, check if new files fit in the bottommost level
|
|
877
959
|
int bottom_lvl = cfd_->NumberLevels() - 1;
|
|
878
960
|
if (!IngestedFileFitInLevel(file_to_ingest, bottom_lvl)) {
|
|
879
961
|
return Status::InvalidArgument(
|
|
@@ -881,7 +963,7 @@ Status ExternalSstFileIngestionJob::CheckLevelForIngestedBehindFile(
|
|
|
881
963
|
"at the bottommost level!");
|
|
882
964
|
}
|
|
883
965
|
|
|
884
|
-
//
|
|
966
|
+
// Second, check if despite allow_ingest_behind=true we still have 0 seqnums
|
|
885
967
|
// at some upper level
|
|
886
968
|
for (int lvl = 0; lvl < cfd_->NumberLevels() - 1; lvl++) {
|
|
887
969
|
for (auto file : vstorage->LevelFiles(lvl)) {
|
|
@@ -997,14 +1079,8 @@ bool ExternalSstFileIngestionJob::IngestedFileFitInLevel(
|
|
|
997
1079
|
// add it to this level
|
|
998
1080
|
return false;
|
|
999
1081
|
}
|
|
1000
|
-
if (cfd_->RangeOverlapWithCompaction(file_smallest_user_key,
|
|
1001
|
-
file_largest_user_key, level)) {
|
|
1002
|
-
// File overlap with a running compaction output that will be stored
|
|
1003
|
-
// in this level, we cannot add this file to this level
|
|
1004
|
-
return false;
|
|
1005
|
-
}
|
|
1006
1082
|
|
|
1007
|
-
// File did not overlap with level files,
|
|
1083
|
+
// File did not overlap with level files, nor compaction output
|
|
1008
1084
|
return true;
|
|
1009
1085
|
}
|
|
1010
1086
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
#include "db/column_family.h"
|
|
12
12
|
#include "db/internal_stats.h"
|
|
13
13
|
#include "db/snapshot_impl.h"
|
|
14
|
+
#include "db/version_edit.h"
|
|
14
15
|
#include "env/file_system_tracer.h"
|
|
15
16
|
#include "logging/event_logger.h"
|
|
16
17
|
#include "options/db_options.h"
|
|
@@ -78,7 +79,8 @@ class ExternalSstFileIngestionJob {
|
|
|
78
79
|
public:
|
|
79
80
|
ExternalSstFileIngestionJob(
|
|
80
81
|
VersionSet* versions, ColumnFamilyData* cfd,
|
|
81
|
-
const ImmutableDBOptions& db_options,
|
|
82
|
+
const ImmutableDBOptions& db_options,
|
|
83
|
+
const MutableDBOptions& mutable_db_options, const EnvOptions& env_options,
|
|
82
84
|
SnapshotList* db_snapshots,
|
|
83
85
|
const IngestExternalFileOptions& ingestion_options,
|
|
84
86
|
Directories* directories, EventLogger* event_logger,
|
|
@@ -88,6 +90,7 @@ class ExternalSstFileIngestionJob {
|
|
|
88
90
|
versions_(versions),
|
|
89
91
|
cfd_(cfd),
|
|
90
92
|
db_options_(db_options),
|
|
93
|
+
mutable_db_options_(mutable_db_options),
|
|
91
94
|
env_options_(env_options),
|
|
92
95
|
db_snapshots_(db_snapshots),
|
|
93
96
|
ingestion_options_(ingestion_options),
|
|
@@ -99,6 +102,17 @@ class ExternalSstFileIngestionJob {
|
|
|
99
102
|
assert(directories != nullptr);
|
|
100
103
|
}
|
|
101
104
|
|
|
105
|
+
~ExternalSstFileIngestionJob() {
|
|
106
|
+
for (const auto& c : file_ingesting_compactions_) {
|
|
107
|
+
cfd_->compaction_picker()->UnregisterCompaction(c);
|
|
108
|
+
delete c;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (const auto& f : compaction_input_metdatas_) {
|
|
112
|
+
delete f;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
102
116
|
// Prepare the job by copying external files into the DB.
|
|
103
117
|
Status Prepare(const std::vector<std::string>& external_files_paths,
|
|
104
118
|
const std::vector<std::string>& files_checksums,
|
|
@@ -120,6 +134,15 @@ class ExternalSstFileIngestionJob {
|
|
|
120
134
|
// REQUIRES: Mutex held
|
|
121
135
|
Status Run();
|
|
122
136
|
|
|
137
|
+
// Register key range involved in this ingestion job
|
|
138
|
+
// to prevent key range conflict with other ongoing compaction/file ingestion
|
|
139
|
+
// REQUIRES: Mutex held
|
|
140
|
+
void RegisterRange();
|
|
141
|
+
|
|
142
|
+
// Unregister key range registered for this ingestion job
|
|
143
|
+
// REQUIRES: Mutex held
|
|
144
|
+
void UnregisterRange();
|
|
145
|
+
|
|
123
146
|
// Update column family stats.
|
|
124
147
|
// REQUIRES: Mutex held
|
|
125
148
|
void UpdateStats();
|
|
@@ -175,11 +198,17 @@ class ExternalSstFileIngestionJob {
|
|
|
175
198
|
template <typename TWritableFile>
|
|
176
199
|
Status SyncIngestedFile(TWritableFile* file);
|
|
177
200
|
|
|
201
|
+
// Create equivalent `Compaction` objects to this file ingestion job
|
|
202
|
+
// , which will be used to check range conflict with other ongoing
|
|
203
|
+
// compactions.
|
|
204
|
+
void CreateEquivalentFileIngestingCompactions();
|
|
205
|
+
|
|
178
206
|
SystemClock* clock_;
|
|
179
207
|
FileSystemPtr fs_;
|
|
180
208
|
VersionSet* versions_;
|
|
181
209
|
ColumnFamilyData* cfd_;
|
|
182
210
|
const ImmutableDBOptions& db_options_;
|
|
211
|
+
const MutableDBOptions& mutable_db_options_;
|
|
183
212
|
const EnvOptions& env_options_;
|
|
184
213
|
SnapshotList* db_snapshots_;
|
|
185
214
|
autovector<IngestedFileInfo> files_to_ingest_;
|
|
@@ -196,6 +225,14 @@ class ExternalSstFileIngestionJob {
|
|
|
196
225
|
// file_checksum_gen_factory is set, DB will generate checksum each file.
|
|
197
226
|
bool need_generate_file_checksum_{true};
|
|
198
227
|
std::shared_ptr<IOTracer> io_tracer_;
|
|
228
|
+
|
|
229
|
+
// Below are variables used in (un)registering range for this ingestion job
|
|
230
|
+
//
|
|
231
|
+
// FileMetaData used in inputs of compactions equivalent to this ingestion
|
|
232
|
+
// job
|
|
233
|
+
std::vector<FileMetaData*> compaction_input_metdatas_;
|
|
234
|
+
// Compactions equivalent to this ingestion job
|
|
235
|
+
std::vector<Compaction*> file_ingesting_compactions_;
|
|
199
236
|
};
|
|
200
237
|
|
|
201
238
|
} // namespace ROCKSDB_NAMESPACE
|
|
@@ -973,7 +973,7 @@ TEST_F(ExternalSSTFileTest, MultiThreaded) {
|
|
|
973
973
|
|
|
974
974
|
do {
|
|
975
975
|
Options options = CurrentOptions();
|
|
976
|
-
|
|
976
|
+
options.disable_auto_compactions = true;
|
|
977
977
|
std::atomic<int> thread_num(0);
|
|
978
978
|
std::function<void()> write_file_func = [&]() {
|
|
979
979
|
int file_idx = thread_num.fetch_add(1);
|
|
@@ -1249,8 +1249,9 @@ TEST_P(ExternalSSTFileTest, PickedLevel) {
|
|
|
1249
1249
|
|
|
1250
1250
|
// This file overlaps with file 0 (L3), file 1 (L2) and the
|
|
1251
1251
|
// output of compaction going to L1
|
|
1252
|
-
ASSERT_OK(GenerateAndAddExternalFile(options, {4, 7}, -1,
|
|
1253
|
-
|
|
1252
|
+
ASSERT_OK(GenerateAndAddExternalFile(options, {4, 7}, -1,
|
|
1253
|
+
true /* allow_global_seqno */, false,
|
|
1254
|
+
true, false, false, &true_data));
|
|
1254
1255
|
EXPECT_EQ(FilesPerLevel(), "5,0,1,1");
|
|
1255
1256
|
|
|
1256
1257
|
// This file does not overlap with any file or with the running compaction
|
|
@@ -1270,106 +1271,6 @@ TEST_P(ExternalSSTFileTest, PickedLevel) {
|
|
|
1270
1271
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
|
|
1271
1272
|
}
|
|
1272
1273
|
|
|
1273
|
-
TEST_F(ExternalSSTFileTest, PickedLevelBug) {
|
|
1274
|
-
env_->skip_fsync_ = true;
|
|
1275
|
-
Options options = CurrentOptions();
|
|
1276
|
-
options.disable_auto_compactions = false;
|
|
1277
|
-
options.level0_file_num_compaction_trigger = 3;
|
|
1278
|
-
options.num_levels = 2;
|
|
1279
|
-
DestroyAndReopen(options);
|
|
1280
|
-
|
|
1281
|
-
std::vector<int> file_keys;
|
|
1282
|
-
|
|
1283
|
-
// file #1 in L0
|
|
1284
|
-
file_keys = {0, 5, 7};
|
|
1285
|
-
for (int k : file_keys) {
|
|
1286
|
-
ASSERT_OK(Put(Key(k), Key(k)));
|
|
1287
|
-
}
|
|
1288
|
-
ASSERT_OK(Flush());
|
|
1289
|
-
|
|
1290
|
-
// file #2 in L0
|
|
1291
|
-
file_keys = {4, 6, 8, 9};
|
|
1292
|
-
for (int k : file_keys) {
|
|
1293
|
-
ASSERT_OK(Put(Key(k), Key(k)));
|
|
1294
|
-
}
|
|
1295
|
-
ASSERT_OK(Flush());
|
|
1296
|
-
|
|
1297
|
-
// We have 2 overlapping files in L0
|
|
1298
|
-
EXPECT_EQ(FilesPerLevel(), "2");
|
|
1299
|
-
|
|
1300
|
-
ASSERT_OK(dbfull()->TEST_WaitForCompact());
|
|
1301
|
-
|
|
1302
|
-
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
|
|
1303
|
-
{{"DBImpl::IngestExternalFile:AfterIncIngestFileCounter",
|
|
1304
|
-
"ExternalSSTFileTest::PickedLevelBug:0"},
|
|
1305
|
-
{"ExternalSSTFileTest::PickedLevelBug:1", "DBImpl::AddFile:MutexUnlock"},
|
|
1306
|
-
{"ExternalSSTFileTest::PickedLevelBug:2",
|
|
1307
|
-
"DBImpl::RunManualCompaction:0"},
|
|
1308
|
-
{"ExternalSSTFileTest::PickedLevelBug:3",
|
|
1309
|
-
"DBImpl::RunManualCompaction:1"}});
|
|
1310
|
-
|
|
1311
|
-
std::atomic<bool> bg_compact_started(false);
|
|
1312
|
-
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
|
|
1313
|
-
"DBImpl::BackgroundCompaction:Start",
|
|
1314
|
-
[&](void* /*arg*/) { bg_compact_started.store(true); });
|
|
1315
|
-
|
|
1316
|
-
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
|
|
1317
|
-
|
|
1318
|
-
Status bg_compact_status;
|
|
1319
|
-
Status bg_addfile_status;
|
|
1320
|
-
|
|
1321
|
-
{
|
|
1322
|
-
// While writing the MANIFEST start a thread that will ask for compaction
|
|
1323
|
-
ThreadGuard bg_compact(port::Thread([&]() {
|
|
1324
|
-
bg_compact_status =
|
|
1325
|
-
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr);
|
|
1326
|
-
}));
|
|
1327
|
-
TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelBug:2");
|
|
1328
|
-
|
|
1329
|
-
// Start a thread that will ingest a new file
|
|
1330
|
-
ThreadGuard bg_addfile(port::Thread([&]() {
|
|
1331
|
-
file_keys = {1, 2, 3};
|
|
1332
|
-
bg_addfile_status = GenerateAndAddExternalFile(options, file_keys, 1);
|
|
1333
|
-
}));
|
|
1334
|
-
|
|
1335
|
-
// Wait for AddFile to start picking levels and writing MANIFEST
|
|
1336
|
-
TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelBug:0");
|
|
1337
|
-
|
|
1338
|
-
TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelBug:3");
|
|
1339
|
-
|
|
1340
|
-
// We need to verify that no compactions can run while AddFile is
|
|
1341
|
-
// ingesting the files into the levels it find suitable. So we will
|
|
1342
|
-
// wait for 2 seconds to give a chance for compactions to run during
|
|
1343
|
-
// this period, and then make sure that no compactions where able to run
|
|
1344
|
-
env_->SleepForMicroseconds(1000000 * 2);
|
|
1345
|
-
bool bg_compact_started_tmp = bg_compact_started.load();
|
|
1346
|
-
|
|
1347
|
-
// Hold AddFile from finishing writing the MANIFEST
|
|
1348
|
-
TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelBug:1");
|
|
1349
|
-
|
|
1350
|
-
// check the status at the end, so even if the ASSERT fails the threads
|
|
1351
|
-
// could be joined and return.
|
|
1352
|
-
ASSERT_FALSE(bg_compact_started_tmp);
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
ASSERT_OK(bg_addfile_status);
|
|
1356
|
-
ASSERT_OK(bg_compact_status);
|
|
1357
|
-
|
|
1358
|
-
ASSERT_OK(dbfull()->TEST_WaitForCompact());
|
|
1359
|
-
|
|
1360
|
-
int total_keys = 0;
|
|
1361
|
-
Iterator* iter = db_->NewIterator(ReadOptions());
|
|
1362
|
-
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
|
1363
|
-
ASSERT_OK(iter->status());
|
|
1364
|
-
total_keys++;
|
|
1365
|
-
}
|
|
1366
|
-
ASSERT_EQ(total_keys, 10);
|
|
1367
|
-
|
|
1368
|
-
delete iter;
|
|
1369
|
-
|
|
1370
|
-
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
1274
|
TEST_F(ExternalSSTFileTest, IngestNonExistingFile) {
|
|
1374
1275
|
Options options = CurrentOptions();
|
|
1375
1276
|
DestroyAndReopen(options);
|
|
@@ -1420,7 +1321,8 @@ TEST_F(ExternalSSTFileTest, CompactDuringAddFileRandom) {
|
|
|
1420
1321
|
int range_id = 0;
|
|
1421
1322
|
std::vector<int> file_keys;
|
|
1422
1323
|
std::function<void()> bg_addfile = [&]() {
|
|
1423
|
-
ASSERT_OK(GenerateAndAddExternalFile(options, file_keys, range_id
|
|
1324
|
+
ASSERT_OK(GenerateAndAddExternalFile(options, file_keys, range_id,
|
|
1325
|
+
true /* allow_global_seqno */));
|
|
1424
1326
|
};
|
|
1425
1327
|
|
|
1426
1328
|
const int num_of_ranges = 1000;
|
|
@@ -1503,8 +1405,9 @@ TEST_F(ExternalSSTFileTest, PickedLevelDynamic) {
|
|
|
1503
1405
|
|
|
1504
1406
|
// This file overlaps with the output of the compaction (going to L3)
|
|
1505
1407
|
// so the file will be added to L0 since L3 is the base level
|
|
1506
|
-
ASSERT_OK(GenerateAndAddExternalFile(options, {31, 32, 33, 34}, -1,
|
|
1507
|
-
|
|
1408
|
+
ASSERT_OK(GenerateAndAddExternalFile(options, {31, 32, 33, 34}, -1,
|
|
1409
|
+
true /* allow_global_seqno */, false,
|
|
1410
|
+
true, false, false, &true_data));
|
|
1508
1411
|
EXPECT_EQ(FilesPerLevel(), "5");
|
|
1509
1412
|
|
|
1510
1413
|
// This file does not overlap with the current running compactiong
|
|
@@ -1642,14 +1545,15 @@ TEST_F(ExternalSSTFileTest, AddFileTrivialMoveBug) {
|
|
|
1642
1545
|
|
|
1643
1546
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
|
|
1644
1547
|
"CompactionJob::Run():Start", [&](void* /*arg*/) {
|
|
1645
|
-
//
|
|
1646
|
-
// to L2
|
|
1647
|
-
// and break LSM consistency
|
|
1548
|
+
// Fit in L3 but will overlap with the compaction output so will be
|
|
1549
|
+
// added to L2. Prior to the fix, a compaction will then trivially move
|
|
1550
|
+
// this file to L3 and break LSM consistency
|
|
1648
1551
|
static std::atomic<bool> called = {false};
|
|
1649
1552
|
if (!called) {
|
|
1650
1553
|
called = true;
|
|
1651
1554
|
ASSERT_OK(dbfull()->SetOptions({{"max_bytes_for_level_base", "1"}}));
|
|
1652
|
-
ASSERT_OK(GenerateAndAddExternalFile(options, {15, 16}, 7
|
|
1555
|
+
ASSERT_OK(GenerateAndAddExternalFile(options, {15, 16}, 7,
|
|
1556
|
+
true /* allow_global_seqno */));
|
|
1653
1557
|
}
|
|
1654
1558
|
});
|
|
1655
1559
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
|
|
@@ -941,7 +941,7 @@ Status FlushJob::WriteLevel0Table() {
|
|
|
941
941
|
cfd_->internal_stats(), &io_s, io_tracer_,
|
|
942
942
|
BlobFileCreationReason::kFlush, seqno_to_time_mapping_, event_logger_,
|
|
943
943
|
job_context_->job_id, io_priority, &table_properties_, write_hint,
|
|
944
|
-
full_history_ts_low, blob_callback_, &num_input_entries,
|
|
944
|
+
full_history_ts_low, blob_callback_, base_, &num_input_entries,
|
|
945
945
|
&memtable_payload_bytes, &memtable_garbage_bytes);
|
|
946
946
|
// TODO: Cleanup io_status in BuildTable and table builders
|
|
947
947
|
assert(!s.ok() || io_s.ok());
|
|
@@ -1003,8 +1003,7 @@ Status FlushJob::WriteLevel0Table() {
|
|
|
1003
1003
|
meta_.oldest_blob_file_number, meta_.oldest_ancester_time,
|
|
1004
1004
|
meta_.file_creation_time, meta_.epoch_number,
|
|
1005
1005
|
meta_.file_checksum, meta_.file_checksum_func_name,
|
|
1006
|
-
meta_.unique_id);
|
|
1007
|
-
|
|
1006
|
+
meta_.unique_id, meta_.compensated_range_deletion_size);
|
|
1008
1007
|
edit_->SetBlobFileAdditions(std::move(blob_file_additions));
|
|
1009
1008
|
}
|
|
1010
1009
|
#ifndef ROCKSDB_LITE
|
|
@@ -143,7 +143,7 @@ Status ImportColumnFamilyJob::Run() {
|
|
|
143
143
|
file_metadata.smallest_seqno, file_metadata.largest_seqno, false,
|
|
144
144
|
file_metadata.temperature, kInvalidBlobFileNumber, oldest_ancester_time,
|
|
145
145
|
current_time, file_metadata.epoch_number, kUnknownFileChecksum,
|
|
146
|
-
kUnknownFileChecksumFuncName, f.unique_id);
|
|
146
|
+
kUnknownFileChecksumFuncName, f.unique_id, 0);
|
|
147
147
|
s = dummy_version_builder.Apply(&dummy_version_edit);
|
|
148
148
|
}
|
|
149
149
|
if (s.ok()) {
|
|
@@ -665,7 +665,8 @@ class Repairer {
|
|
|
665
665
|
table->meta.temperature, table->meta.oldest_blob_file_number,
|
|
666
666
|
table->meta.oldest_ancester_time, table->meta.file_creation_time,
|
|
667
667
|
table->meta.epoch_number, table->meta.file_checksum,
|
|
668
|
-
table->meta.file_checksum_func_name, table->meta.unique_id
|
|
668
|
+
table->meta.file_checksum_func_name, table->meta.unique_id,
|
|
669
|
+
table->meta.compensated_range_deletion_size);
|
|
669
670
|
}
|
|
670
671
|
s = dummy_version_builder.Apply(&dummy_edit);
|
|
671
672
|
if (s.ok()) {
|