Skip to content

Commit d9f4875

Browse files
author
krad
committed
Disable pre-fetching of index and filter blocks for sst_dump_tool.
Summary: BlockBasedTable pre-fetches the filter and index blocks on Open call. This is an optimistic optimization targeted for runtime scenario. The optimization is unnecessary for sst_dump_tool - Added a provision to disable pre-fetching of index and filter blocks in BlockBasedTable - Disabled pre-fetching for the sst_dump tool Stack for reference : #1 0x00000000005ed944 in snappy::InternalUncompress<snappy::SnappyArrayWriter> () from /home/engshare/third-party2/snappy/1.0.3/src/snappy-1.0.3/snappy.cc:148 #2 0x00000000005edeee in snappy::RawUncompress () from /home/engshare/third-party2/snappy/1.0.3/src/snappy-1.0.3/snappy.cc:947 #3 0x00000000004e0b4d in rocksdb::UncompressBlockContents () from /data/users/paultuckfield/rocksdb/./util/compression.h:69 #4 0x00000000004e145c in rocksdb::ReadBlockContents () from /data/users/paultuckfield/rocksdb/table/format.cc:334 #5 0x00000000004ca424 in rocksdb::(anonymous namespace)::ReadBlockFromFile () from /data/users/paultuckfield/rocksdb/table/block_based_table_reader.cc:70 #6 0x00000000004cccad in rocksdb::BlockBasedTable::CreateIndexReader () from /data/users/paultuckfield/rocksdb/table/block_based_table_reader.cc:173 #7 0x00000000004d17e5 in rocksdb::BlockBasedTable::Open () from /data/users/paultuckfield/rocksdb/table/block_based_table_reader.cc:553 #8 0x00000000004c8184 in rocksdb::BlockBasedTableFactory::NewTableReader () from /data/users/paultuckfield/rocksdb/table/block_based_table_factory.cc:51 #9 0x0000000000598463 in rocksdb::SstFileReader::NewTableReader () from /data/users/paultuckfield/rocksdb/util/sst_dump_tool.cc:69 #10 0x00000000005986c2 in rocksdb::SstFileReader::SstFileReader () from /data/users/paultuckfield/rocksdb/util/sst_dump_tool.cc:26 #11 0x0000000000599047 in rocksdb::SSTDumpTool::Run () from /data/users/paultuckfield/rocksdb/util/sst_dump_tool.cc:332 #12 0x0000000000409b06 in main () from /data/users/paultuckfield/rocksdb/tools/sst_dump.cc:12 Test Plan: - Added a unit test to trigger the code. - Also did some manual verification. - Passed all unit tests task #6296048 Reviewers: igor, rven, sdong Reviewed By: sdong Subscribers: dhruba, leveldb Differential Revision: https://reviews.facebook.net/D34041
1 parent 182b4ce commit d9f4875

7 files changed

+116
-39
lines changed

table/block_based_table_factory.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ Status BlockBasedTableFactory::NewTableReader(
4545
const ImmutableCFOptions& ioptions, const EnvOptions& soptions,
4646
const InternalKeyComparator& internal_comparator,
4747
unique_ptr<RandomAccessFile>&& file, uint64_t file_size,
48-
unique_ptr<TableReader>* table_reader) const {
48+
unique_ptr<TableReader>* table_reader, const bool prefetch_enabled) const {
4949
return BlockBasedTable::Open(ioptions, soptions, table_options_,
5050
internal_comparator, std::move(file), file_size,
51-
table_reader);
51+
table_reader, prefetch_enabled);
5252
}
5353

