@nxtedition/rocksdb 7.0.4 → 7.0.7
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/binding.cc +320 -324
- package/chained-batch.js +6 -1
- package/deps/rocksdb/rocksdb/CMakeLists.txt +8 -3
- package/deps/rocksdb/rocksdb/Makefile +10 -4
- package/deps/rocksdb/rocksdb/TARGETS +6 -4
- package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +9 -0
- package/deps/rocksdb/rocksdb/cache/cache_test.cc +14 -0
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +8 -8
- package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +272 -174
- package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +201 -57
- package/deps/rocksdb/rocksdb/cache/lru_cache.cc +19 -19
- package/deps/rocksdb/rocksdb/cache/lru_cache.h +2 -1
- package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +170 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_source.h +95 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +298 -0
- package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +172 -0
- package/deps/rocksdb/rocksdb/db/column_family.cc +8 -3
- package/deps/rocksdb/rocksdb/db/column_family.h +6 -3
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +10 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +6 -6
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +22 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +38 -0
- package/deps/rocksdb/rocksdb/db/db_basic_test.cc +17 -5
- package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +4 -7
- package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +74 -71
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +70 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +13 -12
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +36 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +11 -4
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +139 -91
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +48 -14
- package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +90 -55
- package/deps/rocksdb/rocksdb/db/db_rate_limiter_test.cc +9 -4
- package/deps/rocksdb/rocksdb/db/db_test.cc +3 -1
- package/deps/rocksdb/rocksdb/db/db_wal_test.cc +12 -7
- package/deps/rocksdb/rocksdb/db/db_write_test.cc +35 -0
- package/deps/rocksdb/rocksdb/db/dbformat.cc +3 -1
- package/deps/rocksdb/rocksdb/db/dbformat.h +5 -3
- package/deps/rocksdb/rocksdb/db/flush_job_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/memtable.cc +1 -0
- package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +4 -2
- package/deps/rocksdb/rocksdb/db/repair.cc +1 -1
- package/deps/rocksdb/rocksdb/db/version_builder.cc +43 -1
- package/deps/rocksdb/rocksdb/db/version_edit.cc +13 -5
- package/deps/rocksdb/rocksdb/db/version_edit.h +22 -1
- package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +4 -5
- package/deps/rocksdb/rocksdb/db/version_set.cc +109 -41
- package/deps/rocksdb/rocksdb/db/version_set.h +36 -3
- package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -4
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +10 -10
- package/deps/rocksdb/rocksdb/db/version_util.h +1 -1
- package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +1 -1
- package/deps/rocksdb/rocksdb/db/write_batch.cc +34 -10
- package/deps/rocksdb/rocksdb/db/write_batch_internal.h +2 -0
- package/deps/rocksdb/rocksdb/db/write_callback_test.cc +4 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +2 -0
- package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +4 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +7 -5
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +5 -10
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +0 -7
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +2 -0
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +24 -3
- package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +8 -0
- package/deps/rocksdb/rocksdb/file/writable_file_writer.h +10 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +4 -4
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +9 -5
- package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/types.h +1 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/version.h +1 -1
- package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +0 -3
- package/deps/rocksdb/rocksdb/microbench/ribbon_bench.cc +8 -6
- package/deps/rocksdb/rocksdb/monitoring/statistics.cc +3 -1
- package/deps/rocksdb/rocksdb/options/options_helper.cc +4 -2
- package/deps/rocksdb/rocksdb/options/options_test.cc +1 -11
- package/deps/rocksdb/rocksdb/port/port_posix.h +7 -0
- package/deps/rocksdb/rocksdb/port/win/port_win.h +11 -3
- package/deps/rocksdb/rocksdb/src.mk +6 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +4 -33
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +3 -3
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +38 -118
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +6 -8
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +10 -13
- package/deps/rocksdb/rocksdb/table/block_based/block_like_traits.h +4 -9
- package/deps/rocksdb/rocksdb/table/block_based/block_type.h +0 -1
- package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +10 -28
- package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +2 -3
- package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +0 -91
- package/deps/rocksdb/rocksdb/table/block_based/filter_policy_internal.h +2 -30
- package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +6 -27
- package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +11 -13
- package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +28 -40
- package/deps/rocksdb/rocksdb/table/block_based/mock_block_based_table.h +0 -1
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +22 -43
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +11 -22
- package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +24 -25
- package/deps/rocksdb/rocksdb/table/block_fetcher.cc +0 -1
- package/deps/rocksdb/rocksdb/table/get_context.h +0 -1
- package/deps/rocksdb/rocksdb/table/table_test.cc +3 -18
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +3 -16
- package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +3 -3
- package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +1 -1
- package/deps/rocksdb/rocksdb/util/bloom_test.cc +0 -201
- package/deps/rocksdb/rocksdb/util/distributed_mutex.h +48 -0
- package/deps/rocksdb/rocksdb/util/filter_bench.cc +5 -11
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +3 -0
- package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +7 -21
- package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +1 -1
- package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +45 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.h +21 -14
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +10 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +3 -1
- package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.cc +9 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn.cc +3 -2
- package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn_db.cc +3 -1
- package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +5 -4
- package/deps/rocksdb/rocksdb.gyp +1 -1
- package/index.js +36 -14
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
- package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.cc +0 -358
- package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.h +0 -127
- package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block_test.cc +0 -219
|
@@ -161,8 +161,7 @@ class PartitionedFilterBlockTest
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
void VerifyReader(PartitionedFilterBlockBuilder* builder,
|
|
164
|
-
PartitionedIndexBuilder* pib, bool empty = false
|
|
165
|
-
const SliceTransform* prefix_extractor = nullptr) {
|
|
164
|
+
PartitionedIndexBuilder* pib, bool empty = false) {
|
|
166
165
|
std::unique_ptr<PartitionedFilterBlockReader> reader(
|
|
167
166
|
NewReader(builder, pib));
|
|
168
167
|
// Querying added keys
|
|
@@ -170,31 +169,31 @@ class PartitionedFilterBlockTest
|
|
|
170
169
|
for (auto key : keys) {
|
|
171
170
|
auto ikey = InternalKey(key, 0, ValueType::kTypeValue);
|
|
172
171
|
const Slice ikey_slice = Slice(*ikey.rep());
|
|
173
|
-
ASSERT_TRUE(reader->KeyMayMatch(key,
|
|
174
|
-
|
|
172
|
+
ASSERT_TRUE(reader->KeyMayMatch(key, !no_io, &ikey_slice,
|
|
173
|
+
/*get_context=*/nullptr,
|
|
175
174
|
/*lookup_context=*/nullptr));
|
|
176
175
|
}
|
|
177
176
|
{
|
|
178
177
|
// querying a key twice
|
|
179
178
|
auto ikey = InternalKey(keys[0], 0, ValueType::kTypeValue);
|
|
180
179
|
const Slice ikey_slice = Slice(*ikey.rep());
|
|
181
|
-
ASSERT_TRUE(reader->KeyMayMatch(
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
ASSERT_TRUE(reader->KeyMayMatch(keys[0], !no_io, &ikey_slice,
|
|
181
|
+
/*get_context=*/nullptr,
|
|
182
|
+
/*lookup_context=*/nullptr));
|
|
184
183
|
}
|
|
185
184
|
// querying missing keys
|
|
186
185
|
for (auto key : missing_keys) {
|
|
187
186
|
auto ikey = InternalKey(key, 0, ValueType::kTypeValue);
|
|
188
187
|
const Slice ikey_slice = Slice(*ikey.rep());
|
|
189
188
|
if (empty) {
|
|
190
|
-
ASSERT_TRUE(reader->KeyMayMatch(
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
ASSERT_TRUE(reader->KeyMayMatch(key, !no_io, &ikey_slice,
|
|
190
|
+
/*get_context=*/nullptr,
|
|
191
|
+
/*lookup_context=*/nullptr));
|
|
193
192
|
} else {
|
|
194
193
|
// assuming a good hash function
|
|
195
|
-
ASSERT_FALSE(reader->KeyMayMatch(
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
ASSERT_FALSE(reader->KeyMayMatch(key, !no_io, &ikey_slice,
|
|
195
|
+
/*get_context=*/nullptr,
|
|
196
|
+
/*lookup_context=*/nullptr));
|
|
198
197
|
}
|
|
199
198
|
}
|
|
200
199
|
}
|
|
@@ -343,20 +342,20 @@ TEST_P(PartitionedFilterBlockTest, SamePrefixInMultipleBlocks) {
|
|
|
343
342
|
for (auto key : pkeys) {
|
|
344
343
|
auto ikey = InternalKey(key, 0, ValueType::kTypeValue);
|
|
345
344
|
const Slice ikey_slice = Slice(*ikey.rep());
|
|
346
|
-
ASSERT_TRUE(reader->PrefixMayMatch(
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
345
|
+
ASSERT_TRUE(reader->PrefixMayMatch(prefix_extractor->Transform(key),
|
|
346
|
+
/*no_io=*/false, &ikey_slice,
|
|
347
|
+
/*get_context=*/nullptr,
|
|
348
|
+
/*lookup_context=*/nullptr));
|
|
350
349
|
}
|
|
351
350
|
// Non-existent keys but with the same prefix
|
|
352
351
|
const std::string pnonkeys[4] = {"p-key9", "p-key11", "p-key21", "p-key31"};
|
|
353
352
|
for (auto key : pnonkeys) {
|
|
354
353
|
auto ikey = InternalKey(key, 0, ValueType::kTypeValue);
|
|
355
354
|
const Slice ikey_slice = Slice(*ikey.rep());
|
|
356
|
-
ASSERT_TRUE(reader->PrefixMayMatch(
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
355
|
+
ASSERT_TRUE(reader->PrefixMayMatch(prefix_extractor->Transform(key),
|
|
356
|
+
/*no_io=*/false, &ikey_slice,
|
|
357
|
+
/*get_context=*/nullptr,
|
|
358
|
+
/*lookup_context=*/nullptr));
|
|
360
359
|
}
|
|
361
360
|
}
|
|
362
361
|
|
|
@@ -391,10 +390,10 @@ TEST_P(PartitionedFilterBlockTest, PrefixInWrongPartitionBug) {
|
|
|
391
390
|
auto prefix = prefix_extractor->Transform(key);
|
|
392
391
|
auto ikey = InternalKey(prefix, 0, ValueType::kTypeValue);
|
|
393
392
|
const Slice ikey_slice = Slice(*ikey.rep());
|
|
394
|
-
ASSERT_TRUE(reader->PrefixMayMatch(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
393
|
+
ASSERT_TRUE(reader->PrefixMayMatch(prefix,
|
|
394
|
+
/*no_io=*/false, &ikey_slice,
|
|
395
|
+
/*get_context=*/nullptr,
|
|
396
|
+
/*lookup_context=*/nullptr));
|
|
398
397
|
}
|
|
399
398
|
}
|
|
400
399
|
|
|
@@ -3524,11 +3524,10 @@ TEST_P(BlockBasedTableTest, InvalidOptions) {
|
|
|
3524
3524
|
}
|
|
3525
3525
|
|
|
3526
3526
|
TEST_P(BlockBasedTableTest, BlockReadCountTest) {
|
|
3527
|
-
// bloom_filter_type = 0 -- block-based filter (not available in public API)
|
|
3528
3527
|
// bloom_filter_type = 1 -- full filter using use_block_based_builder=false
|
|
3529
3528
|
// bloom_filter_type = 2 -- full filter using use_block_based_builder=true
|
|
3530
3529
|
// because of API change to hide block-based filter
|
|
3531
|
-
for (int bloom_filter_type =
|
|
3530
|
+
for (int bloom_filter_type = 1; bloom_filter_type <= 2; ++bloom_filter_type) {
|
|
3532
3531
|
for (int index_and_filter_in_cache = 0; index_and_filter_in_cache < 2;
|
|
3533
3532
|
++index_and_filter_in_cache) {
|
|
3534
3533
|
Options options;
|
|
@@ -3537,22 +3536,8 @@ TEST_P(BlockBasedTableTest, BlockReadCountTest) {
|
|
|
3537
3536
|
BlockBasedTableOptions table_options = GetBlockBasedTableOptions();
|
|
3538
3537
|
table_options.block_cache = NewLRUCache(1, 0);
|
|
3539
3538
|
table_options.cache_index_and_filter_blocks = index_and_filter_in_cache;
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
// Use back-door way of enabling obsolete block-based Bloom
|
|
3543
|
-
ASSERT_OK(FilterPolicy::CreateFromString(
|
|
3544
|
-
ConfigOptions(),
|
|
3545
|
-
"rocksdb.internal.DeprecatedBlockBasedBloomFilter:10",
|
|
3546
|
-
&table_options.filter_policy));
|
|
3547
|
-
#else
|
|
3548
|
-
// Skip this case in LITE build
|
|
3549
|
-
continue;
|
|
3550
|
-
#endif
|
|
3551
|
-
} else {
|
|
3552
|
-
// Public API
|
|
3553
|
-
table_options.filter_policy.reset(
|
|
3554
|
-
NewBloomFilterPolicy(10, bloom_filter_type == 2));
|
|
3555
|
-
}
|
|
3539
|
+
table_options.filter_policy.reset(
|
|
3540
|
+
NewBloomFilterPolicy(10, bloom_filter_type == 2));
|
|
3556
3541
|
options.table_factory.reset(new BlockBasedTableFactory(table_options));
|
|
3557
3542
|
std::vector<std::string> keys;
|
|
3558
3543
|
stl_wrappers::KVMap kvmap;
|
|
@@ -1605,9 +1605,6 @@ DEFINE_double(cuckoo_hash_ratio, 0.9, "Hash ratio for Cuckoo SST table.");
|
|
|
1605
1605
|
DEFINE_bool(use_hash_search, false, "if use kHashSearch "
|
|
1606
1606
|
"instead of kBinarySearch. "
|
|
1607
1607
|
"This is valid if only we use BlockTable");
|
|
1608
|
-
DEFINE_bool(use_block_based_filter, false, "if use kBlockBasedFilter "
|
|
1609
|
-
"instead of kFullFilter for filter block. "
|
|
1610
|
-
"This is valid if only we use BlockTable");
|
|
1611
1608
|
DEFINE_string(merge_operator, "", "The merge operator to use with the database."
|
|
1612
1609
|
"If a new merge operator is specified, be sure to use fresh"
|
|
1613
1610
|
" database The possible merge operators are defined in"
|
|
@@ -4525,19 +4522,6 @@ class Benchmark {
|
|
|
4525
4522
|
table_options->filter_policy = BlockBasedTableOptions().filter_policy;
|
|
4526
4523
|
} else if (FLAGS_bloom_bits == 0) {
|
|
4527
4524
|
table_options->filter_policy.reset();
|
|
4528
|
-
} else if (FLAGS_use_block_based_filter) {
|
|
4529
|
-
// Use back-door way of enabling obsolete block-based Bloom
|
|
4530
|
-
Status s = FilterPolicy::CreateFromString(
|
|
4531
|
-
ConfigOptions(),
|
|
4532
|
-
"rocksdb.internal.DeprecatedBlockBasedBloomFilter:" +
|
|
4533
|
-
std::to_string(FLAGS_bloom_bits),
|
|
4534
|
-
&table_options->filter_policy);
|
|
4535
|
-
if (!s.ok()) {
|
|
4536
|
-
fprintf(stderr,
|
|
4537
|
-
"failure creating obsolete block-based filter: %s\n",
|
|
4538
|
-
s.ToString().c_str());
|
|
4539
|
-
exit(1);
|
|
4540
|
-
}
|
|
4541
4525
|
} else {
|
|
4542
4526
|
table_options->filter_policy.reset(
|
|
4543
4527
|
FLAGS_use_ribbon_filter ? NewRibbonFilterPolicy(FLAGS_bloom_bits)
|
|
@@ -4578,6 +4562,9 @@ class Benchmark {
|
|
|
4578
4562
|
options.rate_limiter.reset(NewGenericRateLimiter(
|
|
4579
4563
|
FLAGS_rate_limiter_bytes_per_sec,
|
|
4580
4564
|
FLAGS_rate_limiter_refill_period_us, 10 /* fairness */,
|
|
4565
|
+
// TODO: replace this with a more general FLAG for deciding
|
|
4566
|
+
// RateLimiter::Mode as now we also rate-limit foreground reads e.g,
|
|
4567
|
+
// Get()/MultiGet()
|
|
4581
4568
|
FLAGS_rate_limit_bg_reads ? RateLimiter::Mode::kReadsOnly
|
|
4582
4569
|
: RateLimiter::Mode::kWritesOnly,
|
|
4583
4570
|
FLAGS_rate_limiter_auto_tuned));
|
|
@@ -1306,7 +1306,7 @@ void DumpManifestFile(Options options, std::string file, bool verbose, bool hex,
|
|
|
1306
1306
|
ImmutableDBOptions immutable_db_options(options);
|
|
1307
1307
|
VersionSet versions(dbname, &immutable_db_options, sopt, tc.get(), &wb, &wc,
|
|
1308
1308
|
/*block_cache_tracer=*/nullptr, /*io_tracer=*/nullptr,
|
|
1309
|
-
/*db_session_id*/ "");
|
|
1309
|
+
/*db_id*/ "", /*db_session_id*/ "");
|
|
1310
1310
|
Status s = versions.DumpManifest(options, file, verbose, hex, json);
|
|
1311
1311
|
if (!s.ok()) {
|
|
1312
1312
|
fprintf(stderr, "Error in processing file %s %s\n", file.c_str(),
|
|
@@ -1448,7 +1448,7 @@ Status GetLiveFilesChecksumInfoFromVersionSet(Options options,
|
|
|
1448
1448
|
ImmutableDBOptions immutable_db_options(options);
|
|
1449
1449
|
VersionSet versions(dbname, &immutable_db_options, sopt, tc.get(), &wb, &wc,
|
|
1450
1450
|
/*block_cache_tracer=*/nullptr, /*io_tracer=*/nullptr,
|
|
1451
|
-
/*db_session_id*/ "");
|
|
1451
|
+
/*db_id*/ "", /*db_session_id*/ "");
|
|
1452
1452
|
std::vector<std::string> cf_name_list;
|
|
1453
1453
|
s = versions.ListColumnFamilies(&cf_name_list, db_path,
|
|
1454
1454
|
immutable_db_options.fs.get());
|
|
@@ -2255,7 +2255,7 @@ Status ReduceDBLevelsCommand::GetOldNumOfLevels(Options& opt,
|
|
|
2255
2255
|
WriteBufferManager wb(opt.db_write_buffer_size);
|
|
2256
2256
|
VersionSet versions(db_path_, &db_options, soptions, tc.get(), &wb, &wc,
|
|
2257
2257
|
/*block_cache_tracer=*/nullptr, /*io_tracer=*/nullptr,
|
|
2258
|
-
/*db_session_id*/ "");
|
|
2258
|
+
/*db_id*/ "", /*db_session_id*/ "");
|
|
2259
2259
|
std::vector<ColumnFamilyDescriptor> dummy;
|
|
2260
2260
|
ColumnFamilyDescriptor dummy_descriptor(kDefaultColumnFamilyName,
|
|
2261
2261
|
ColumnFamilyOptions(opt));
|
|
@@ -208,7 +208,7 @@ class FileChecksumTestHelper {
|
|
|
208
208
|
WriteBufferManager wb(options_.db_write_buffer_size);
|
|
209
209
|
ImmutableDBOptions immutable_db_options(options_);
|
|
210
210
|
VersionSet versions(dbname_, &immutable_db_options, sopt, tc.get(), &wb,
|
|
211
|
-
&wc, nullptr, nullptr, "");
|
|
211
|
+
&wc, nullptr, nullptr, "", "");
|
|
212
212
|
std::vector<std::string> cf_name_list;
|
|
213
213
|
Status s;
|
|
214
214
|
s = versions.ListColumnFamilies(&cf_name_list, dbname_,
|
|
@@ -69,207 +69,6 @@ static int NextLength(int length) {
|
|
|
69
69
|
return length;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
class BlockBasedBloomTest : public testing::Test {
|
|
73
|
-
private:
|
|
74
|
-
std::unique_ptr<const DeprecatedBlockBasedBloomFilterPolicy> policy_;
|
|
75
|
-
std::string filter_;
|
|
76
|
-
std::vector<std::string> keys_;
|
|
77
|
-
|
|
78
|
-
public:
|
|
79
|
-
BlockBasedBloomTest() { ResetPolicy(); }
|
|
80
|
-
|
|
81
|
-
void Reset() {
|
|
82
|
-
keys_.clear();
|
|
83
|
-
filter_.clear();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
void ResetPolicy(double bits_per_key) {
|
|
87
|
-
policy_.reset(new DeprecatedBlockBasedBloomFilterPolicy(bits_per_key));
|
|
88
|
-
Reset();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
void ResetPolicy() { ResetPolicy(FLAGS_bits_per_key); }
|
|
92
|
-
|
|
93
|
-
void Add(const Slice& s) {
|
|
94
|
-
keys_.push_back(s.ToString());
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
void Build() {
|
|
98
|
-
std::vector<Slice> key_slices;
|
|
99
|
-
for (size_t i = 0; i < keys_.size(); i++) {
|
|
100
|
-
key_slices.push_back(Slice(keys_[i]));
|
|
101
|
-
}
|
|
102
|
-
filter_.clear();
|
|
103
|
-
DeprecatedBlockBasedBloomFilterPolicy::CreateFilter(
|
|
104
|
-
&key_slices[0], static_cast<int>(key_slices.size()),
|
|
105
|
-
policy_->GetWholeBitsPerKey(), &filter_);
|
|
106
|
-
keys_.clear();
|
|
107
|
-
if (kVerbose >= 2) DumpFilter();
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
size_t FilterSize() const {
|
|
111
|
-
return filter_.size();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
Slice FilterData() const { return Slice(filter_); }
|
|
115
|
-
|
|
116
|
-
void DumpFilter() {
|
|
117
|
-
fprintf(stderr, "F(");
|
|
118
|
-
for (size_t i = 0; i+1 < filter_.size(); i++) {
|
|
119
|
-
const unsigned int c = static_cast<unsigned int>(filter_[i]);
|
|
120
|
-
for (int j = 0; j < 8; j++) {
|
|
121
|
-
fprintf(stderr, "%c", (c & (1 <<j)) ? '1' : '.');
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
fprintf(stderr, ")\n");
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
bool Matches(const Slice& s) {
|
|
128
|
-
if (!keys_.empty()) {
|
|
129
|
-
Build();
|
|
130
|
-
}
|
|
131
|
-
return DeprecatedBlockBasedBloomFilterPolicy::KeyMayMatch(s, filter_);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
double FalsePositiveRate() {
|
|
135
|
-
char buffer[sizeof(int)];
|
|
136
|
-
int result = 0;
|
|
137
|
-
for (int i = 0; i < 10000; i++) {
|
|
138
|
-
if (Matches(Key(i + 1000000000, buffer))) {
|
|
139
|
-
result++;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return result / 10000.0;
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
TEST_F(BlockBasedBloomTest, EmptyFilter) {
|
|
147
|
-
ASSERT_TRUE(! Matches("hello"));
|
|
148
|
-
ASSERT_TRUE(! Matches("world"));
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
TEST_F(BlockBasedBloomTest, Small) {
|
|
152
|
-
Add("hello");
|
|
153
|
-
Add("world");
|
|
154
|
-
ASSERT_TRUE(Matches("hello"));
|
|
155
|
-
ASSERT_TRUE(Matches("world"));
|
|
156
|
-
ASSERT_TRUE(! Matches("x"));
|
|
157
|
-
ASSERT_TRUE(! Matches("foo"));
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
TEST_F(BlockBasedBloomTest, VaryingLengths) {
|
|
161
|
-
char buffer[sizeof(int)];
|
|
162
|
-
|
|
163
|
-
// Count number of filters that significantly exceed the false positive rate
|
|
164
|
-
int mediocre_filters = 0;
|
|
165
|
-
int good_filters = 0;
|
|
166
|
-
|
|
167
|
-
for (int length = 1; length <= 10000; length = NextLength(length)) {
|
|
168
|
-
Reset();
|
|
169
|
-
for (int i = 0; i < length; i++) {
|
|
170
|
-
Add(Key(i, buffer));
|
|
171
|
-
}
|
|
172
|
-
Build();
|
|
173
|
-
|
|
174
|
-
ASSERT_LE(FilterSize(), (size_t)((length * FLAGS_bits_per_key / 8) + 40))
|
|
175
|
-
<< length;
|
|
176
|
-
|
|
177
|
-
// All added keys must match
|
|
178
|
-
for (int i = 0; i < length; i++) {
|
|
179
|
-
ASSERT_TRUE(Matches(Key(i, buffer)))
|
|
180
|
-
<< "Length " << length << "; key " << i;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Check false positive rate
|
|
184
|
-
double rate = FalsePositiveRate();
|
|
185
|
-
if (kVerbose >= 1) {
|
|
186
|
-
fprintf(stderr, "False positives: %5.2f%% @ length = %6d ; bytes = %6d\n",
|
|
187
|
-
rate*100.0, length, static_cast<int>(FilterSize()));
|
|
188
|
-
}
|
|
189
|
-
if (FLAGS_bits_per_key == 10) {
|
|
190
|
-
ASSERT_LE(rate, 0.02); // Must not be over 2%
|
|
191
|
-
if (rate > 0.0125) {
|
|
192
|
-
mediocre_filters++; // Allowed, but not too often
|
|
193
|
-
} else {
|
|
194
|
-
good_filters++;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
if (FLAGS_bits_per_key == 10 && kVerbose >= 1) {
|
|
199
|
-
fprintf(stderr, "Filters: %d good, %d mediocre\n",
|
|
200
|
-
good_filters, mediocre_filters);
|
|
201
|
-
}
|
|
202
|
-
ASSERT_LE(mediocre_filters, good_filters/5);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Ensure the implementation doesn't accidentally change in an
|
|
206
|
-
// incompatible way
|
|
207
|
-
TEST_F(BlockBasedBloomTest, Schema) {
|
|
208
|
-
char buffer[sizeof(int)];
|
|
209
|
-
|
|
210
|
-
ResetPolicy(8); // num_probes = 5
|
|
211
|
-
for (int key = 0; key < 87; key++) {
|
|
212
|
-
Add(Key(key, buffer));
|
|
213
|
-
}
|
|
214
|
-
Build();
|
|
215
|
-
ASSERT_EQ(BloomHash(FilterData()), 3589896109U);
|
|
216
|
-
|
|
217
|
-
ResetPolicy(9); // num_probes = 6
|
|
218
|
-
for (int key = 0; key < 87; key++) {
|
|
219
|
-
Add(Key(key, buffer));
|
|
220
|
-
}
|
|
221
|
-
Build();
|
|
222
|
-
ASSERT_EQ(BloomHash(FilterData()), 969445585U);
|
|
223
|
-
|
|
224
|
-
ResetPolicy(11); // num_probes = 7
|
|
225
|
-
for (int key = 0; key < 87; key++) {
|
|
226
|
-
Add(Key(key, buffer));
|
|
227
|
-
}
|
|
228
|
-
Build();
|
|
229
|
-
ASSERT_EQ(BloomHash(FilterData()), 1694458207U);
|
|
230
|
-
|
|
231
|
-
ResetPolicy(10); // num_probes = 6
|
|
232
|
-
for (int key = 0; key < 87; key++) {
|
|
233
|
-
Add(Key(key, buffer));
|
|
234
|
-
}
|
|
235
|
-
Build();
|
|
236
|
-
ASSERT_EQ(BloomHash(FilterData()), 2373646410U);
|
|
237
|
-
|
|
238
|
-
ResetPolicy(10);
|
|
239
|
-
for (int key = /*CHANGED*/ 1; key < 87; key++) {
|
|
240
|
-
Add(Key(key, buffer));
|
|
241
|
-
}
|
|
242
|
-
Build();
|
|
243
|
-
ASSERT_EQ(BloomHash(FilterData()), 1908442116U);
|
|
244
|
-
|
|
245
|
-
ResetPolicy(10);
|
|
246
|
-
for (int key = 1; key < /*CHANGED*/ 88; key++) {
|
|
247
|
-
Add(Key(key, buffer));
|
|
248
|
-
}
|
|
249
|
-
Build();
|
|
250
|
-
ASSERT_EQ(BloomHash(FilterData()), 3057004015U);
|
|
251
|
-
|
|
252
|
-
// With new fractional bits_per_key, check that we are rounding to
|
|
253
|
-
// whole bits per key for old Bloom filters.
|
|
254
|
-
ResetPolicy(9.5); // Treated as 10
|
|
255
|
-
for (int key = 1; key < 88; key++) {
|
|
256
|
-
Add(Key(key, buffer));
|
|
257
|
-
}
|
|
258
|
-
Build();
|
|
259
|
-
ASSERT_EQ(BloomHash(FilterData()), /*SAME*/ 3057004015U);
|
|
260
|
-
|
|
261
|
-
ResetPolicy(10.499); // Treated as 10
|
|
262
|
-
for (int key = 1; key < 88; key++) {
|
|
263
|
-
Add(Key(key, buffer));
|
|
264
|
-
}
|
|
265
|
-
Build();
|
|
266
|
-
ASSERT_EQ(BloomHash(FilterData()), /*SAME*/ 3057004015U);
|
|
267
|
-
|
|
268
|
-
ResetPolicy();
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Different bits-per-byte
|
|
272
|
-
|
|
273
72
|
class FullBloomTest : public testing::TestWithParam<std::string> {
|
|
274
73
|
protected:
|
|
275
74
|
BlockBasedTableOptions table_options_;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
|
2
|
+
// This source code is licensed under both the GPLv2 (found in the
|
|
3
|
+
// COPYING file in the root directory) and Apache 2.0 License
|
|
4
|
+
// (found in the LICENSE.Apache file in the root directory).
|
|
5
|
+
|
|
6
|
+
#pragma once
|
|
7
|
+
|
|
8
|
+
#include "rocksdb/rocksdb_namespace.h"
|
|
9
|
+
|
|
10
|
+
// This file declares a wrapper around the efficient folly DistributedMutex
|
|
11
|
+
// that falls back on a standard mutex when not available. See
|
|
12
|
+
// https://github.com/facebook/folly/blob/main/folly/synchronization/DistributedMutex.h
|
|
13
|
+
// for benefits and limitations.
|
|
14
|
+
|
|
15
|
+
// At the moment, only scoped locking is supported using DMutexLock
|
|
16
|
+
// RAII wrapper, because lock/unlock APIs will vary.
|
|
17
|
+
|
|
18
|
+
#ifdef USE_FOLLY
|
|
19
|
+
|
|
20
|
+
#include <folly/synchronization/DistributedMutex.h>
|
|
21
|
+
|
|
22
|
+
namespace ROCKSDB_NAMESPACE {
|
|
23
|
+
|
|
24
|
+
class DMutex : public folly::DistributedMutex {
|
|
25
|
+
public:
|
|
26
|
+
static const char* kName() { return "folly::DistributedMutex"; }
|
|
27
|
+
|
|
28
|
+
explicit DMutex(bool IGNORED_adaptive = false) { (void)IGNORED_adaptive; }
|
|
29
|
+
|
|
30
|
+
// currently no-op
|
|
31
|
+
void AssertHeld() {}
|
|
32
|
+
};
|
|
33
|
+
using DMutexLock = std::lock_guard<folly::DistributedMutex>;
|
|
34
|
+
|
|
35
|
+
} // namespace ROCKSDB_NAMESPACE
|
|
36
|
+
|
|
37
|
+
#else
|
|
38
|
+
|
|
39
|
+
#include "port/port.h"
|
|
40
|
+
|
|
41
|
+
namespace ROCKSDB_NAMESPACE {
|
|
42
|
+
|
|
43
|
+
using DMutex = port::Mutex;
|
|
44
|
+
using DMutexLock = std::lock_guard<DMutex>;
|
|
45
|
+
|
|
46
|
+
} // namespace ROCKSDB_NAMESPACE
|
|
47
|
+
|
|
48
|
+
#endif
|
|
@@ -84,8 +84,8 @@ DEFINE_bool(new_builder, false,
|
|
|
84
84
|
|
|
85
85
|
DEFINE_uint32(impl, 0,
|
|
86
86
|
"Select filter implementation. Without -use_plain_table_bloom:"
|
|
87
|
-
"0 = legacy full Bloom filter,
|
|
88
|
-
"
|
|
87
|
+
"0 = legacy full Bloom filter, "
|
|
88
|
+
"1 = format_version 5 Bloom filter, 2 = Ribbon128 filter. With "
|
|
89
89
|
"-use_plain_table_bloom: 0 = no locality, 1 = locality.");
|
|
90
90
|
|
|
91
91
|
DEFINE_bool(net_includes_hashing, false,
|
|
@@ -358,13 +358,9 @@ void FilterBench::Go() {
|
|
|
358
358
|
"-impl must currently be >= 0 and <= 1 for Plain table");
|
|
359
359
|
}
|
|
360
360
|
} else {
|
|
361
|
-
if (FLAGS_impl
|
|
361
|
+
if (FLAGS_impl > 2) {
|
|
362
362
|
throw std::runtime_error(
|
|
363
|
-
"
|
|
364
|
-
}
|
|
365
|
-
if (FLAGS_impl > 3) {
|
|
366
|
-
throw std::runtime_error(
|
|
367
|
-
"-impl must currently be 0, 2, or 3 for Block-based table");
|
|
363
|
+
"-impl must currently be >= 0 and <= 2 for Block-based table");
|
|
368
364
|
}
|
|
369
365
|
}
|
|
370
366
|
|
|
@@ -603,7 +599,7 @@ double FilterBench::RandomQueryTest(uint32_t inside_threshold, bool dry_run,
|
|
|
603
599
|
|
|
604
600
|
auto dry_run_hash_fn = DryRunNoHash;
|
|
605
601
|
if (!FLAGS_net_includes_hashing) {
|
|
606
|
-
if (FLAGS_impl
|
|
602
|
+
if (FLAGS_impl == 0 || FLAGS_use_plain_table_bloom) {
|
|
607
603
|
dry_run_hash_fn = DryRunHash32;
|
|
608
604
|
} else {
|
|
609
605
|
dry_run_hash_fn = DryRunHash64;
|
|
@@ -728,8 +724,6 @@ double FilterBench::RandomQueryTest(uint32_t inside_threshold, bool dry_run,
|
|
|
728
724
|
} else {
|
|
729
725
|
may_match = info.full_block_reader_->KeyMayMatch(
|
|
730
726
|
batch_slices[i],
|
|
731
|
-
/*prefix_extractor=*/nullptr,
|
|
732
|
-
/*block_offset=*/ROCKSDB_NAMESPACE::kNotValid,
|
|
733
727
|
/*no_io=*/false, /*const_ikey_ptr=*/nullptr,
|
|
734
728
|
/*get_context=*/nullptr,
|
|
735
729
|
/*lookup_context=*/nullptr);
|
|
@@ -296,6 +296,9 @@ class BackupEngineImpl {
|
|
|
296
296
|
}
|
|
297
297
|
};
|
|
298
298
|
|
|
299
|
+
// TODO: deprecate this function once we migrate all BackupEngine's rate
|
|
300
|
+
// limiting to lower-level ones (i.e, ones in file access wrapper level like
|
|
301
|
+
// `WritableFileWriter`)
|
|
299
302
|
static void LoopRateLimitRequestHelper(const size_t total_bytes_to_request,
|
|
300
303
|
RateLimiter* rate_limiter,
|
|
301
304
|
const Env::IOPriority pri,
|
|
@@ -139,11 +139,6 @@ CacheDumperImpl::DumpOneBlockCallBack() {
|
|
|
139
139
|
block_start = (static_cast<Block*>(value))->data();
|
|
140
140
|
block_len = (static_cast<Block*>(value))->size();
|
|
141
141
|
break;
|
|
142
|
-
case CacheEntryRole::kDeprecatedFilterBlock:
|
|
143
|
-
type = CacheDumpUnitType::kDeprecatedFilterBlock;
|
|
144
|
-
block_start = (static_cast<BlockContents*>(value))->data.data();
|
|
145
|
-
block_len = (static_cast<BlockContents*>(value))->data.size();
|
|
146
|
-
break;
|
|
147
142
|
case CacheEntryRole::kFilterBlock:
|
|
148
143
|
type = CacheDumpUnitType::kFilter;
|
|
149
144
|
block_start = (static_cast<ParsedFullFilterBlock*>(value))
|
|
@@ -163,6 +158,10 @@ CacheDumperImpl::DumpOneBlockCallBack() {
|
|
|
163
158
|
block_start = (static_cast<Block*>(value))->data();
|
|
164
159
|
block_len = (static_cast<Block*>(value))->size();
|
|
165
160
|
break;
|
|
161
|
+
case CacheEntryRole::kDeprecatedFilterBlock:
|
|
162
|
+
// Obsolete
|
|
163
|
+
filter_out = true;
|
|
164
|
+
break;
|
|
166
165
|
case CacheEntryRole::kMisc:
|
|
167
166
|
filter_out = true;
|
|
168
167
|
break;
|
|
@@ -322,22 +321,6 @@ IOStatus CacheDumpedLoaderImpl::RestoreCacheEntriesToSecondaryCache() {
|
|
|
322
321
|
// according to the block type, get the helper callback function and create
|
|
323
322
|
// the corresponding block
|
|
324
323
|
switch (dump_unit.type) {
|
|
325
|
-
case CacheDumpUnitType::kDeprecatedFilterBlock: {
|
|
326
|
-
helper = BlocklikeTraits<BlockContents>::GetCacheItemHelper(
|
|
327
|
-
BlockType::kDeprecatedFilter);
|
|
328
|
-
std::unique_ptr<BlockContents> block_holder;
|
|
329
|
-
block_holder.reset(BlocklikeTraits<BlockContents>::Create(
|
|
330
|
-
std::move(raw_block_contents), 0, statistics, false,
|
|
331
|
-
toptions_.filter_policy.get()));
|
|
332
|
-
// Insert the block to secondary cache.
|
|
333
|
-
// Note that, if we cannot get the correct helper callback, the block
|
|
334
|
-
// will not be inserted.
|
|
335
|
-
if (helper != nullptr) {
|
|
336
|
-
s = secondary_cache_->Insert(dump_unit.key,
|
|
337
|
-
(void*)(block_holder.get()), helper);
|
|
338
|
-
}
|
|
339
|
-
break;
|
|
340
|
-
}
|
|
341
324
|
case CacheDumpUnitType::kFilter: {
|
|
342
325
|
helper = BlocklikeTraits<ParsedFullFilterBlock>::GetCacheItemHelper(
|
|
343
326
|
BlockType::kFilter);
|
|
@@ -390,6 +373,9 @@ IOStatus CacheDumpedLoaderImpl::RestoreCacheEntriesToSecondaryCache() {
|
|
|
390
373
|
}
|
|
391
374
|
case CacheDumpUnitType::kFooter:
|
|
392
375
|
break;
|
|
376
|
+
case CacheDumpUnitType::kDeprecatedFilterBlock:
|
|
377
|
+
// Obsolete
|
|
378
|
+
break;
|
|
393
379
|
default:
|
|
394
380
|
continue;
|
|
395
381
|
}
|
|
@@ -915,6 +915,51 @@ TEST_F(CheckpointTest, CheckpointWithDbPath) {
|
|
|
915
915
|
delete checkpoint;
|
|
916
916
|
}
|
|
917
917
|
|
|
918
|
+
TEST_F(CheckpointTest, PutRaceWithCheckpointTrackedWalSync) {
|
|
919
|
+
// Repro for a race condition where a user write comes in after the checkpoint
|
|
920
|
+
// syncs WAL for `track_and_verify_wals_in_manifest` but before the
|
|
921
|
+
// corresponding MANIFEST update. With the bug, that scenario resulted in an
|
|
922
|
+
// unopenable DB with error "Corruption: Size mismatch: WAL ...".
|
|
923
|
+
Options options = CurrentOptions();
|
|
924
|
+
std::unique_ptr<FaultInjectionTestEnv> fault_env(
|
|
925
|
+
new FaultInjectionTestEnv(env_));
|
|
926
|
+
options.env = fault_env.get();
|
|
927
|
+
options.track_and_verify_wals_in_manifest = true;
|
|
928
|
+
Reopen(options);
|
|
929
|
+
|
|
930
|
+
ASSERT_OK(Put("key1", "val1"));
|
|
931
|
+
|
|
932
|
+
SyncPoint::GetInstance()->SetCallBack(
|
|
933
|
+
"DBImpl::SyncWAL:BeforeMarkLogsSynced:1",
|
|
934
|
+
[this](void* /* arg */) { ASSERT_OK(Put("key2", "val2")); });
|
|
935
|
+
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
|
|
936
|
+
|
|
937
|
+
std::unique_ptr<Checkpoint> checkpoint;
|
|
938
|
+
{
|
|
939
|
+
Checkpoint* checkpoint_ptr;
|
|
940
|
+
ASSERT_OK(Checkpoint::Create(db_, &checkpoint_ptr));
|
|
941
|
+
checkpoint.reset(checkpoint_ptr);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
ASSERT_OK(checkpoint->CreateCheckpoint(snapshot_name_));
|
|
945
|
+
|
|
946
|
+
// Ensure callback ran.
|
|
947
|
+
ASSERT_EQ("val2", Get("key2"));
|
|
948
|
+
|
|
949
|
+
Close();
|
|
950
|
+
|
|
951
|
+
// Simulate full loss of unsynced data. This drops "key2" -> "val2" from the
|
|
952
|
+
// DB WAL.
|
|
953
|
+
fault_env->DropUnsyncedFileData();
|
|
954
|
+
|
|
955
|
+
// Before the bug fix, reopening the DB would fail because the MANIFEST's
|
|
956
|
+
// AddWal entry indicated the WAL should be synced through "key2" -> "val2".
|
|
957
|
+
Reopen(options);
|
|
958
|
+
|
|
959
|
+
// Need to close before `fault_env` goes out of scope.
|
|
960
|
+
Close();
|
|
961
|
+
}
|
|
962
|
+
|
|
918
963
|
} // namespace ROCKSDB_NAMESPACE
|
|
919
964
|
|
|
920
965
|
int main(int argc, char** argv) {
|