Fix bugs in FilePickerMultiGet (#5292)
Summary: This PR fixes a couple of bugs in FilePickerMultiGet that were causing db_stress test failures. The failures were caused by - 1. Improper handling of a key that matches the user key portion of an L0 file's largest key. In this case, the curr_index_in_curr_level file index in L0 for that key was getting incremented, but batch_iter_ was not advanced. By design, all keys in a batch are supposed to be checked against an L0 file before advancing to the next L0 file. Not advancing to the next key in the batch was causing a double increment of curr_index_in_curr_level due to the same key being processed again 2. Improper handling of a key that matches the user key portion of the largest key in the last file of L1 and higher. This was resulting in a premature end to the processing of the batch for that level when the next key in the batch is a duplicate. Typically, the keys in MultiGet will not be duplicates, but its good to handle that case correctly Test - asan_crash make check Pull Request resolved: https://github.com/facebook/rocksdb/pull/5292 Differential Revision: D15282530 Pulled By: anand1976 fbshipit-source-id: d1a6a86e0af273169c3632db22a44d79c66a581f
This commit is contained in:
parent
25d81e4577
commit
181bb43f08
@ -416,6 +416,18 @@ class FilePickerMultiGet {
|
|||||||
bool file_hit = false;
|
bool file_hit = false;
|
||||||
int cmp_largest = -1;
|
int cmp_largest = -1;
|
||||||
if (curr_file_index >= curr_file_level_->num_files) {
|
if (curr_file_index >= curr_file_level_->num_files) {
|
||||||
|
// In the unlikely case the next key is a duplicate of the current key,
|
||||||
|
// and the current key is the last in the level and the internal key
|
||||||
|
// was not found, we need to skip lookup for the remaining keys and
|
||||||
|
// reset the search bounds
|
||||||
|
if (batch_iter_ != current_level_range_.end()) {
|
||||||
|
++batch_iter_;
|
||||||
|
for (; batch_iter_ != current_level_range_.end(); ++batch_iter_) {
|
||||||
|
struct FilePickerContext& fp_ctx = fp_ctx_array_[batch_iter_.index()];
|
||||||
|
fp_ctx.search_left_bound = 0;
|
||||||
|
fp_ctx.search_right_bound = FileIndexer::kLevelMaxIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Loops over keys in the MultiGet batch until it finds a file with
|
// Loops over keys in the MultiGet batch until it finds a file with
|
||||||
@ -533,7 +545,10 @@ class FilePickerMultiGet {
|
|||||||
// any further for that key, so advance batch_iter_. Else, keep
|
// any further for that key, so advance batch_iter_. Else, keep
|
||||||
// batch_iter_ positioned on that key so we look it up again in
|
// batch_iter_ positioned on that key so we look it up again in
|
||||||
// the next file
|
// the next file
|
||||||
if (current_level_range_.CheckKeyDone(batch_iter_)) {
|
// For L0, always advance the key because we will look in the next
|
||||||
|
// file regardless for all keys not found yet
|
||||||
|
if (current_level_range_.CheckKeyDone(batch_iter_) ||
|
||||||
|
curr_level_ == 0) {
|
||||||
++batch_iter_;
|
++batch_iter_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -601,7 +616,8 @@ class FilePickerMultiGet {
|
|||||||
unsigned int start_index_in_curr_level;
|
unsigned int start_index_in_curr_level;
|
||||||
|
|
||||||
FilePickerContext(int32_t left, int32_t right)
|
FilePickerContext(int32_t left, int32_t right)
|
||||||
: search_left_bound(left), search_right_bound(right) {}
|
: search_left_bound(left), search_right_bound(right),
|
||||||
|
curr_index_in_curr_level(0), start_index_in_curr_level(0) {}
|
||||||
|
|
||||||
FilePickerContext() = default;
|
FilePickerContext() = default;
|
||||||
};
|
};
|
||||||
|
@ -65,7 +65,7 @@ default_params = {
|
|||||||
"writepercent": 35,
|
"writepercent": 35,
|
||||||
"format_version": lambda: random.randint(2, 4),
|
"format_version": lambda: random.randint(2, 4),
|
||||||
"index_block_restart_interval": lambda: random.choice(range(1, 16)),
|
"index_block_restart_interval": lambda: random.choice(range(1, 16)),
|
||||||
"use_multiget" : 0,
|
"use_multiget" : lambda: random.randint(0, 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
_TEST_DIR_ENV_VAR = 'TEST_TMPDIR'
|
_TEST_DIR_ENV_VAR = 'TEST_TMPDIR'
|
||||||
|
Loading…
Reference in New Issue
Block a user