Init compression dict handle before reading meta-blocks (#5267)

Summary:
At least one of the meta-block loading functions (`ReadRangeDelBlock`)
uses the same block reading function (`NewDataBlockIterator`) as data
block reads, which means it uses the dictionary handle. However, the
dictionary handle was uninitialized while reading meta-blocks, causing
readers to receive an error. This situation was only noticed when
`cache_index_and_filter_blocks=true`.

This PR initializes the handle to null while reading meta-blocks to
prevent the error. It also adds support to `db_stress` /
`db_crashtest.py` for `cache_index_and_filter_blocks`.

Fixes #5263.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/5267

Differential Revision: D15149264

Pulled By: maysamyabandeh

fbshipit-source-id: 991d38a306c62db5976778bfb050fa3cd4a0671b
This commit is contained in:
Andrew Kryczka 2019-04-30 09:46:40 -07:00 committed by Facebook Github Bot
parent 25810ca9c7
commit b02d0c238d
3 changed files with 11 additions and 0 deletions

View File

@ -838,6 +838,11 @@ Status BlockBasedTable::Open(const ImmutableCFOptions& ioptions,
rep->persistent_cache_key_prefix_size), rep->persistent_cache_key_prefix_size),
rep->ioptions.statistics); rep->ioptions.statistics);
// Meta-blocks are not dictionary compressed. Explicitly set the dictionary
// handle to null, otherwise it may be seen as uninitialized during the below
// meta-block reads.
rep->compression_dict_handle = BlockHandle::NullBlockHandle();
// Read metaindex // Read metaindex
std::unique_ptr<Block> meta; std::unique_ptr<Block> meta;
std::unique_ptr<InternalIterator> meta_iter; std::unique_ptr<InternalIterator> meta_iter;

View File

@ -25,6 +25,7 @@ expected_values_file = tempfile.NamedTemporaryFile()
default_params = { default_params = {
"acquire_snapshot_one_in": 10000, "acquire_snapshot_one_in": 10000,
"block_size": 16384, "block_size": 16384,
"cache_index_and_filter_blocks": lambda: random.randint(0, 1),
"cache_size": 1048576, "cache_size": 1048576,
"checkpoint_one_in": 1000000, "checkpoint_one_in": 1000000,
"compression_type": "snappy", "compression_type": "snappy",

View File

@ -297,6 +297,9 @@ DEFINE_int32(set_in_place_one_in, 0,
DEFINE_int64(cache_size, 2LL * KB * KB * KB, DEFINE_int64(cache_size, 2LL * KB * KB * KB,
"Number of bytes to use as a cache of uncompressed data."); "Number of bytes to use as a cache of uncompressed data.");
DEFINE_bool(cache_index_and_filter_blocks, false,
"True if indexes/filters should be cached in block cache.");
DEFINE_bool(use_clock_cache, false, DEFINE_bool(use_clock_cache, false,
"Replace default LRU block cache with clock cache."); "Replace default LRU block cache with clock cache.");
@ -2578,6 +2581,8 @@ class StressTest {
if (FLAGS_options_file.empty()) { if (FLAGS_options_file.empty()) {
BlockBasedTableOptions block_based_options; BlockBasedTableOptions block_based_options;
block_based_options.block_cache = cache_; block_based_options.block_cache = cache_;
block_based_options.cache_index_and_filter_blocks =
FLAGS_cache_index_and_filter_blocks;
block_based_options.block_cache_compressed = compressed_cache_; block_based_options.block_cache_compressed = compressed_cache_;
block_based_options.checksum = FLAGS_checksum_type_e; block_based_options.checksum = FLAGS_checksum_type_e;
block_based_options.block_size = FLAGS_block_size; block_based_options.block_size = FLAGS_block_size;