@nxtedition/rocksdb 12.1.4 → 12.1.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.
Files changed (132) hide show
  1. package/binding.cc +1 -1
  2. package/deps/rocksdb/rocksdb/Makefile +10 -5
  3. package/deps/rocksdb/rocksdb/TARGETS +9 -7
  4. package/deps/rocksdb/rocksdb/cache/cache.cc +15 -11
  5. package/deps/rocksdb/rocksdb/cache/cache_test.cc +26 -0
  6. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +16 -0
  7. package/deps/rocksdb/rocksdb/cache/clock_cache.h +6 -0
  8. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +38 -8
  9. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +2 -0
  10. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +4 -0
  11. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +11 -0
  12. package/deps/rocksdb/rocksdb/cache/lru_cache.h +6 -0
  13. package/deps/rocksdb/rocksdb/cache/secondary_cache_adapter.cc +2 -1
  14. package/deps/rocksdb/rocksdb/cache/tiered_secondary_cache_test.cc +56 -0
  15. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +12 -9
  16. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.cc +10 -0
  17. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.h +9 -0
  18. package/deps/rocksdb/rocksdb/db/c.cc +9 -0
  19. package/deps/rocksdb/rocksdb/db/c_test.c +12 -1
  20. package/deps/rocksdb/rocksdb/db/column_family.cc +6 -23
  21. package/deps/rocksdb/rocksdb/db/column_family.h +1 -2
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +4 -5
  23. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +4 -4
  24. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +14 -6
  25. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +19 -16
  26. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +34 -30
  27. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +2 -1
  28. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +2 -1
  29. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +1 -1
  30. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +16 -31
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +2 -1
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +7 -50
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +95 -84
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +616 -5
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_state.cc +1 -1
  36. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +1 -1
  37. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +1 -1
  38. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +8 -2
  39. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +93 -69
  40. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +353 -89
  41. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +4 -3
  42. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +116 -14
  43. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +67 -8
  44. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +42 -14
  45. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +50 -0
  46. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +1 -1
  47. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +79 -32
  48. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +36 -59
  49. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +72 -39
  50. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +14 -12
  51. package/deps/rocksdb/rocksdb/db/db_io_failure_test.cc +75 -0
  52. package/deps/rocksdb/rocksdb/db/db_iter.cc +7 -3
  53. package/deps/rocksdb/rocksdb/db/db_secondary_test.cc +1 -1
  54. package/deps/rocksdb/rocksdb/db/db_sst_test.cc +24 -0
  55. package/deps/rocksdb/rocksdb/db/db_test2.cc +36 -22
  56. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +23 -0
  57. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +2 -0
  58. package/deps/rocksdb/rocksdb/db/error_handler.cc +28 -3
  59. package/deps/rocksdb/rocksdb/db/error_handler.h +2 -1
  60. package/deps/rocksdb/rocksdb/db/event_helpers.cc +1 -0
  61. package/deps/rocksdb/rocksdb/db/experimental.cc +165 -33
  62. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +13 -5
  63. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +37 -28
  64. package/deps/rocksdb/rocksdb/db/flush_job.cc +11 -6
  65. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +7 -6
  66. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +14 -6
  67. package/deps/rocksdb/rocksdb/db/job_context.h +4 -0
  68. package/deps/rocksdb/rocksdb/db/memtable.cc +24 -14
  69. package/deps/rocksdb/rocksdb/db/memtable.h +2 -1
  70. package/deps/rocksdb/rocksdb/db/memtable_list.cc +61 -33
  71. package/deps/rocksdb/rocksdb/db/memtable_list.h +8 -0
  72. package/deps/rocksdb/rocksdb/db/repair.cc +4 -2
  73. package/deps/rocksdb/rocksdb/db/table_cache.cc +2 -0
  74. package/deps/rocksdb/rocksdb/db/version_builder.cc +14 -11
  75. package/deps/rocksdb/rocksdb/db/version_edit_handler.h +20 -4
  76. package/deps/rocksdb/rocksdb/db/version_set.cc +40 -30
  77. package/deps/rocksdb/rocksdb/db/version_set.h +13 -3
  78. package/deps/rocksdb/rocksdb/db/version_set_test.cc +8 -76
  79. package/deps/rocksdb/rocksdb/db/write_batch.cc +6 -2
  80. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +1 -1
  81. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -0
  82. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +5 -1
  83. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +2 -1
  84. package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.cc +25 -2
  85. package/deps/rocksdb/rocksdb/env/fs_remap.cc +11 -0
  86. package/deps/rocksdb/rocksdb/env/fs_remap.h +5 -0
  87. package/deps/rocksdb/rocksdb/file/sst_file_manager_impl.cc +11 -1
  88. package/deps/rocksdb/rocksdb/file/sst_file_manager_impl.h +3 -1
  89. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_cache.h +20 -1
  90. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +10 -8
  91. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +4 -0
  92. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +30 -28
  93. package/deps/rocksdb/rocksdb/include/rocksdb/comparator.h +10 -5
  94. package/deps/rocksdb/rocksdb/include/rocksdb/convenience.h +3 -1
  95. package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +287 -83
  96. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +68 -36
  97. package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +8 -0
  98. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd.h +1 -0
  99. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  100. package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +4 -4
  101. package/deps/rocksdb/rocksdb/options/customizable_test.cc +31 -0
  102. package/deps/rocksdb/rocksdb/options/db_options.cc +14 -0
  103. package/deps/rocksdb/rocksdb/options/db_options.h +2 -0
  104. package/deps/rocksdb/rocksdb/options/options_helper.cc +15 -4
  105. package/deps/rocksdb/rocksdb/options/options_helper.h +4 -0
  106. package/deps/rocksdb/rocksdb/options/options_parser.cc +5 -4
  107. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +11 -1
  108. package/deps/rocksdb/rocksdb/options/options_test.cc +38 -45
  109. package/deps/rocksdb/rocksdb/port/port.h +16 -0
  110. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +8 -1
  111. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +10 -20
  112. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +15 -9
  113. package/deps/rocksdb/rocksdb/table/format.cc +32 -4
  114. package/deps/rocksdb/rocksdb/table/format.h +12 -1
  115. package/deps/rocksdb/rocksdb/table/iterator.cc +4 -0
  116. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +214 -161
  117. package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.cc +4 -2
  118. package/deps/rocksdb/rocksdb/table/table_properties.cc +4 -0
  119. package/deps/rocksdb/rocksdb/table/table_reader.h +2 -2
  120. package/deps/rocksdb/rocksdb/table/table_test.cc +5 -4
  121. package/deps/rocksdb/rocksdb/test_util/testutil.cc +2 -0
  122. package/deps/rocksdb/rocksdb/test_util/testutil.h +2 -0
  123. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +11 -2
  124. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +213 -22
  125. package/deps/rocksdb/rocksdb/tools/ldb_cmd_impl.h +3 -0
  126. package/deps/rocksdb/rocksdb/util/async_file_reader.h +1 -1
  127. package/deps/rocksdb/rocksdb/util/compaction_job_stats_impl.cc +3 -0
  128. package/deps/rocksdb/rocksdb/util/coro_utils.h +2 -2
  129. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +3 -3
  130. package/package.json +1 -1
  131. package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
  132. package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