5454
TableBuilder* BlockBasedTableFactory::NewTableBuilder(

table/block_based_table_factory.h

+18-5
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,24 @@ class BlockBasedTableFactory : public TableFactory {
3333

3434
const char* Name() const override { return "BlockBasedTable"; }
3535

36-
Status NewTableReader(
37-
const ImmutableCFOptions& ioptions, const EnvOptions& soptions,
38-
const InternalKeyComparator& internal_comparator,
39-
unique_ptr<RandomAccessFile>&& file, uint64_t file_size,
40-
unique_ptr<TableReader>* table_reader) const override;
36+
Status NewTableReader(const ImmutableCFOptions& ioptions,
37+
const EnvOptions& soptions,
38+
const InternalKeyComparator& internal_comparator,
39+
unique_ptr<RandomAccessFile>&& file, uint64_t file_size,
40+
unique_ptr<TableReader>* table_reader) const override {
41+
return NewTableReader(ioptions, soptions, internal_comparator,
42+
std::move(file), file_size, table_reader,
43+
/*prefetch_index_and_filter=*/true);
44+
}
45+
46+
// This is a variant of virtual member function NewTableReader function with
47+
// added capability to disable pre-fetching of blocks on BlockBasedTable::Open
48+
Status NewTableReader(const ImmutableCFOptions& ioptions,
49+
const EnvOptions& soptions,
50+
const InternalKeyComparator& internal_comparator,
51+
unique_ptr<RandomAccessFile>&& file, uint64_t file_size,
52+
unique_ptr<TableReader>* table_reader,
53+
bool prefetch_index_and_filter) const;
4154

4255
TableBuilder* NewTableBuilder(
4356
const ImmutableCFOptions& ioptions,

table/block_based_table_reader.cc

+30-25
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,8 @@ Status BlockBasedTable::Open(const ImmutableCFOptions& ioptions,
463463
const InternalKeyComparator& internal_comparator,
464464
unique_ptr<RandomAccessFile>&& file,
465465
uint64_t file_size,
466-
unique_ptr<TableReader>* table_reader) {
466+
unique_ptr<TableReader>* table_reader,
467+
const bool prefetch_index_and_filter) {
467468
table_reader->reset();
468469

469470
Footer footer;
@@ -537,34 +538,38 @@ Status BlockBasedTable::Open(const ImmutableCFOptions& ioptions,
537538
BlockBasedTablePropertyNames::kPrefixFiltering, rep->ioptions.info_log);
538539
}
539540

540-
// Will use block cache for index/filter blocks access?
541-
if (table_options.cache_index_and_filter_blocks) {
542-
assert(table_options.block_cache != nullptr);
543-
// Hack: Call NewIndexIterator() to implicitly add index to the block_cache
544-
unique_ptr<Iterator> iter(new_table->NewIndexIterator(ReadOptions()));
545-
s = iter->status();
541+
if (prefetch_index_and_filter) {
542+
// pre-fetching of blocks is turned on
543+
// Will use block cache for index/filter blocks access?
544+
if (table_options.cache_index_and_filter_blocks) {
545+
assert(table_options.block_cache != nullptr);
546+
// Hack: Call NewIndexIterator() to implicitly add index to the
547+
// block_cache
548+
unique_ptr<Iterator> iter(new_table->NewIndexIterator(ReadOptions()));
549+
s = iter->status();
546550

547-
if (s.ok()) {
548-
// Hack: Call GetFilter() to implicitly add filter to the block_cache
549-
auto filter_entry = new_table->GetFilter();
550-
filter_entry.Release(table_options.block_cache.get());
551-
}
552-
} else {
553-
// If we don't use block cache for index/filter blocks access, we'll
554-
// pre-load these blocks, which will kept in member variables in Rep
555-
// and with a same life-time as this table object.
556-
IndexReader* index_reader = nullptr;
557-
s = new_table->CreateIndexReader(&index_reader, meta_iter.get());
551+
if (s.ok()) {
552+
// Hack: Call GetFilter() to implicitly add filter to the block_cache
553+
auto filter_entry = new_table->GetFilter();
554+
filter_entry.Release(table_options.block_cache.get());
555+
}
556+
} else {
557+
// If we don't use block cache for index/filter blocks access, we'll
558+
// pre-load these blocks, which will kept in member variables in Rep
559+
// and with a same life-time as this table object.
560+
IndexReader* index_reader = nullptr;
561+
s = new_table->CreateIndexReader(&index_reader, meta_iter.get());
558562

559-
if (s.ok()) {
560-
rep->index_reader.reset(index_reader);
563+
if (s.ok()) {
564+
rep->index_reader.reset(index_reader);
561565

562-
// Set filter block
563-
if (rep->filter_policy) {
564-
rep->filter.reset(ReadFilter(rep, meta_iter.get(), nullptr));
566+
// Set filter block
567+
if (rep->filter_policy) {
568+
rep->filter.reset(ReadFilter(rep, meta_iter.get(), nullptr));
569+
}
570+
} else {
571+
delete index_reader;
565572
}
566-
} else {
567-
delete index_reader;
568573
}
569574
}
570575

table/block_based_table_reader.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,15 @@ class BlockBasedTable : public TableReader {
6363
// to nullptr and returns a non-ok status.
6464
//
6565
// *file must remain live while this Table is in use.
66+
// *prefetch_blocks can be used to disable prefetching of index and filter
67+
// blocks at statup
6668
static Status Open(const ImmutableCFOptions& ioptions,
6769
const EnvOptions& env_options,
6870
const BlockBasedTableOptions& table_options,
6971
const InternalKeyComparator& internal_key_comparator,
7072
unique_ptr<RandomAccessFile>&& file, uint64_t file_size,
71-
unique_ptr<TableReader>* table_reader);
73+
unique_ptr<TableReader>* table_reader,
74+
bool prefetch_index_and_filter = true);
7275

7376
bool PrefixMayMatch(const Slice& internal_key);
7477

util/sst_dump_test.cc

+22
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,28 @@ TEST(SSTDumpToolTest, FullFilterBlock) {
147147
delete[] usage[i];
148148
}
149149
}
150+
151+
TEST(SSTDumpToolTest, GetProperties) {
152+
table_options_.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));
153+
std::string file_name = "rocksdb_sst_test.sst";
154+
createSST(file_name, table_options_);
155+
156+
char* usage[3];
157+
for (int i = 0; i < 3; i++) {
158+
usage[i] = new char[optLength];
159+
}
160+
snprintf(usage[0], optLength, "./sst_dump");
161+
snprintf(usage[1], optLength, "--show_properties");
162+
snprintf(usage[2], optLength, "--file=rocksdb_sst_test.sst");
163+
164+
rocksdb::SSTDumpTool tool;
165+
ASSERT_TRUE(!tool.Run(3, usage));
166+
167+
cleanup(file_name);
168+
for (int i = 0; i < 3; i++) {
169+
delete[] usage[i];
170+
}
171+
}
150172
} // namespace rocksdb
151173

152174
int main(int argc, char** argv) { return rocksdb::test::RunAllTests(); }

util/sst_dump_tool.cc

+30-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
namespace rocksdb {
1717

18+
using std::dynamic_pointer_cast;
19+
1820
SstFileReader::SstFileReader(const std::string& file_path,
1921
bool verify_checksum,
2022
bool output_hex)
@@ -23,15 +25,15 @@ SstFileReader::SstFileReader(const std::string& file_path,
2325
internal_comparator_(BytewiseComparator()) {
2426
fprintf(stdout, "Process %s\n", file_path.c_str());
2527

26-
init_result_ = NewTableReader(file_name_);
28+
init_result_ = GetTableReader(file_name_);
2729
}
2830

2931
extern const uint64_t kBlockBasedTableMagicNumber;
3032
extern const uint64_t kLegacyBlockBasedTableMagicNumber;
3133
extern const uint64_t kPlainTableMagicNumber;
3234
extern const uint64_t kLegacyPlainTableMagicNumber;
3335

34-
Status SstFileReader::NewTableReader(const std::string& file_path) {
36+
Status SstFileReader::GetTableReader(const std::string& file_path) {
3537
uint64_t magic_number;
3638

3739
// read table magic number
@@ -66,13 +68,36 @@ Status SstFileReader::NewTableReader(const std::string& file_path) {
6668
}
6769

6870
if (s.ok()) {
69-
s = options_.table_factory->NewTableReader(
70-
ioptions_, soptions_, internal_comparator_, std::move(file_), file_size,
71-
&table_reader_);
71+
s = NewTableReader(ioptions_, soptions_, internal_comparator_,
72+
std::move(file_), file_size, &table_reader_);
7273
}
7374
return s;
7475
}
7576

77+
Status SstFileReader::NewTableReader(
78+
const ImmutableCFOptions& ioptions, const EnvOptions& soptions,
79+
const InternalKeyComparator& internal_comparator,
80+
unique_ptr<RandomAccessFile>&& file, uint64_t file_size,
81+
unique_ptr<TableReader>* table_reader) {
82+
// We need to turn off pre-fetching of index and filter nodes for
83+
// BlockBasedTable
84+
shared_ptr<BlockBasedTableFactory> block_table_factory =
85+
dynamic_pointer_cast<BlockBasedTableFactory>(options_.table_factory);
86+
87+
if (block_table_factory) {
88+
return block_table_factory->NewTableReader(
89+
ioptions_, soptions_, internal_comparator_, std::move(file_), file_size,
90+
&table_reader_, /*enable_prefetch=*/false);
91+
}
92+
93+
assert(!block_table_factory);
94+
95+
// For all other factory implementation
96+
return options_.table_factory->NewTableReader(
97+
ioptions_, soptions_, internal_comparator_, std::move(file_), file_size,
98+
&table_reader_);
99+
}
100+
76101
Status SstFileReader::DumpTable(const std::string& out_filename) {
77102
unique_ptr<WritableFile> out_file;
78103
Env* env = Env::Default();

util/sst_dump_tool_imp.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,21 @@ class SstFileReader {
5353
Status getStatus() { return init_result_; }
5454

5555
private:
56-
Status NewTableReader(const std::string& file_path);
56+
// Get the TableReader implementation for the sst file
57+
Status GetTableReader(const std::string& file_path);
5758
Status ReadTableProperties(uint64_t table_magic_number,
5859
RandomAccessFile* file, uint64_t file_size);
5960
Status SetTableOptionsByMagicNumber(uint64_t table_magic_number);
6061
Status SetOldTableOptions();
6162

63+
// Helper function to call the factory with settings specific to the
64+
// factory implementation
65+
Status NewTableReader(const ImmutableCFOptions& ioptions,
66+
const EnvOptions& soptions,
67+
const InternalKeyComparator& internal_comparator,
68+
unique_ptr<RandomAccessFile>&& file, uint64_t file_size,
69+
unique_ptr<TableReader>* table_reader);
70+
6271
std::string file_name_;
6372
uint64_t read_num_;
6473
bool verify_checksum_;

0 commit comments

Comments
 (0)