Respect ReadOptions::read_tier in prefetching (#12782)

Summary:
a pre-existing flaw revealed by crash test with uncache behavior. Easy fix.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12782

Test Plan: Modified unit test PrefetchTest.Basic (fails without fix)

Reviewed By: hx235

Differential Revision: D58757916

Pulled By: pdillinger

fbshipit-source-id: 23c0240c7cf0cb0b69a372f9531c07af920e09da
This commit is contained in:
Peter Dillinger 2024-06-19 09:53:59 -07:00 committed by Facebook GitHub Bot
parent 1adb935720
commit efba8f5b27
2 changed files with 40 additions and 19 deletions

View File

@ -99,7 +99,10 @@ class PrefetchTest
virtual void SetGenericOptions(Env* env, bool use_direct_io,
Options& options) {
options = CurrentOptions();
anon::OptionsOverride options_override;
// for !disable_io in PrefetchTest.Basic
options_override.full_block_cache = true;
options = CurrentOptions(options_override);
options.write_buffer_size = 1024;
options.create_if_missing = true;
options.compression = kNoCompression;
@ -254,26 +257,38 @@ TEST_P(PrefetchTest, Basic) {
prev_table_open_prefetch_tail_miss);
}
// count the keys
{
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ReadOptions()));
int num_keys = 0;
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
num_keys++;
for (bool disable_io : {false, true}) {
SCOPED_TRACE("disable_io: " + std::to_string(disable_io));
ReadOptions ro;
if (disable_io) {
// When this is set on the second iteration, all blocks should be in
// block cache
ro.read_tier = ReadTier::kBlockCacheTier;
}
// count the keys
{
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ro));
int num_keys = 0;
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
num_keys++;
}
ASSERT_OK(iter->status());
ASSERT_EQ(num_keys, kNumKeys);
}
ASSERT_OK(iter->status());
(void)num_keys;
}
// To verify prefetch during user scan
if (support_prefetch && !use_direct_io) {
ASSERT_TRUE(fs->IsPrefetchCalled());
fs->ClearPrefetchCount();
ASSERT_EQ(0, buff_prefetch_count);
} else {
ASSERT_FALSE(fs->IsPrefetchCalled());
ASSERT_GT(buff_prefetch_count, 0);
buff_prefetch_count = 0;
// To verify prefetch during user scan, when IO allowed
if (disable_io) {
ASSERT_FALSE(fs->IsPrefetchCalled());
ASSERT_EQ(0, buff_prefetch_count);
} else if (support_prefetch && !use_direct_io) {
ASSERT_TRUE(fs->IsPrefetchCalled());
fs->ClearPrefetchCount();
ASSERT_EQ(0, buff_prefetch_count);
} else {
ASSERT_FALSE(fs->IsPrefetchCalled());
ASSERT_GT(buff_prefetch_count, 0);
buff_prefetch_count = 0;
}
}
Close();
}

View File

@ -18,6 +18,12 @@ void BlockPrefetcher::PrefetchIfNeeded(
const bool no_sequential_checking, const ReadOptions& read_options,
const std::function<void(bool, uint64_t&, uint64_t&)>& readaheadsize_cb,
bool is_async_io_prefetch) {
if (read_options.read_tier == ReadTier::kBlockCacheTier) {
// Disable prefetching when IO disallowed. (Note that we haven't allocated
// any buffers yet despite the various tracked settings.)
return;
}
ReadaheadParams readahead_params;
readahead_params.initial_readahead_size = readahead_size;
readahead_params.max_readahead_size = readahead_size;