@@ -3,9 +3,9 @@
3
3
  // COPYING file in the root directory) and Apache 2.0 License
4
4
  // (found in the LICENSE.Apache file in the root directory).
5
5
 
6
-
7
6
  #include "db/db_test_util.h"
8
7
  #include "port/stack_trace.h"
8
+ #include "rocksdb/utilities/options_util.h"
9
9
  #include "table/unique_id_impl.h"
10
10
 
11
11
  namespace ROCKSDB_NAMESPACE {
@@ -21,8 +21,10 @@ class MyTestCompactionService : public CompactionService {
21
21
  : db_path_(std::move(db_path)),
22
22
  options_(options),
23
23
  statistics_(statistics),
24
- start_info_("na", "na", "na", 0, Env::TOTAL),
25
- wait_info_("na", "na", "na", 0, Env::TOTAL),
24
+ start_info_("na", "na", "na", 0, Env::TOTAL, CompactionReason::kUnknown,
25
+ false, false, false),
26
+ wait_info_("na", "na", "na", 0, Env::TOTAL, CompactionReason::kUnknown,
27
+ false, false, false),
26
28
  listeners_(listeners),
27
29
  table_properties_collector_factories_(
28
30
  std::move(table_properties_collector_factories)) {}
@@ -97,8 +99,12 @@ class MyTestCompactionService : public CompactionService {
97
99
  Status s =
98
100
  DB::OpenAndCompact(options, db_path_, db_path_ + "/" + scheduled_job_id,
99
101
  compaction_input, result, options_override);
100
- if (is_override_wait_result_) {
101
- *result = override_wait_result_;
102
+ {
103
+ InstrumentedMutexLock l(&mutex_);
104
+ if (is_override_wait_result_) {
105
+ *result = override_wait_result_;
106
+ }
107
+ result_ = *result;
102
108
  }
103
109
  compaction_num_.fetch_add(1);
104
110
  if (s.ok()) {
@@ -141,6 +147,10 @@ class MyTestCompactionService : public CompactionService {
141
147
 
142
148
  void SetCanceled(bool canceled) { canceled_ = canceled; }
143
149
 
150
+ void GetResult(CompactionServiceResult* deserialized) {
151
+ CompactionServiceResult::Read(result_, deserialized).PermitUncheckedError();
152
+ }
153
+
144
154
  CompactionServiceJobStatus GetFinalCompactionServiceJobStatus() {
145
155
  return final_updated_status_.load();
146
156
  }
@@ -162,6 +172,7 @@ class MyTestCompactionService : public CompactionService {
162
172
  CompactionServiceJobStatus override_wait_status_ =
163
173
  CompactionServiceJobStatus::kFailure;
164
174
  bool is_override_wait_result_ = false;
175
+ std::string result_;
165
176
  std::string override_wait_result_;
166
177
  std::vector<std::shared_ptr<EventListener>> listeners_;
167
178
  std::vector<std::shared_ptr<TablePropertiesCollectorFactory>>
@@ -331,6 +342,34 @@ TEST_F(CompactionServiceTest, BasicCompactions) {
331
342
  ReopenWithColumnFamilies({kDefaultColumnFamilyName, "cf_1", "cf_2", "cf_3"},
332
343
  options);
333
344
  ASSERT_GT(verify_passed, 0);
345
+ CompactionServiceResult result;
346
+ my_cs->GetResult(&result);
347
+ if (s.IsAborted()) {
348
+ ASSERT_NOK(result.status);
349
+ } else {
350
+ ASSERT_OK(result.status);
351
+ }
352
+ ASSERT_GE(result.stats.elapsed_micros, 1);
353
+ ASSERT_GE(result.stats.cpu_micros, 1);
354
+
355
+ ASSERT_EQ(20, result.stats.num_output_records);
356
+ ASSERT_EQ(result.output_files.size(), result.stats.num_output_files);
357
+
358
+ uint64_t total_size = 0;
359
+ for (auto output_file : result.output_files) {
360
+ std::string file_name = result.output_path + "/" + output_file.file_name;
361
+
362
+ uint64_t file_size = 0;
363
+ ASSERT_OK(options.env->GetFileSize(file_name, &file_size));
364
+ ASSERT_GT(file_size, 0);
365
+ total_size += file_size;
366
+ }
367
+ ASSERT_EQ(total_size, result.stats.total_output_bytes);
368
+
369
+ ASSERT_TRUE(result.stats.is_remote_compaction);
370
+ ASSERT_TRUE(result.stats.is_manual_compaction);
371
+ ASSERT_FALSE(result.stats.is_full_compaction);
372
+
334
373
  Close();
335
374
  }
336
375
 
@@ -369,6 +408,507 @@ TEST_F(CompactionServiceTest, ManualCompaction) {
369
408
  ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
370
409
  ASSERT_GE(my_cs->GetCompactionNum(), comp_num + 1);
371
410
  VerifyTestData();
411
+
412
+ CompactionServiceResult result;
413
+ my_cs->GetResult(&result);
414
+ ASSERT_OK(result.status);
415
+ ASSERT_TRUE(result.stats.is_manual_compaction);
416
+ ASSERT_TRUE(result.stats.is_remote_compaction);
417
+ }
418
+
419
+ TEST_F(CompactionServiceTest, PreservedOptionsLocalCompaction) {
420
+ Options options = CurrentOptions();
421
+ options.level0_file_num_compaction_trigger = 2;
422
+ options.disable_auto_compactions = true;
423
+ DestroyAndReopen(options);
424
+
425
+ Random rnd(301);
426
+ for (auto i = 0; i < 2; ++i) {
427
+ for (auto j = 0; j < 10; ++j) {
428
+ ASSERT_OK(
429
+ Put("foo" + std::to_string(i * 10 + j), rnd.RandomString(1024)));
430
+ }
431
+ ASSERT_OK(Flush());
432
+ }
433
+
434
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
435
+ "CompactionJob::ProcessKeyValueCompaction()::Processing", [&](void* arg) {
436
+ auto compaction = static_cast<Compaction*>(arg);
437
+ std::string options_file_name = OptionsFileName(
438
+ dbname_,
439
+ compaction->input_version()->version_set()->options_file_number());
440
+
441
+ // Change option twice to make sure the very first OPTIONS file gets
442
+ // purged
443
+ ASSERT_OK(dbfull()->SetOptions(
444
+ {{"level0_file_num_compaction_trigger", "4"}}));
445
+ ASSERT_EQ(4, dbfull()->GetOptions().level0_file_num_compaction_trigger);
446
+ ASSERT_OK(dbfull()->SetOptions(
447
+ {{"level0_file_num_compaction_trigger", "6"}}));
448
+ ASSERT_EQ(6, dbfull()->GetOptions().level0_file_num_compaction_trigger);
449
+ dbfull()->TEST_DeleteObsoleteFiles();
450
+
451
+ // For non-remote compactions, OPTIONS file can be deleted while
452
+ // using option at the start of the compaction
453
+ Status s = env_->FileExists(options_file_name);
454
+ ASSERT_NOK(s);
455
+ ASSERT_TRUE(s.IsNotFound());
456
+ // Should be old value
457
+ ASSERT_EQ(2, compaction->mutable_cf_options()
458
+ ->level0_file_num_compaction_trigger);
459
+ ASSERT_TRUE(dbfull()->min_options_file_numbers_.empty());
460
+ });
461
+
462
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
463
+ Status s = dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr);
464
+ ASSERT_TRUE(s.ok());
465
+ }
466
+
467
+ TEST_F(CompactionServiceTest, PreservedOptionsRemoteCompaction) {
468
+ // For non-remote compaction do not preserve options file
469
+ Options options = CurrentOptions();
470
+ options.level0_file_num_compaction_trigger = 2;
471
+ options.disable_auto_compactions = true;
472
+ ReopenWithCompactionService(&options);
473
+ GenerateTestData();
474
+
475
+ auto my_cs = GetCompactionService();
476
+
477
+ Random rnd(301);
478
+ for (auto i = 0; i < 2; ++i) {
479
+ for (auto j = 0; j < 10; ++j) {
480
+ ASSERT_OK(
481
+ Put("foo" + std::to_string(i * 10 + j), rnd.RandomString(1024)));
482
+ }
483
+ ASSERT_OK(Flush());
484
+ }
485
+
486
+ bool is_primary_called = false;
487
+ // This will be called twice. One from primary and one from remote.
488
+ // Try changing the option when called from remote. Otherwise, the new option
489
+ // will be used
490
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
491
+ "DBImpl::BackgroundCompaction:NonTrivial:BeforeRun", [&](void* /*arg*/) {
492
+ if (!is_primary_called) {
493
+ is_primary_called = true;
494
+ return;
495
+ }
496
+ // Change the option right before the compaction run
497
+ ASSERT_OK(dbfull()->SetOptions(
498
+ {{"level0_file_num_compaction_trigger", "4"}}));
499
+ ASSERT_EQ(4, dbfull()->GetOptions().level0_file_num_compaction_trigger);
500
+ dbfull()->TEST_DeleteObsoleteFiles();
501
+ });
502
+
503
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
504
+ "CompactionServiceJob::ProcessKeyValueCompactionWithCompactionService",
505
+ [&](void* arg) {
506
+ auto input = static_cast<CompactionServiceInput*>(arg);
507
+ std::string options_file_name =
508
+ OptionsFileName(dbname_, input->options_file_number);
509
+
510
+ ASSERT_OK(env_->FileExists(options_file_name));
511
+ ASSERT_FALSE(dbfull()->min_options_file_numbers_.empty());
512
+ ASSERT_EQ(dbfull()->min_options_file_numbers_.front(),
513
+ input->options_file_number);
514
+
515
+ DBOptions db_options;
516
+ ConfigOptions config_options;
517
+ std::vector<ColumnFamilyDescriptor> all_column_families;
518
+ config_options.env = env_;
519
+ ASSERT_OK(LoadOptionsFromFile(config_options, options_file_name,
520
+ &db_options, &all_column_families));
521
+ bool has_cf = false;
522
+ for (auto& cf : all_column_families) {
523
+ if (cf.name == input->cf_name) {
524
+ // Should be old value
525
+ ASSERT_EQ(2, cf.options.level0_file_num_compaction_trigger);
526
+ has_cf = true;
527
+ }
528
+ }
529
+ ASSERT_TRUE(has_cf);
530
+ });
531
+
532
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
533
+ "CompactionJob::ProcessKeyValueCompaction()::Processing", [&](void* arg) {
534
+ auto compaction = static_cast<Compaction*>(arg);
535
+ ASSERT_EQ(2, compaction->mutable_cf_options()
536
+ ->level0_file_num_compaction_trigger);
537
+ });
538
+
539
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
540
+ Status s = dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr);
541
+ ASSERT_TRUE(s.ok());
542
+
543
+ CompactionServiceResult result;
544
+ my_cs->GetResult(&result);
545
+ ASSERT_OK(result.status);
546
+ ASSERT_TRUE(result.stats.is_manual_compaction);
547
+ ASSERT_TRUE(result.stats.is_remote_compaction);
548
+ }
549
+
550
+ class EventVerifier : public EventListener {
551
+ public:
552
+ explicit EventVerifier(uint64_t expected_num_input_records,
553
+ size_t expected_num_input_files,
554
+ uint64_t expected_num_output_records,
555
+ size_t expected_num_output_files,
556
+ const std::string& expected_smallest_output_key_prefix,
557
+ const std::string& expected_largest_output_key_prefix,
558
+ bool expected_is_remote_compaction_on_begin,
559
+ bool expected_is_remote_compaction_on_complete)
560
+ : expected_num_input_records_(expected_num_input_records),
561
+ expected_num_input_files_(expected_num_input_files),
562
+ expected_num_output_records_(expected_num_output_records),
563
+ expected_num_output_files_(expected_num_output_files),
564
+ expected_smallest_output_key_prefix_(
565
+ expected_smallest_output_key_prefix),
566
+ expected_largest_output_key_prefix_(expected_largest_output_key_prefix),
567
+ expected_is_remote_compaction_on_begin_(
568
+ expected_is_remote_compaction_on_begin),
569
+ expected_is_remote_compaction_on_complete_(
570
+ expected_is_remote_compaction_on_complete) {}
571
+ void OnCompactionBegin(DB* /*db*/, const CompactionJobInfo& ci) override {
572
+ ASSERT_EQ(expected_num_input_files_, ci.input_files.size());
573
+ ASSERT_EQ(expected_num_input_files_, ci.input_file_infos.size());
574
+ ASSERT_EQ(expected_is_remote_compaction_on_begin_,
575
+ ci.stats.is_remote_compaction);
576
+ ASSERT_TRUE(ci.stats.is_manual_compaction);
577
+ ASSERT_FALSE(ci.stats.is_full_compaction);
578
+ }
579
+ void OnCompactionCompleted(DB* /*db*/, const CompactionJobInfo& ci) override {
580
+ ASSERT_GT(ci.stats.elapsed_micros, 0);
581
+ ASSERT_GT(ci.stats.cpu_micros, 0);
582
+ ASSERT_EQ(expected_num_input_records_, ci.stats.num_input_records);
583
+ ASSERT_EQ(expected_num_input_files_, ci.stats.num_input_files);
584
+ ASSERT_EQ(expected_num_output_records_, ci.stats.num_output_records);
585
+ ASSERT_EQ(expected_num_output_files_, ci.stats.num_output_files);
586
+ ASSERT_EQ(expected_smallest_output_key_prefix_,
587
+ ci.stats.smallest_output_key_prefix);
588
+ ASSERT_EQ(expected_largest_output_key_prefix_,
589
+ ci.stats.largest_output_key_prefix);
590
+ ASSERT_GT(ci.stats.total_input_bytes, 0);
591
+ ASSERT_GT(ci.stats.total_output_bytes, 0);
592
+ ASSERT_EQ(ci.stats.num_input_records,
593
+ ci.stats.num_output_records + ci.stats.num_records_replaced);
594
+ ASSERT_EQ(expected_is_remote_compaction_on_complete_,
595
+ ci.stats.is_remote_compaction);
596
+ ASSERT_TRUE(ci.stats.is_manual_compaction);
597
+ ASSERT_FALSE(ci.stats.is_full_compaction);
598
+ }
599
+
600
+ private:
601
+ uint64_t expected_num_input_records_;
602
+ size_t expected_num_input_files_;
603
+ uint64_t expected_num_output_records_;
604
+ size_t expected_num_output_files_;
605
+ std::string expected_smallest_output_key_prefix_;
606
+ std::string expected_largest_output_key_prefix_;
607
+ bool expected_is_remote_compaction_on_begin_;
608
+ bool expected_is_remote_compaction_on_complete_;
609
+ };
610
+
611
+ TEST_F(CompactionServiceTest, VerifyStats) {
612
+ Options options = CurrentOptions();
613
+ options.disable_auto_compactions = true;
614
+ auto event_verifier = std::make_shared<EventVerifier>(
615
+ 30 /* expected_num_input_records */, 3 /* expected_num_input_files */,
616
+ 20 /* expected_num_output_records */, 1 /* expected_num_output_files */,
617
+ "key00000" /* expected_smallest_output_key_prefix */,
618
+ "key00001" /* expected_largest_output_key_prefix */,
619
+ true /* expected_is_remote_compaction_on_begin */,
620
+ true /* expected_is_remote_compaction_on_complete */);
621
+ options.listeners.push_back(event_verifier);
622
+ ReopenWithCompactionService(&options);
623
+ GenerateTestData();
624
+
625
+ auto my_cs = GetCompactionService();
626
+
627
+ std::string start_str = Key(0);
628
+ std::string end_str = Key(1);
629
+ Slice start(start_str);
630
+ Slice end(end_str);
631
+ uint64_t comp_num = my_cs->GetCompactionNum();
632
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), &start, &end));
633
+ ASSERT_GE(my_cs->GetCompactionNum(), comp_num + 1);
634
+ VerifyTestData();
635
+
636
+ CompactionServiceResult result;
637
+ my_cs->GetResult(&result);
638
+ ASSERT_OK(result.status);
639
+ ASSERT_TRUE(result.stats.is_manual_compaction);
640
+ ASSERT_TRUE(result.stats.is_remote_compaction);
641
+ }
642
+
643
+ TEST_F(CompactionServiceTest, VerifyStatsLocalFallback) {
644
+ Options options = CurrentOptions();
645
+ options.disable_auto_compactions = true;
646
+ auto event_verifier = std::make_shared<EventVerifier>(
647
+ 30 /* expected_num_input_records */, 3 /* expected_num_input_files */,
648
+ 20 /* expected_num_output_records */, 1 /* expected_num_output_files */,
649
+ "key00000" /* expected_smallest_output_key_prefix */,
650
+ "key00001" /* expected_largest_output_key_prefix */,
651
+ true /* expected_is_remote_compaction_on_begin */,
652
+ false /* expected_is_remote_compaction_on_complete */);
653
+ options.listeners.push_back(event_verifier);
654
+ ReopenWithCompactionService(&options);
655
+ GenerateTestData();
656
+
657
+ auto my_cs = GetCompactionService();
658
+ my_cs->OverrideStartStatus(CompactionServiceJobStatus::kUseLocal);
659
+
660
+ std::string start_str = Key(0);
661
+ std::string end_str = Key(1);
662
+ Slice start(start_str);
663
+ Slice end(end_str);
664
+ uint64_t comp_num = my_cs->GetCompactionNum();
665
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), &start, &end));
666
+ // Remote Compaction did not happen
667
+ ASSERT_EQ(my_cs->GetCompactionNum(), comp_num);
668
+ VerifyTestData();
669
+ }
670
+
671
+ TEST_F(CompactionServiceTest, CorruptedOutput) {
672
+ Options options = CurrentOptions();
673
+ options.disable_auto_compactions = true;
674
+ ReopenWithCompactionService(&options);
675
+ GenerateTestData();
676
+
677
+ auto my_cs = GetCompactionService();
678
+
679
+ std::string start_str = Key(15);
680
+ std::string end_str = Key(45);
681
+ Slice start(start_str);
682
+ Slice end(end_str);
683
+ uint64_t comp_num = my_cs->GetCompactionNum();
684
+
685
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
686
+ "CompactionServiceCompactionJob::Run:0", [&](void* arg) {
687
+ CompactionServiceResult* compaction_result =
688
+ *(static_cast<CompactionServiceResult**>(arg));
689
+ ASSERT_TRUE(compaction_result != nullptr &&
690
+ !compaction_result->output_files.empty());
691
+ // Corrupt files here
692
+ for (const auto& output_file : compaction_result->output_files) {
693
+ std::string file_name =
694
+ compaction_result->output_path + "/" + output_file.file_name;
695
+
696
+ uint64_t file_size = 0;
697
+ Status s = options.env->GetFileSize(file_name, &file_size);
698
+ ASSERT_OK(s);
699
+ ASSERT_GT(file_size, 0);
700
+
701
+ ASSERT_OK(test::CorruptFile(env_, file_name, 0,
702
+ static_cast<int>(file_size),
703
+ true /* verifyChecksum */));
704
+ }
705
+ });
706
+ SyncPoint::GetInstance()->EnableProcessing();
707
+
708
+ // CompactRange() should fail
709
+ Status s = db_->CompactRange(CompactRangeOptions(), &start, &end);
710
+ ASSERT_NOK(s);
711
+ ASSERT_TRUE(s.IsCorruption());
712
+
713
+ ASSERT_GE(my_cs->GetCompactionNum(), comp_num + 1);
714
+
715
+ SyncPoint::GetInstance()->DisableProcessing();
716
+ SyncPoint::GetInstance()->ClearAllCallBacks();
717
+
718
+ // On the worker side, the compaction is considered success
719
+ // Verification is done on the primary side
720
+ CompactionServiceResult result;
721
+ my_cs->GetResult(&result);
722
+ ASSERT_OK(result.status);
723
+ ASSERT_TRUE(result.stats.is_manual_compaction);
724
+ ASSERT_TRUE(result.stats.is_remote_compaction);
725
+ }
726
+
727
+ TEST_F(CompactionServiceTest, CorruptedOutputParanoidFileCheck) {
728
+ for (bool paranoid_file_check_enabled : {false, true}) {
729
+ SCOPED_TRACE("paranoid_file_check_enabled=" +
730
+ std::to_string(paranoid_file_check_enabled));
731
+
732
+ Options options = CurrentOptions();
733
+ Destroy(options);
734
+ options.disable_auto_compactions = true;
735
+ options.paranoid_file_checks = paranoid_file_check_enabled;
736
+ ReopenWithCompactionService(&options);
737
+ GenerateTestData();
738
+
739
+ auto my_cs = GetCompactionService();
740
+
741
+ std::string start_str = Key(15);
742
+ std::string end_str = Key(45);
743
+ Slice start(start_str);
744
+ Slice end(end_str);
745
+ uint64_t comp_num = my_cs->GetCompactionNum();
746
+
747
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
748
+ "CompactionServiceCompactionJob::Run:0", [&](void* arg) {
749
+ CompactionServiceResult* compaction_result =
750
+ *(static_cast<CompactionServiceResult**>(arg));
751
+ ASSERT_TRUE(compaction_result != nullptr &&
752
+ !compaction_result->output_files.empty());
753
+ // Corrupt files here
754
+ for (const auto& output_file : compaction_result->output_files) {
755
+ std::string file_name =
756
+ compaction_result->output_path + "/" + output_file.file_name;
757
+
758
+ // Corrupt very small range of bytes. This corruption is so small
759
+ // that this isn't caught by default light-weight check
760
+ ASSERT_OK(test::CorruptFile(env_, file_name, 0, 1,
761
+ false /* verifyChecksum */));
762
+ }
763
+ });
764
+ SyncPoint::GetInstance()->EnableProcessing();
765
+
766
+ Status s = db_->CompactRange(CompactRangeOptions(), &start, &end);
767
+ if (paranoid_file_check_enabled) {
768
+ ASSERT_NOK(s);
769
+ ASSERT_EQ(Status::Corruption("Paranoid checksums do not match"), s);
770
+ } else {
771
+ // CompactRange() goes through if paranoid file check is not enabled
772
+ ASSERT_OK(s);
773
+ }
774
+
775
+ ASSERT_GE(my_cs->GetCompactionNum(), comp_num + 1);
776
+
777
+ SyncPoint::GetInstance()->DisableProcessing();
778
+ SyncPoint::GetInstance()->ClearAllCallBacks();
779
+
780
+ // On the worker side, the compaction is considered success
781
+ // Verification is done on the primary side
782
+ CompactionServiceResult result;
783
+ my_cs->GetResult(&result);
784
+ ASSERT_OK(result.status);
785
+ ASSERT_TRUE(result.stats.is_manual_compaction);
786
+ ASSERT_TRUE(result.stats.is_remote_compaction);
787
+ }
788
+ }
789
+
790
+ TEST_F(CompactionServiceTest, TruncatedOutput) {
791
+ Options options = CurrentOptions();
792
+ options.disable_auto_compactions = true;
793
+ ReopenWithCompactionService(&options);
794
+ GenerateTestData();
795
+
796
+ auto my_cs = GetCompactionService();
797
+
798
+ std::string start_str = Key(15);
799
+ std::string end_str = Key(45);
800
+ Slice start(start_str);
801
+ Slice end(end_str);
802
+ uint64_t comp_num = my_cs->GetCompactionNum();
803
+
804
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
805
+ "CompactionServiceCompactionJob::Run:0", [&](void* arg) {
806
+ CompactionServiceResult* compaction_result =
807
+ *(static_cast<CompactionServiceResult**>(arg));
808
+ ASSERT_TRUE(compaction_result != nullptr &&
809
+ !compaction_result->output_files.empty());
810
+ // Truncate files here
811
+ for (const auto& output_file : compaction_result->output_files) {
812
+ std::string file_name =
813
+ compaction_result->output_path + "/" + output_file.file_name;
814
+
815
+ uint64_t file_size = 0;
816
+ Status s = options.env->GetFileSize(file_name, &file_size);
817
+ ASSERT_OK(s);
818
+ ASSERT_GT(file_size, 0);
819
+
820
+ ASSERT_OK(test::TruncateFile(env_, file_name, file_size / 2));
821
+ }
822
+ });
823
+ SyncPoint::GetInstance()->EnableProcessing();
824
+
825
+ // CompactRange() should fail
826
+ Status s = db_->CompactRange(CompactRangeOptions(), &start, &end);
827
+ ASSERT_NOK(s);
828
+ ASSERT_TRUE(s.IsCorruption());
829
+
830
+ ASSERT_GE(my_cs->GetCompactionNum(), comp_num + 1);
831
+
832
+ SyncPoint::GetInstance()->DisableProcessing();
833
+ SyncPoint::GetInstance()->ClearAllCallBacks();
834
+
835
+ // On the worker side, the compaction is considered success
836
+ // Verification is done on the primary side
837
+ CompactionServiceResult result;
838
+ my_cs->GetResult(&result);
839
+ ASSERT_OK(result.status);
840
+ ASSERT_TRUE(result.stats.is_manual_compaction);
841
+ ASSERT_TRUE(result.stats.is_remote_compaction);
842
+ }
843
+
844
+ TEST_F(CompactionServiceTest, CustomFileChecksum) {
845
+ Options options = CurrentOptions();
846
+ options.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory();
847
+ ReopenWithCompactionService(&options);
848
+ GenerateTestData();
849
+
850
+ auto my_cs = GetCompactionService();
851
+
852
+ std::string start_str = Key(15);
853
+ std::string end_str = Key(45);
854
+ Slice start(start_str);
855
+ Slice end(end_str);
856
+ uint64_t comp_num = my_cs->GetCompactionNum();
857
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
858
+ "CompactionServiceCompactionJob::Run:0", [&](void* arg) {
859
+ CompactionServiceResult* compaction_result =
860
+ *(static_cast<CompactionServiceResult**>(arg));
861
+ ASSERT_TRUE(compaction_result != nullptr &&
862
+ !compaction_result->output_files.empty());
863
+ // Validate Checksum files here
864
+ for (const auto& output_file : compaction_result->output_files) {
865
+ std::string file_name =
866
+ compaction_result->output_path + "/" + output_file.file_name;
867
+
868
+ FileChecksumGenContext gen_context;
869
+ gen_context.file_name = file_name;
870
+ std::unique_ptr<FileChecksumGenerator> file_checksum_gen =
871
+ options.file_checksum_gen_factory->CreateFileChecksumGenerator(
872
+ gen_context);
873
+
874
+ std::unique_ptr<SequentialFile> file_reader;
875
+ uint64_t file_size = 0;
876
+ Status s = options.env->GetFileSize(file_name, &file_size);
877
+ ASSERT_OK(s);
878
+ ASSERT_GT(file_size, 0);
879
+
880
+ s = options.env->NewSequentialFile(file_name, &file_reader,
881
+ EnvOptions());
882
+ ASSERT_OK(s);
883
+
884
+ Slice result;
885
+ std::unique_ptr<char[]> scratch(new char[file_size]);
886
+ s = file_reader->Read(file_size, &result, scratch.get());
887
+ ASSERT_OK(s);
888
+
889
+ file_checksum_gen->Update(scratch.get(), result.size());
890
+ file_checksum_gen->Finalize();
891
+
892
+ // Verify actual checksum and the func name
893
+ ASSERT_EQ(file_checksum_gen->Name(),
894
+ output_file.file_checksum_func_name);
895
+ ASSERT_EQ(file_checksum_gen->GetChecksum(),
896
+ output_file.file_checksum);
897
+ }
898
+ });
899
+ SyncPoint::GetInstance()->EnableProcessing();
900
+
901
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), &start, &end));
902
+ ASSERT_GE(my_cs->GetCompactionNum(), comp_num + 1);
903
+
904
+ SyncPoint::GetInstance()->DisableProcessing();
905
+ SyncPoint::GetInstance()->ClearAllCallBacks();
906
+
907
+ CompactionServiceResult result;
908
+ my_cs->GetResult(&result);
909
+ ASSERT_OK(result.status);
910
+ ASSERT_TRUE(result.stats.is_manual_compaction);
911
+ ASSERT_TRUE(result.stats.is_remote_compaction);
372
912
  }
