Skip to content

Commit 772e342

Browse files
anand1976facebook-github-bot
authored andcommitted
Add an option to sst_dump to list all metadata blocks (facebook#13838)
Summary: Add the --list_meta_blocks option to sst_dump. This PR also refactors some of the test code in sst_dump_test. Pull Request resolved: facebook#13838 Reviewed By: cbi42 Differential Revision: D80320812 Pulled By: anand1976 fbshipit-source-id: 921b6560fbd756f5f8b364893700d240d3b7ad00
1 parent b3fdb9b commit 772e342

4 files changed

Lines changed: 93 additions & 127 deletions

File tree

table/sst_file_dumper.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ Status SstFileDumper::GetTableReader(const std::string& file_path) {
158158
s = SetOldTableOptions();
159159
}
160160
options_.comparator = internal_comparator_.user_comparator();
161+
162+
{
163+
Status status = ReadMetaIndexBlockInFile(
164+
file_.get(), file_size, magic_number, ImmutableOptions(options_),
165+
ReadOptions(), &meta_index_contents_);
166+
// Ignore any errors since this is required for a specific CLI option
167+
status.PermitUncheckedError();
168+
}
161169
}
162170

163171
if (s.ok()) {

table/sst_file_dumper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class SstFileDumper {
5151
Status ShowCompressionSize(size_t block_size, CompressionType compress_type,
5252
const CompressionOptions& compress_opt);
5353

54+
BlockContents& GetMetaIndexContents() { return meta_index_contents_; }
55+
5456
private:
5557
// Get the TableReader implementation for the sst file
5658
Status GetTableReader(const std::string& file_path);
@@ -96,6 +98,7 @@ class SstFileDumper {
9698
ReadOptions read_options_;
9799
InternalKeyComparator internal_comparator_;
98100
std::unique_ptr<TableProperties> table_properties_;
101+
BlockContents meta_index_contents_;
99102
};
100103

101104
} // namespace ROCKSDB_NAMESPACE

tools/sst_dump_test.cc

Lines changed: 47 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,30 @@ class SSTDumpToolTest : public testing::Test {
175175

176176
protected:
177177
constexpr static int kNumKey = 1024;
178+
179+
void SSTDumpToolTestCase(Options& opts, bool filter, int wide_column_one_in,
180+
const char* cmd_arg) {
181+
opts.env = env();
182+
BlockBasedTableOptions table_opts;
183+
if (filter) {
184+
table_opts.filter_policy.reset(
185+
ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10));
186+
}
187+
opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
188+
std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
189+
createSST(opts, file_path, wide_column_one_in);
190+
191+
char* usage[3];
192+
PopulateCommandArgs(file_path, cmd_arg, usage);
193+
194+
ROCKSDB_NAMESPACE::SSTDumpTool tool;
195+
ASSERT_TRUE(!tool.Run(3, usage, opts));
196+
197+
cleanup(opts, file_path);
198+
for (int i = 0; i < 3; i++) {
199+
delete[] usage[i];
200+
}
201+
}
178202
};
179203

180204

