From 20b48c64788ab54a9529ad5b23c520e4a4f42bec Mon Sep 17 00:00:00 2001 From: tabokie Date: Tue, 19 Nov 2019 11:37:24 -0800 Subject: [PATCH] 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 Pull Request resolved: https://github.com/facebook/rocksdb/pull/6051 Differential Revision: D18596274 Pulled By: ltamasi fbshipit-source-id: 8e4714af263b99dc2c379707d50db88fe6799278 --- HISTORY.md | 1 + db/db_blob_index_test.cc | 20 ++++++++++++++++++++ db/db_iter.cc | 2 ++ 3 files changed, 23 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index ac96d92a7..c05f98dec 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -21,6 +21,7 @@ * 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. * 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) ### Bug Fixes diff --git a/db/db_blob_index_test.cc b/db/db_blob_index_test.cc index 0cdc93dde..b7a048dd4 100644 --- a/db/db_blob_index_test.cc +++ b/db/db_blob_index_test.cc @@ -398,6 +398,26 @@ TEST_F(DBBlobIndexTest, Iterate) { verify(15, Status::kOk, get_value(16, 0), get_value(14, 0), 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) { dbfull()->ReleaseSnapshot(snapshot); } diff --git a/db/db_iter.cc b/db/db_iter.cc index df7e1b450..b2675c520 100644 --- a/db/db_iter.cc +++ b/db/db_iter.cc @@ -856,6 +856,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() { // In case read_callback presents, the value we seek to may not be visible. // Find the next value that's visible. ParsedInternalKey ikey; + is_blob_ = false; while (true) { if (!iter_.Valid()) { valid_ = false; @@ -897,6 +898,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() { if (ikey.type == kTypeValue || ikey.type == kTypeBlobIndex) { assert(iter_.iter()->IsValuePinned()); pinned_value_ = iter_.value(); + is_blob_ = (ikey.type == kTypeBlobIndex); valid_ = true; return true; }