@nxtedition/rocksdb 8.0.3 → 8.0.5
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 +7 -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 +39 -19
- 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 +289 -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 +118 -26
- 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/range_tombstone_fragmenter_test.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_env_wrapper.h +8 -6
- 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 +11 -4
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +12 -13
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +13 -1
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +14 -1
- 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/table/block_based/block_based_table_reader_impl.h +6 -2
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +245 -74
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +195 -4
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +39 -0
- package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.h +9 -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
package/BUILDING.md
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
- Copy `libfolly.a` to `/usr/lib/x86_64-linux-gnu`.
|
|
11
11
|
- Copy headers to `/usr/lib/x86_64-linux-gnu/include`.
|
|
12
12
|
- Copy boost headers from folly scratchpad to `/usr/lib/x86_64-linux-gnu/include`.
|
|
13
|
-
- `
|
|
13
|
+
- `JONS=16 npx prebuildify -t 18.11.0 --napi --strip --arch x64`
|
|
14
14
|
|
|
15
15
|
# OSX
|
|
16
16
|
|
|
17
17
|
- `brew install zstd`
|
|
18
|
-
- `
|
|
18
|
+
- `JONS=16 npx prebuildify -t 18.11.0 --napi --strip --arch arm64`
|
package/binding.cc
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
#include <thread>
|
|
27
27
|
#include <vector>
|
|
28
28
|
|
|
29
|
+
#include "max_rev_operator.h"
|
|
29
30
|
#include "util.h"
|
|
30
31
|
|
|
31
32
|
class NullLogger : public rocksdb::Logger {
|
|
@@ -556,8 +557,12 @@ napi_status InitOptions(napi_env env, T& columnOptions, const U& options) {
|
|
|
556
557
|
std::optional<std::string> mergeOperatorOpt;
|
|
557
558
|
NAPI_STATUS_RETURN(GetProperty(env, options, "mergeOperator", mergeOperatorOpt));
|
|
558
559
|
if (mergeOperatorOpt) {
|
|
559
|
-
|
|
560
|
-
|
|
560
|
+
if (*mergeOperatorOpt == "maxRev") {
|
|
561
|
+
columnOptions.merge_operator = std::make_shared<MaxRevOperator>();
|
|
562
|
+
} else {
|
|
563
|
+
ROCKS_STATUS_RETURN_NAPI(
|
|
564
|
+
rocksdb::MergeOperator::CreateFromString(configOptions, *mergeOperatorOpt, &columnOptions.merge_operator));
|
|
565
|
+
}
|
|
561
566
|
}
|
|
562
567
|
|
|
563
568
|
std::optional<std::string> compactionPriority;
|
|
@@ -980,6 +980,12 @@ if ( ROCKSDB_PLUGINS )
|
|
|
980
980
|
plugin/${plugin}/${src}
|
|
981
981
|
PROPERTIES COMPILE_FLAGS "${${plugin}_COMPILE_FLAGS}")
|
|
982
982
|
endforeach()
|
|
983
|
+
foreach (test ${${plugin}_TESTS})
|
|
984
|
+
list(APPEND PLUGIN_TESTS plugin/${plugin}/${test})
|
|
985
|
+
set_source_files_properties(
|
|
986
|
+
plugin/${plugin}/${test}
|
|
987
|
+
PROPERTIES COMPILE_FLAGS "${${plugin}_COMPILE_FLAGS}")
|
|
988
|
+
endforeach()
|
|
983
989
|
foreach (path ${${plugin}_INCLUDE_PATHS})
|
|
984
990
|
include_directories(${path})
|
|
985
991
|
endforeach()
|
|
@@ -1471,6 +1477,7 @@ if(WITH_TESTS)
|
|
|
1471
1477
|
utilities/ttl/ttl_test.cc
|
|
1472
1478
|
utilities/util_merge_operators_test.cc
|
|
1473
1479
|
utilities/write_batch_with_index/write_batch_with_index_test.cc
|
|
1480
|
+
${PLUGIN_TESTS}
|
|
1474
1481
|
)
|
|
1475
1482
|
endif()
|
|
1476
1483
|
|
|
@@ -266,6 +266,7 @@ ROCKSDB_PLUGIN_EXTERNS = $(foreach p, $(ROCKSDB_PLUGIN_W_FUNCS), int $($(p)_FUNC
|
|
|
266
266
|
ROCKSDB_PLUGIN_BUILTINS = $(foreach p, $(ROCKSDB_PLUGIN_W_FUNCS), {\"$(p)\"\, $($(p)_FUNC)}\,)
|
|
267
267
|
ROCKSDB_PLUGIN_LDFLAGS = $(foreach plugin, $(ROCKSDB_PLUGINS), $($(plugin)_LDFLAGS))
|
|
268
268
|
ROCKSDB_PLUGIN_PKGCONFIG_REQUIRES = $(foreach plugin, $(ROCKSDB_PLUGINS), $($(plugin)_PKGCONFIG_REQUIRES))
|
|
269
|
+
ROCKSDB_PLUGIN_TESTS = $(foreach p, $(ROCKSDB_PLUGINS), $(foreach test, $($(p)_TESTS), plugin/$(p)/$(test)))
|
|
269
270
|
|
|
270
271
|
CXXFLAGS += $(foreach plugin, $(ROCKSDB_PLUGINS), $($(plugin)_CXXFLAGS))
|
|
271
272
|
PLATFORM_LDFLAGS += $(ROCKSDB_PLUGIN_LDFLAGS)
|
|
@@ -647,10 +648,12 @@ STRESS_OBJECTS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(STRESS_LIB_SOURCES))
|
|
|
647
648
|
ALL_SOURCES = $(filter-out util/build_version.cc, $(LIB_SOURCES)) $(TEST_LIB_SOURCES) $(MOCK_LIB_SOURCES) $(GTEST_DIR)/gtest/gtest-all.cc
|
|
648
649
|
ALL_SOURCES += $(TOOL_LIB_SOURCES) $(BENCH_LIB_SOURCES) $(CACHE_BENCH_LIB_SOURCES) $(ANALYZER_LIB_SOURCES) $(STRESS_LIB_SOURCES)
|
|
649
650
|
ALL_SOURCES += $(TEST_MAIN_SOURCES) $(TOOL_MAIN_SOURCES) $(BENCH_MAIN_SOURCES)
|
|
650
|
-
ALL_SOURCES += $(ROCKSDB_PLUGIN_SOURCES)
|
|
651
|
+
ALL_SOURCES += $(ROCKSDB_PLUGIN_SOURCES) $(ROCKSDB_PLUGIN_TESTS)
|
|
651
652
|
|
|
653
|
+
PLUGIN_TESTS = $(patsubst %.cc, %, $(notdir $(ROCKSDB_PLUGIN_TESTS)))
|
|
652
654
|
TESTS = $(patsubst %.cc, %, $(notdir $(TEST_MAIN_SOURCES)))
|
|
653
655
|
TESTS += $(patsubst %.c, %, $(notdir $(TEST_MAIN_SOURCES_C)))
|
|
656
|
+
TESTS += $(PLUGIN_TESTS)
|
|
654
657
|
|
|
655
658
|
# `make check-headers` to very that each header file includes its own
|
|
656
659
|
# dependencies
|
|
@@ -702,6 +705,7 @@ NON_PARALLEL_TEST = \
|
|
|
702
705
|
env_test \
|
|
703
706
|
deletefile_test \
|
|
704
707
|
db_bloom_filter_test \
|
|
708
|
+
$(PLUGIN_TESTS) \
|
|
705
709
|
|
|
706
710
|
PARALLEL_TEST = $(filter-out $(NON_PARALLEL_TEST), $(TESTS))
|
|
707
711
|
|
|
@@ -1355,6 +1359,14 @@ db_sanity_test: $(OBJ_DIR)/tools/db_sanity_test.o $(LIBRARY)
|
|
|
1355
1359
|
db_repl_stress: $(OBJ_DIR)/tools/db_repl_stress.o $(LIBRARY)
|
|
1356
1360
|
$(AM_LINK)
|
|
1357
1361
|
|
|
1362
|
+
define MakeTestRule
|
|
1363
|
+
$(notdir $(1:%.cc=%)): $(1:%.cc=$$(OBJ_DIR)/%.o) $$(TEST_LIBRARY) $$(LIBRARY)
|
|
1364
|
+
$$(AM_LINK)
|
|
1365
|
+
endef
|
|
1366
|
+
|
|
1367
|
+
# For each PLUGIN test, create a rule to generate the test executable
|
|
1368
|
+
$(foreach test, $(ROCKSDB_PLUGIN_TESTS), $(eval $(call MakeTestRule, $(test))))
|
|
1369
|
+
|
|
1358
1370
|
arena_test: $(OBJ_DIR)/memory/arena_test.o $(TEST_LIBRARY) $(LIBRARY)
|
|
1359
1371
|
$(AM_LINK)
|
|
1360
1372
|
|
|
@@ -71,8 +71,9 @@ Status BuildTable(
|
|
|
71
71
|
int job_id, const Env::IOPriority io_priority,
|
|
72
72
|
TableProperties* table_properties, Env::WriteLifeTimeHint write_hint,
|
|
73
73
|
const std::string* full_history_ts_low,
|
|
74
|
-
BlobFileCompletionCallback* blob_callback,
|
|
75
|
-
uint64_t*
|
|
74
|
+
BlobFileCompletionCallback* blob_callback, Version* version,
|
|
75
|
+
uint64_t* num_input_entries, uint64_t* memtable_payload_bytes,
|
|
76
|
+
uint64_t* memtable_garbage_bytes) {
|
|
76
77
|
assert((tboptions.column_family_id ==
|
|
77
78
|
TablePropertiesCollectorFactory::Context::kUnknownColumnFamily) ==
|
|
78
79
|
tboptions.column_family_name.empty());
|
|
@@ -246,9 +247,17 @@ Status BuildTable(
|
|
|
246
247
|
auto tombstone = range_del_it->Tombstone();
|
|
247
248
|
auto kv = tombstone.Serialize();
|
|
248
249
|
builder->Add(kv.first.Encode(), kv.second);
|
|
249
|
-
|
|
250
|
-
|
|
250
|
+
InternalKey tombstone_end = tombstone.SerializeEndKey();
|
|
251
|
+
meta->UpdateBoundariesForRange(kv.first, tombstone_end, tombstone.seq_,
|
|
251
252
|
tboptions.internal_comparator);
|
|
253
|
+
if (version) {
|
|
254
|
+
SizeApproximationOptions approx_opts;
|
|
255
|
+
approx_opts.files_size_error_margin = 0.1;
|
|
256
|
+
meta->compensated_range_deletion_size += versions->ApproximateSize(
|
|
257
|
+
approx_opts, version, kv.first.Encode(), tombstone_end.Encode(),
|
|
258
|
+
0 /* start_level */, -1 /* end_level */,
|
|
259
|
+
TableReaderCaller::kFlush);
|
|
260
|
+
}
|
|
252
261
|
}
|
|
253
262
|
}
|
|
254
263
|
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#include "db/range_tombstone_fragmenter.h"
|
|
14
14
|
#include "db/seqno_to_time_mapping.h"
|
|
15
15
|
#include "db/table_properties_collector.h"
|
|
16
|
+
#include "db/version_set.h"
|
|
16
17
|
#include "logging/event_logger.h"
|
|
17
18
|
#include "options/cf_options.h"
|
|
18
19
|
#include "rocksdb/comparator.h"
|
|
@@ -70,7 +71,7 @@ extern Status BuildTable(
|
|
|
70
71
|
Env::WriteLifeTimeHint write_hint = Env::WLTH_NOT_SET,
|
|
71
72
|
const std::string* full_history_ts_low = nullptr,
|
|
72
73
|
BlobFileCompletionCallback* blob_callback = nullptr,
|
|
73
|
-
uint64_t* num_input_entries = nullptr,
|
|
74
|
+
Version* version = nullptr, uint64_t* num_input_entries = nullptr,
|
|
74
75
|
uint64_t* memtable_payload_bytes = nullptr,
|
|
75
76
|
uint64_t* memtable_garbage_bytes = nullptr);
|
|
76
77
|
|
|
@@ -2588,6 +2588,12 @@ void rocksdb_block_based_options_set_partition_filters(
|
|
|
2588
2588
|
options->rep.partition_filters = partition_filters;
|
|
2589
2589
|
}
|
|
2590
2590
|
|
|
2591
|
+
void rocksdb_block_based_options_set_optimize_filters_for_memory(
|
|
2592
|
+
rocksdb_block_based_table_options_t* options,
|
|
2593
|
+
unsigned char optimize_filters_for_memory) {
|
|
2594
|
+
options->rep.optimize_filters_for_memory = optimize_filters_for_memory;
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2591
2597
|
void rocksdb_block_based_options_set_use_delta_encoding(
|
|
2592
2598
|
rocksdb_block_based_table_options_t* options,
|
|
2593
2599
|
unsigned char use_delta_encoding) {
|
|
@@ -235,12 +235,19 @@ Compaction::Compaction(
|
|
|
235
235
|
inputs_(PopulateWithAtomicBoundaries(vstorage, std::move(_inputs))),
|
|
236
236
|
grandparents_(std::move(_grandparents)),
|
|
237
237
|
score_(_score),
|
|
238
|
-
bottommost_level_(
|
|
238
|
+
bottommost_level_(
|
|
239
|
+
// For simplicity, we don't support the concept of "bottommost level"
|
|
240
|
+
// with
|
|
241
|
+
// `CompactionReason::kExternalSstIngestion` and
|
|
242
|
+
// `CompactionReason::kRefitLevel`
|
|
243
|
+
(_compaction_reason == CompactionReason::kExternalSstIngestion ||
|
|
244
|
+
_compaction_reason == CompactionReason::kRefitLevel)
|
|
245
|
+
? false
|
|
246
|
+
: IsBottommostLevel(output_level_, vstorage, inputs_)),
|
|
239
247
|
is_full_compaction_(IsFullCompaction(vstorage, inputs_)),
|
|
240
248
|
is_manual_compaction_(_manual_compaction),
|
|
241
249
|
trim_ts_(_trim_ts),
|
|
242
250
|
is_trivial_move_(false),
|
|
243
|
-
|
|
244
251
|
compaction_reason_(_compaction_reason),
|
|
245
252
|
notify_on_compaction_completion_(false),
|
|
246
253
|
enable_blob_garbage_collection_(
|
|
@@ -255,8 +262,15 @@ Compaction::Compaction(
|
|
|
255
262
|
_blob_garbage_collection_age_cutoff > 1
|
|
256
263
|
? mutable_cf_options()->blob_garbage_collection_age_cutoff
|
|
257
264
|
: _blob_garbage_collection_age_cutoff),
|
|
258
|
-
penultimate_level_(
|
|
259
|
-
|
|
265
|
+
penultimate_level_(
|
|
266
|
+
// For simplicity, we don't support the concept of "penultimate level"
|
|
267
|
+
// with `CompactionReason::kExternalSstIngestion` and
|
|
268
|
+
// `CompactionReason::kRefitLevel`
|
|
269
|
+
_compaction_reason == CompactionReason::kExternalSstIngestion ||
|
|
270
|
+
_compaction_reason == CompactionReason::kRefitLevel
|
|
271
|
+
? Compaction::kInvalidLevel
|
|
272
|
+
: EvaluatePenultimateLevel(vstorage, immutable_options_,
|
|
273
|
+
start_level_, output_level_)) {
|
|
260
274
|
MarkFilesBeingCompacted(true);
|
|
261
275
|
if (is_manual_compaction_) {
|
|
262
276
|
compaction_reason_ = CompactionReason::kManualCompaction;
|
|
@@ -99,6 +99,8 @@ const char* GetCompactionReasonString(CompactionReason compaction_reason) {
|
|
|
99
99
|
return "ForcedBlobGC";
|
|
100
100
|
case CompactionReason::kRoundRobinTtl:
|
|
101
101
|
return "RoundRobinTtl";
|
|
102
|
+
case CompactionReason::kRefitLevel:
|
|
103
|
+
return "RefitLevel";
|
|
102
104
|
case CompactionReason::kNumOfReasons:
|
|
103
105
|
// fall through
|
|
104
106
|
default:
|
|
@@ -386,7 +386,8 @@ class CompactionJobTestBase : public testing::Test {
|
|
|
386
386
|
oldest_blob_file_number, kUnknownOldestAncesterTime,
|
|
387
387
|
kUnknownFileCreationTime,
|
|
388
388
|
versions_->GetColumnFamilySet()->GetDefault()->NewEpochNumber(),
|
|
389
|
-
kUnknownFileChecksum, kUnknownFileChecksumFuncName, kNullUniqueId64x2
|
|
389
|
+
kUnknownFileChecksum, kUnknownFileChecksumFuncName, kNullUniqueId64x2,
|
|
390
|
+
0);
|
|
390
391
|
|
|
391
392
|
mutex_.Lock();
|
|
392
393
|
EXPECT_OK(
|
|
@@ -525,30 +525,26 @@ Status CompactionOutputs::AddRangeDels(
|
|
|
525
525
|
ucmp->CompareWithoutTimestamp(*lower_bound, kv.second) < 0);
|
|
526
526
|
// Range tombstone is not supported by output validator yet.
|
|
527
527
|
builder_->Add(kv.first.Encode(), kv.second);
|
|
528
|
-
InternalKey
|
|
528
|
+
InternalKey tombstone_start = std::move(kv.first);
|
|
529
|
+
InternalKey smallest_candidate{tombstone_start};
|
|
529
530
|
if (lower_bound != nullptr &&
|
|
530
531
|
ucmp->CompareWithoutTimestamp(smallest_candidate.user_key(),
|
|
531
532
|
*lower_bound) <= 0) {
|
|
532
533
|
// Pretend the smallest key has the same user key as lower_bound
|
|
533
534
|
// (the max key in the previous table or subcompaction) in order for
|
|
534
535
|
// files to appear key-space partitioned.
|
|
535
|
-
//
|
|
536
|
-
// When lower_bound is chosen by a subcompaction, we know that
|
|
537
|
-
// subcompactions over smaller keys cannot contain any keys at
|
|
538
|
-
// lower_bound. We also know that smaller subcompactions exist,
|
|
539
|
-
// because otherwise the subcompaction woud be unbounded on the left.
|
|
540
|
-
// As a result, we know that no other files on the output level will
|
|
541
|
-
// contain actual keys at lower_bound (an output file may have a
|
|
542
|
-
// largest key of lower_bound@kMaxSequenceNumber, but this only
|
|
543
|
-
// indicates a large range tombstone was truncated). Therefore, it is
|
|
544
|
-
// safe to use the tombstone's sequence number, to ensure that keys at
|
|
545
|
-
// lower_bound at lower levels are covered by truncated tombstones.
|
|
546
|
-
//
|
|
547
|
-
// If lower_bound was chosen by the smallest data key in the file,
|
|
548
|
-
// choose lowest seqnum so this file's smallest internal key comes
|
|
549
|
-
// after the previous file's largest. The fake seqnum is OK because
|
|
550
|
-
// the read path's file-picking code only considers user key.
|
|
551
536
|
if (lower_bound_from_sub_compact) {
|
|
537
|
+
// When lower_bound is chosen by a subcompaction
|
|
538
|
+
// (lower_bound_from_sub_compact), we know that subcompactions over
|
|
539
|
+
// smaller keys cannot contain any keys at lower_bound. We also know
|
|
540
|
+
// that smaller subcompactions exist, because otherwise the
|
|
541
|
+
// subcompaction woud be unbounded on the left. As a result, we know
|
|
542
|
+
// that no other files on the output level will contain actual keys at
|
|
543
|
+
// lower_bound (an output file may have a largest key of
|
|
544
|
+
// lower_bound@kMaxSequenceNumber, but this only indicates a large range
|
|
545
|
+
// tombstone was truncated). Therefore, it is safe to use the
|
|
546
|
+
// tombstone's sequence number, to ensure that keys at lower_bound at
|
|
547
|
+
// lower levels are covered by truncated tombstones.
|
|
552
548
|
if (ts_sz) {
|
|
553
549
|
assert(tombstone.ts_.size() == ts_sz);
|
|
554
550
|
smallest_candidate = InternalKey(*lower_bound, tombstone.seq_,
|
|
@@ -558,6 +554,7 @@ Status CompactionOutputs::AddRangeDels(
|
|
|
558
554
|
InternalKey(*lower_bound, tombstone.seq_, kTypeRangeDeletion);
|
|
559
555
|
}
|
|
560
556
|
} else if (lower_bound_from_range_tombstone) {
|
|
557
|
+
// When lower_bound is chosen from a range tombtone start key:
|
|
561
558
|
// Range tombstone keys can be truncated at file boundaries of the files
|
|
562
559
|
// that contain them.
|
|
563
560
|
//
|
|
@@ -591,10 +588,15 @@ Status CompactionOutputs::AddRangeDels(
|
|
|
591
588
|
smallest_candidate = range_tombstone_lower_bound_;
|
|
592
589
|
}
|
|
593
590
|
} else {
|
|
591
|
+
// If lower_bound was chosen by the smallest data key in the file,
|
|
592
|
+
// choose lowest seqnum so this file's smallest internal key comes
|
|
593
|
+
// after the previous file's largest. The fake seqnum is OK because
|
|
594
|
+
// the read path's file-picking code only considers user key.
|
|
594
595
|
smallest_candidate = InternalKey(*lower_bound, 0, kTypeRangeDeletion);
|
|
595
596
|
}
|
|
596
597
|
}
|
|
597
|
-
InternalKey
|
|
598
|
+
InternalKey tombstone_end = tombstone.SerializeEndKey();
|
|
599
|
+
InternalKey largest_candidate{tombstone_end};
|
|
598
600
|
if (upper_bound != nullptr &&
|
|
599
601
|
ucmp->CompareWithoutTimestamp(*upper_bound,
|
|
600
602
|
largest_candidate.user_key()) <= 0) {
|
|
@@ -636,11 +638,29 @@ Status CompactionOutputs::AddRangeDels(
|
|
|
636
638
|
#endif
|
|
637
639
|
meta.UpdateBoundariesForRange(smallest_candidate, largest_candidate,
|
|
638
640
|
tombstone.seq_, icmp);
|
|
641
|
+
if (!bottommost_level) {
|
|
642
|
+
// Range tombstones are truncated at file boundaries
|
|
643
|
+
if (icmp.Compare(tombstone_start, meta.smallest) < 0) {
|
|
644
|
+
tombstone_start = meta.smallest;
|
|
645
|
+
}
|
|
646
|
+
if (icmp.Compare(tombstone_end, meta.largest) > 0) {
|
|
647
|
+
tombstone_end = meta.largest;
|
|
648
|
+
}
|
|
649
|
+
SizeApproximationOptions approx_opts;
|
|
650
|
+
approx_opts.files_size_error_margin = 0.1;
|
|
651
|
+
auto approximate_covered_size =
|
|
652
|
+
compaction_->input_version()->version_set()->ApproximateSize(
|
|
653
|
+
approx_opts, compaction_->input_version(),
|
|
654
|
+
tombstone_start.Encode(), tombstone_end.Encode(),
|
|
655
|
+
compaction_->output_level() + 1 /* start_level */,
|
|
656
|
+
-1 /* end_level */, kCompaction);
|
|
657
|
+
meta.compensated_range_deletion_size += approximate_covered_size;
|
|
658
|
+
}
|
|
639
659
|
// The smallest key in a file is used for range tombstone truncation, so
|
|
640
660
|
// it cannot have a seqnum of 0 (unless the smallest data key in a file
|
|
641
661
|
// has a seqnum of 0). Otherwise, the truncated tombstone may expose
|
|
642
662
|
// deleted keys at lower levels.
|
|
643
|
-
assert(smallest_ikey_seqnum == 0 ||
|
|
663
|
+
assert(smallest_ikey_seqnum == 0 || lower_bound_from_range_tombstone ||
|
|
644
664
|
ExtractInternalKeyFooter(meta.smallest.Encode()) !=
|
|
645
665
|
PackSequenceAndType(0, kTypeRangeDeletion));
|
|
646
666
|
}
|
|
@@ -1126,7 +1126,11 @@ void CompactionPicker::RegisterCompaction(Compaction* c) {
|
|
|
1126
1126
|
c->output_level() == 0 ||
|
|
1127
1127
|
!FilesRangeOverlapWithCompaction(*c->inputs(), c->output_level(),
|
|
1128
1128
|
c->GetPenultimateLevel()));
|
|
1129
|
-
|
|
1129
|
+
// CompactionReason::kExternalSstIngestion's start level is just a placeholder
|
|
1130
|
+
// number without actual meaning as file ingestion technically does not have
|
|
1131
|
+
// an input level like other compactions
|
|
1132
|
+
if ((c->start_level() == 0 &&
|
|
1133
|
+
c->compaction_reason() != CompactionReason::kExternalSstIngestion) ||
|
|
1130
1134
|
ioptions_.compaction_style == kCompactionStyleUniversal) {
|
|
1131
1135
|
level0_compactions_in_progress_.insert(c);
|
|
1132
1136
|
}
|
|
@@ -447,21 +447,21 @@ bool LevelCompactionBuilder::SetupOtherInputsIfNeeded() {
|
|
|
447
447
|
compaction_inputs_.push_back(output_level_inputs_);
|
|
448
448
|
}
|
|
449
449
|
|
|
450
|
+
// In some edge cases we could pick a compaction that will be compacting
|
|
451
|
+
// a key range that overlap with another running compaction, and both
|
|
452
|
+
// of them have the same output level. This could happen if
|
|
453
|
+
// (1) we are running a non-exclusive manual compaction
|
|
454
|
+
// (2) AddFile ingest a new file into the LSM tree
|
|
455
|
+
// We need to disallow this from happening.
|
|
456
|
+
if (compaction_picker_->FilesRangeOverlapWithCompaction(
|
|
457
|
+
compaction_inputs_, output_level_,
|
|
458
|
+
Compaction::EvaluatePenultimateLevel(
|
|
459
|
+
vstorage_, ioptions_, start_level_, output_level_))) {
|
|
460
|
+
// This compaction output could potentially conflict with the output
|
|
461
|
+
// of a currently running compaction, we cannot run it.
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
450
464
|
if (!is_l0_trivial_move_) {
|
|
451
|
-
// In some edge cases we could pick a compaction that will be compacting
|
|
452
|
-
// a key range that overlap with another running compaction, and both
|
|
453
|
-
// of them have the same output level. This could happen if
|
|
454
|
-
// (1) we are running a non-exclusive manual compaction
|
|
455
|
-
// (2) AddFile ingest a new file into the LSM tree
|
|
456
|
-
// We need to disallow this from happening.
|
|
457
|
-
if (compaction_picker_->FilesRangeOverlapWithCompaction(
|
|
458
|
-
compaction_inputs_, output_level_,
|
|
459
|
-
Compaction::EvaluatePenultimateLevel(
|
|
460
|
-
vstorage_, ioptions_, start_level_, output_level_))) {
|
|
461
|
-
// This compaction output could potentially conflict with the output
|
|
462
|
-
// of a currently running compaction, we cannot run it.
|
|
463
|
-
return false;
|
|
464
|
-
}
|
|
465
465
|
compaction_picker_->GetGrandparents(vstorage_, start_level_inputs_,
|
|
466
466
|
output_level_inputs_, &grandparents_);
|
|
467
467
|
}
|
|
@@ -148,7 +148,7 @@ class CompactionPickerTestBase : public testing::Test {
|
|
|
148
148
|
smallest_seq, largest_seq, marked_for_compact, temperature,
|
|
149
149
|
kInvalidBlobFileNumber, kUnknownOldestAncesterTime,
|
|
150
150
|
kUnknownFileCreationTime, epoch_number, kUnknownFileChecksum,
|
|
151
|
-
kUnknownFileChecksumFuncName, kNullUniqueId64x2);
|
|
151
|
+
kUnknownFileChecksumFuncName, kNullUniqueId64x2, 0);
|
|
152
152
|
f->compensated_file_size =
|
|
153
153
|
(compensated_file_size != 0) ? compensated_file_size : file_size;
|
|
154
154
|
f->oldest_ancester_time = oldest_ancestor_time;
|
|
@@ -2873,7 +2873,6 @@ TEST_F(CompactionPickerTest, IntraL0MaxCompactionBytesHit) {
|
|
|
2873
2873
|
ASSERT_EQ(0, compaction->output_level());
|
|
2874
2874
|
}
|
|
2875
2875
|
|
|
2876
|
-
|
|
2877
2876
|
#ifndef ROCKSDB_LITE
|
|
2878
2877
|
TEST_F(CompactionPickerTest, UniversalMarkedCompactionFullOverlap) {
|
|
2879
2878
|
const uint64_t kFileSize = 100000;
|
|
@@ -1229,7 +1229,7 @@ TEST_P(ChargeFilterConstructionTestWithParam, Basic) {
|
|
|
1229
1229
|
*
|
|
1230
1230
|
* The test is designed in a way such that the reservation for (p1 - b')
|
|
1231
1231
|
* will trigger at least another dummy entry insertion
|
|
1232
|
-
* (or
|
|
1232
|
+
* (or equivalently to saying, creating another peak).
|
|
1233
1233
|
*
|
|
1234
1234
|
* kStandard128Ribbon + FullFilter +
|
|
1235
1235
|
* detect_filter_construct_corruption
|
|
@@ -2618,8 +2618,7 @@ TEST_F(DBBloomFilterTest, OptimizeFiltersForHits) {
|
|
|
2618
2618
|
BottommostLevelCompaction::kSkip;
|
|
2619
2619
|
compact_options.change_level = true;
|
|
2620
2620
|
compact_options.target_level = 7;
|
|
2621
|
-
|
|
2622
|
-
.IsNotSupported());
|
|
2621
|
+
ASSERT_OK(db_->CompactRange(compact_options, handles_[1], nullptr, nullptr));
|
|
2623
2622
|
|
|
2624
2623
|
ASSERT_EQ(trivial_move, 1);
|
|
2625
2624
|
ASSERT_EQ(non_trivial_move, 0);
|