373
913
 
374
914
  TEST_F(CompactionServiceTest, CancelCompactionOnRemoteSide) {
@@ -601,11 +1141,20 @@ TEST_F(CompactionServiceTest, CompactionInfo) {
601
1141
  {file.db_path + "/" + file.name}, 2));
602
1142
  info = my_cs->GetCompactionInfoForStart();
603
1143
  ASSERT_EQ(Env::USER, info.priority);
1144
+ ASSERT_EQ(CompactionReason::kManualCompaction, info.compaction_reason);
1145
+ ASSERT_EQ(true, info.is_manual_compaction);
1146
+ ASSERT_EQ(false, info.is_full_compaction);
1147
+ ASSERT_EQ(true, info.bottommost_level);
604
1148
  info = my_cs->GetCompactionInfoForWait();
605
1149
  ASSERT_EQ(Env::USER, info.priority);
1150
+ ASSERT_EQ(CompactionReason::kManualCompaction, info.compaction_reason);
1151
+ ASSERT_EQ(true, info.is_manual_compaction);
1152
+ ASSERT_EQ(false, info.is_full_compaction);
1153
+ ASSERT_EQ(true, info.bottommost_level);
606
1154
 
607
1155
  // Test priority BOTTOM
608
1156
  env_->SetBackgroundThreads(1, Env::BOTTOM);
