Fix blob context when db_iter uses seek (#6051)

Summary:
Fix: when `db_iter` falls back to using seek by `FindValueForCurrentKeyUsingSeek`, `is_blob_` flag is not properly set on encountering BlobIndex.
Also patch existing test for the mentioned code path.
Signed-off-by: tabokie <xy.tao@outlook.com>
Pull Request resolved: https://github.com/facebook/rocksdb/pull/6051

Differential Revision: D18596274

Pulled By: ltamasi

fbshipit-source-id: 8e4714af263b99dc2c379707d50db88fe6799278
This commit is contained in:
tabokie 2019-11-19 11:37:24 -08:00 committed by Facebook Github Bot
parent 38cc611297
commit 20b48c6478
3 changed files with 23 additions and 0 deletions

View file

@ -21,6 +21,7 @@
* Fix a assertion failure in MultiGe4t() when BlockBasedTableOptions::no_block_cache is true and there is no compressed block cache * Fix a assertion failure in MultiGe4t() when BlockBasedTableOptions::no_block_cache is true and there is no compressed block cache
* If a call to BackupEngine::PurgeOldBackups or BackupEngine::DeleteBackup suffered a crash, power failure, or I/O error, files could be left over from old backups that could only be purged with a call to GarbageCollect. Any call to PurgeOldBackups, DeleteBackup, or GarbageCollect should now suffice to purge such files. * If a call to BackupEngine::PurgeOldBackups or BackupEngine::DeleteBackup suffered a crash, power failure, or I/O error, files could be left over from old backups that could only be purged with a call to GarbageCollect. Any call to PurgeOldBackups, DeleteBackup, or GarbageCollect should now suffice to purge such files.
* Fix a buffer overrun problem in BlockBasedTable::MultiGet() when compression is enabled and no compressed block cache is configured. * Fix a buffer overrun problem in BlockBasedTable::MultiGet() when compression is enabled and no compressed block cache is configured.
* Fix a bug in DBIter that is_blob_ state isn't updated when iterating backward using seek.
## 6.5.1 (10/16/2019) ## 6.5.1 (10/16/2019)
### Bug Fixes ### Bug Fixes

View file

@ -398,6 +398,26 @@ TEST_F(DBBlobIndexTest, Iterate) {
verify(15, Status::kOk, get_value(16, 0), get_value(14, 0), verify(15, Status::kOk, get_value(16, 0), get_value(14, 0),
create_blob_iterator, check_is_blob(false)); create_blob_iterator, check_is_blob(false));
// Iterator with blob support and using seek.
ASSERT_OK(dbfull()->SetOptions(cfh(), {{"max_sequential_skip_in_iterations", "0"}}));
verify(1, Status::kOk, get_value(1, 0), get_value(1, 0),
create_blob_iterator, check_is_blob(true));
verify(3, Status::kOk, get_value(3, 0), get_value(3, 0),
create_blob_iterator, check_is_blob(true));
verify(5, Status::kOk, get_value(5, 0), get_value(5, 0),
create_blob_iterator, check_is_blob(false));
verify(7, Status::kOk, get_value(8, 0), get_value(6, 0),
create_blob_iterator, check_is_blob(false));
verify(9, Status::kOk, get_value(10, 0), get_value(8, 0),
create_blob_iterator, check_is_blob(false));
verify(11, Status::kNotSupported, "", "", create_blob_iterator);
verify(13, Status::kOk,
get_value(13, 2) + "," + get_value(13, 1) + "," + get_value(13, 0),
get_value(13, 2) + "," + get_value(13, 1) + "," + get_value(13, 0),
create_blob_iterator, check_is_blob(false));
verify(15, Status::kOk, get_value(16, 0), get_value(14, 0),
create_blob_iterator, check_is_blob(false));
for (auto* snapshot : snapshots) { for (auto* snapshot : snapshots) {
dbfull()->ReleaseSnapshot(snapshot); dbfull()->ReleaseSnapshot(snapshot);
} }

View file

@ -856,6 +856,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
// In case read_callback presents, the value we seek to may not be visible. // In case read_callback presents, the value we seek to may not be visible.
// Find the next value that's visible. // Find the next value that's visible.
ParsedInternalKey ikey; ParsedInternalKey ikey;
is_blob_ = false;
while (true) { while (true) {
if (!iter_.Valid()) { if (!iter_.Valid()) {
valid_ = false; valid_ = false;
@ -897,6 +898,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
if (ikey.type == kTypeValue || ikey.type == kTypeBlobIndex) { if (ikey.type == kTypeValue || ikey.type == kTypeBlobIndex) {
assert(iter_.iter()->IsValuePinned()); assert(iter_.iter()->IsValuePinned());
pinned_value_ = iter_.value(); pinned_value_ = iter_.value();
is_blob_ = (ikey.type == kTypeBlobIndex);
valid_ = true; valid_ = true;
return true; return true;
} }