@@ -194,156 +218,52 @@ TEST_F(SSTDumpToolTest, HelpAndVersion) {
194218

195219
TEST_F(SSTDumpToolTest, EmptyFilter) {
196220
Options opts;
197-
opts.env = env();
198-
std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
199-
createSST(opts, file_path, 10);
200-
201-
char* usage[3];
202-
PopulateCommandArgs(file_path, "--command=raw", usage);
203-
204-
ROCKSDB_NAMESPACE::SSTDumpTool tool;
205-
ASSERT_TRUE(!tool.Run(3, usage, opts));
206-
207-
cleanup(opts, file_path);
208-
for (int i = 0; i < 3; i++) {
209-
delete[] usage[i];
210-
}
221+
SSTDumpToolTestCase(opts, /*filter=*/false, /*wide_column_one_in=*/10,
222+
"--command=raw");
211223
}
212224

213225
TEST_F(SSTDumpToolTest, SstDumpReverseBytewiseComparator) {
214226
Options opts;
215-
opts.env = env();
216227
opts.comparator = ReverseBytewiseComparator();
217-
BlockBasedTableOptions table_opts;
218-
table_opts.filter_policy.reset(
219-
ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
220-
opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
221-
std::string file_path =
222-
MakeFilePath("rocksdb_sst_reverse_bytewise_comparator.sst");
223-
createSST(opts, file_path);
224-
225-
char* usage[3];
226-
PopulateCommandArgs(file_path, "--command=raw", usage);
227-
228-
ROCKSDB_NAMESPACE::SSTDumpTool tool;
229-
ASSERT_TRUE(!tool.Run(3, usage, opts));
230-
231-
cleanup(opts, file_path);
232-
for (int i = 0; i < 3; i++) {
233-
delete[] usage[i];
234-
}
228+
SSTDumpToolTestCase(opts, /*filter=*/true, /*wide_column_one_in=*/10,
229+
"--command=raw");
235230
}
236231

237232
TEST_F(SSTDumpToolTest, SstDumpComparatorWithU64Ts) {
238233
Options opts;
239-
opts.env = env();
240234
opts.comparator = test::BytewiseComparatorWithU64TsWrapper();
241-
BlockBasedTableOptions table_opts;
242-
table_opts.filter_policy.reset(
243-
ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
244-
opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
245-
std::string file_path =
246-
MakeFilePath("rocksdb_sst_comparator_with_u64_ts.sst");
247-
createSST(opts, file_path, 10);
248-
249-
char* usage[3];
250-
PopulateCommandArgs(file_path, "--command=raw", usage);
251-
252-
ROCKSDB_NAMESPACE::SSTDumpTool tool;
253-
ASSERT_TRUE(!tool.Run(3, usage, opts));
254-
255-
cleanup(opts, file_path);
256-
for (int i = 0; i < 3; i++) {
257-
delete[] usage[i];
258-
}
235+
SSTDumpToolTestCase(opts, /*filter=*/true, /*wide_column_one_in=*/10,
236+
"--command=raw");
259237
}
260238

261-
TEST_F(SSTDumpToolTest, FilterBlock) {
239+
TEST_F(SSTDumpToolTest, FilterBlockWideColumn) {
262240
Options opts;
263-
opts.env = env();
264-
BlockBasedTableOptions table_opts;
265-
table_opts.filter_policy.reset(
266-
ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, true));
267-
opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
268-
std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
269-
createSST(opts, file_path, 10);
270-
271-
char* usage[3];
272-
PopulateCommandArgs(file_path, "--command=raw", usage);
273-
274-
ROCKSDB_NAMESPACE::SSTDumpTool tool;
275-
ASSERT_TRUE(!tool.Run(3, usage, opts));
276-
277-
cleanup(opts, file_path);
278-
for (int i = 0; i < 3; i++) {
279-
delete[] usage[i];
280-
}
241+
SSTDumpToolTestCase(opts, /*filter=*/true, /*wide_column_one_in=*/10,
242+
"--command=raw");
281243
}
282244

283-
TEST_F(SSTDumpToolTest, FullFilterBlock) {
245+
TEST_F(SSTDumpToolTest, FilterBlock) {
284246
Options opts;
285-
opts.env = env();
286-
BlockBasedTableOptions table_opts;
287-
table_opts.filter_policy.reset(
288-
ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
289-
opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
290-
std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
291-
createSST(opts, file_path);
292-
293-
char* usage[3];
294-
PopulateCommandArgs(file_path, "--command=raw", usage);
295-
296-
ROCKSDB_NAMESPACE::SSTDumpTool tool;
297-
ASSERT_TRUE(!tool.Run(3, usage, opts));
298-
299-
cleanup(opts, file_path);
300-
for (int i = 0; i < 3; i++) {
301-
delete[] usage[i];
302-
}
247+
SSTDumpToolTestCase(opts, /*filter=*/true, /*wide_column_one_in=*/0,
248+
"--command=raw");
303249
}
304250

305251
TEST_F(SSTDumpToolTest, GetProperties) {
306252
Options opts;
307-
opts.env = env();
308-
BlockBasedTableOptions table_opts;
309-
table_opts.filter_policy.reset(
310-
ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
311-
opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
312-
std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
313-
createSST(opts, file_path);
314-
315-
char* usage[3];
316-
PopulateCommandArgs(file_path, "--show_properties", usage);
317-
318-
ROCKSDB_NAMESPACE::SSTDumpTool tool;
319-
ASSERT_TRUE(!tool.Run(3, usage, opts));
320-
321-
cleanup(opts, file_path);
322-
for (int i = 0; i < 3; i++) {
323-
delete[] usage[i];
324-
}
253+
SSTDumpToolTestCase(opts, /*filter=*/true, /*wide_column_one_in=*/0,
254+
"--show_properties");
325255
}
326256

327257
TEST_F(SSTDumpToolTest, CompressedSizes) {
328258
Options opts;
329-
opts.env = env();
330-
BlockBasedTableOptions table_opts;
331-
table_opts.filter_policy.reset(
332-
ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
333-
opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
334-
std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
335-
createSST(opts, file_path, 10);
336-
337-
char* usage[3];
338-
PopulateCommandArgs(file_path, "--command=recompress", usage);
339-
340-
ROCKSDB_NAMESPACE::SSTDumpTool tool;
341-
ASSERT_TRUE(!tool.Run(3, usage, opts));
259+
SSTDumpToolTestCase(opts, /*filter=*/true, /*wide_column_one_in=*/10,
260+
"--command=recompress");
261+
}
342262

343-
cleanup(opts, file_path);
344-
for (int i = 0; i < 3; i++) {
345-
delete[] usage[i];
346-
}
263+
TEST_F(SSTDumpToolTest, ListMetaBlocks) {
264+
Options opts;
265+
SSTDumpToolTestCase(opts, /*filter=*/true, /*wide_column_one_in=*/0,
266+
"--list_meta_blocks");
347267
}
348268

349269
namespace {
@@ -455,8 +375,8 @@ TEST_F(SSTDumpToolTest, ReadaheadSize) {
455375

456376
// The file is approximately 10MB. Readahead is 4MB.
457377
// We usually need 3 reads + one metadata read.
458-
// One extra read is needed before opening the file for metadata.
459-
ASSERT_EQ(5, num_reads);
378+
// Three extra read is needed before opening the file for metadata.
379+
ASSERT_EQ(7, num_reads);
460380

461381
SyncPoint::GetInstance()->ClearAllCallBacks();
462382
SyncPoint::GetInstance()->DisableProcessing();

tools/sst_dump_tool.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "port/port.h"
1515
#include "rocksdb/convenience.h"
1616
#include "rocksdb/utilities/ldb_cmd.h"
17+
#include "table/block_based/block.h"
1718
#include "table/sst_file_dumper.h"
1819

1920
namespace ROCKSDB_NAMESPACE {
@@ -121,6 +122,9 @@ void print_help(bool to_stderr) {
121122
122123
--compression_use_zstd_finalize_dict
123124
Use zstd's finalizeDictionary() API instead of zstd's dictionary trainer to generate dictionary.
125+
126+
--list_meta_blocks
127+
Print the list of all meta blocks in the file
124128
)",
125129
supported_compressions.c_str());
126130
}
@@ -162,6 +166,7 @@ int SSTDumpTool::Run(int argc, char const* const* argv, Options options) {
162166
bool use_from_as_prefix = false;
163167
bool show_properties = false;
164168
bool show_summary = false;
169+
bool list_meta_blocks = false;
165170
bool set_block_size = false;
166171
bool has_compression_level_from = false;
167172
bool has_compression_level_to = false;
@@ -335,6 +340,8 @@ int SSTDumpTool::Run(int argc, char const* const* argv, Options options) {
335340
compression_max_dict_buffer_bytes = static_cast<uint64_t>(tmp_val);
336341
} else if (strcmp(argv[i], "--compression_use_zstd_finalize_dict") == 0) {
337342
compression_use_zstd_finalize_dict = true;
343+
} else if (strcmp(argv[i], "--list_meta_blocks") == 0) {
344+
list_meta_blocks = true;
338345
} else if (strcmp(argv[i], "--help") == 0) {
339346
print_help(/*to_stderr*/ false);
340347
return 0;
@@ -561,7 +568,35 @@ int SSTDumpTool::Run(int argc, char const* const* argv, Options options) {
561568
fprintf(stderr, "Reader unexpectedly returned null properties\n");
562569
}
563570
}
571+
572+
BlockContents& meta_index_contents = dumper.GetMetaIndexContents();
573+
if (list_meta_blocks && meta_index_contents.data.size() > 0) {
574+
Block meta_index_block(std::move(meta_index_contents));
575+
std::unique_ptr<MetaBlockIter> meta_index_iter;
576+
meta_index_iter.reset(meta_index_block.NewMetaIterator());
577+
meta_index_iter->SeekToFirst();
578+
fprintf(stdout,
579+
"Meta Blocks:\n"
580+
"------------------------------\n");
581+
while (meta_index_iter->status().ok() && meta_index_iter->Valid()) {
582+
Slice v = meta_index_iter->value();
583+
BlockHandle handle;
584+
st = handle.DecodeFrom(&v);
585+
if (!st.ok()) {
586+
fprintf(stderr, "%s: Could not decode block handle - %s\n",
587+
filename.c_str(), st.ToString().c_str());
588+
} else {
589+
fprintf(stdout, " %s: %" PRIu64 " %" PRIu64 "\n",
590+
meta_index_iter->key().ToString().c_str(), handle.offset(),
591+
handle.size());
592+
}
593+
meta_index_iter->Next();
594+
}
595+
} else if (list_meta_blocks) {
596+
fprintf(stderr, "Could not read the meta index block\n");
597+
}
564598
}
599+
565600
if (show_summary) {
566601
fprintf(stdout, "total number of files: %" PRIu64 "\n", total_num_files);
567602
fprintf(stdout, "total number of data blocks: %" PRIu64 "\n",

0 commit comments

Comments
 (0)