1157
+ // This will set bottommost_level = true but is_full_compaction = false
609
1158
  options.num_levels = 2;
610
1159
  ReopenWithCompactionService(&options);
611
1160
  my_cs =
@@ -628,9 +1177,71 @@ TEST_F(CompactionServiceTest, CompactionInfo) {
628
1177
  }
629
1178
  ASSERT_OK(dbfull()->TEST_WaitForCompact());
630
1179
  info = my_cs->GetCompactionInfoForStart();
1180
+ ASSERT_EQ(CompactionReason::kLevelL0FilesNum, info.compaction_reason);
1181
+ ASSERT_EQ(false, info.is_manual_compaction);
1182
+ ASSERT_EQ(false, info.is_full_compaction);
1183
+ ASSERT_EQ(true, info.bottommost_level);
631
1184
  ASSERT_EQ(Env::BOTTOM, info.priority);
632
1185
  info = my_cs->GetCompactionInfoForWait();
633
1186
  ASSERT_EQ(Env::BOTTOM, info.priority);
1187
+ ASSERT_EQ(CompactionReason::kLevelL0FilesNum, info.compaction_reason);
1188
+ ASSERT_EQ(false, info.is_manual_compaction);
1189
+ ASSERT_EQ(false, info.is_full_compaction);
1190
+ ASSERT_EQ(true, info.bottommost_level);
1191
+
1192
+ // Test Non-Bottommost Level
1193
+ options.num_levels = 4;
1194
+ ReopenWithCompactionService(&options);
1195
+ my_cs =
1196
+ static_cast_with_check<MyTestCompactionService>(GetCompactionService());
1197
+
1198
+ for (int i = 0; i < options.level0_file_num_compaction_trigger; i++) {
1199
+ for (int j = 0; j < 10; j++) {
1200
+ int key_id = i * 10 + j;
1201
+ ASSERT_OK(Put(Key(key_id), "value_new_new" + std::to_string(key_id)));
1202
+ }
1203
+ ASSERT_OK(Flush());
1204
+ }
1205
+
1206
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
1207
+ info = my_cs->GetCompactionInfoForStart();
1208
+ ASSERT_EQ(false, info.is_manual_compaction);
1209
+ ASSERT_EQ(false, info.is_full_compaction);
1210
+ ASSERT_EQ(false, info.bottommost_level);
1211
+ info = my_cs->GetCompactionInfoForWait();
1212
+ ASSERT_EQ(false, info.is_manual_compaction);
1213
+ ASSERT_EQ(false, info.is_full_compaction);
1214
+ ASSERT_EQ(false, info.bottommost_level);
1215
+
1216
+ // Test Full Compaction + Bottommost Level
1217
+ options.num_levels = 6;
1218
+ ReopenWithCompactionService(&options);
1219
+ my_cs =
1220
+ static_cast_with_check<MyTestCompactionService>(GetCompactionService());
1221
+
1222
+ for (int i = 0; i < 20; i++) {
1223
+ for (int j = 0; j < 10; j++) {
1224
+ int key_id = i * 10 + j;
1225
+ ASSERT_OK(Put(Key(key_id), "value_new_new" + std::to_string(key_id)));
1226
+ }
1227
+ ASSERT_OK(Flush());
1228
+ }
1229
+
1230
+ CompactRangeOptions cro;
1231
+ cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
1232
+ ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
1233
+
1234
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
1235
+ info = my_cs->GetCompactionInfoForStart();
1236
+ ASSERT_EQ(true, info.is_manual_compaction);
1237
+ ASSERT_EQ(true, info.is_full_compaction);
1238
+ ASSERT_EQ(true, info.bottommost_level);
1239
+ ASSERT_EQ(CompactionReason::kManualCompaction, info.compaction_reason);
1240
+ info = my_cs->GetCompactionInfoForWait();
1241
+ ASSERT_EQ(true, info.is_manual_compaction);
1242
+ ASSERT_EQ(true, info.is_full_compaction);
1243
+ ASSERT_EQ(true, info.bottommost_level);
1244
+ ASSERT_EQ(CompactionReason::kManualCompaction, info.compaction_reason);
634
1245
  }
635
1246
 
636
1247
  TEST_F(CompactionServiceTest, FallbackLocalAuto) {
@@ -39,7 +39,7 @@ void CompactionState::AggregateCompactionStats(
39
39
  InternalStats::CompactionStatsFull& compaction_stats,
40
40
  CompactionJobStats& compaction_job_stats) {
41
41
  for (const auto& sc : sub_compact_states) {
42
- sc.AggregateCompactionStats(compaction_stats);
42
+ sc.AggregateCompactionOutputStats(compaction_stats);
43
43
  compaction_job_stats.Add(sc.compaction_job_stats);
44
44
  }
45
45
  }