From ebd5639b6d6e33e14165f318c128272ae54edb46 Mon Sep 17 00:00:00 2001 From: Reid Horuff Date: Mon, 13 Mar 2017 10:24:52 -0700 Subject: [PATCH] Add ability to search for key prefix in sst_dump tool Summary: Add the flag --prefix to the sst_dump tool This flag is similar to, and exclusive from, the --from flag. --prefix=0x00FF will return all rows prefixed with 0x00FF. The --to flag may also be specified and will work as expected. These changes were used to help in debugging the power cycle corruption issue and theses changes were tested by scanning through a udb. Closes https://github.com/facebook/rocksdb/pull/1984 Differential Revision: D4691814 Pulled By: reidHoruff fbshipit-source-id: 027f261 --- db/dbformat.cc | 2 +- tools/ldb_test.py | 2 +- tools/sst_dump_tool.cc | 40 ++++++++++++++++++++++++++++----------- tools/sst_dump_tool_imp.h | 3 ++- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/db/dbformat.cc b/db/dbformat.cc index baa1c9114..cf606a5c3 100644 --- a/db/dbformat.cc +++ b/db/dbformat.cc @@ -55,7 +55,7 @@ void AppendInternalKeyFooter(std::string* result, SequenceNumber s, std::string ParsedInternalKey::DebugString(bool hex) const { char buf[50]; - snprintf(buf, sizeof(buf), "' @ %" PRIu64 ": %d", sequence, + snprintf(buf, sizeof(buf), "' seq:%" PRIu64 ", type:%d", sequence, static_cast(type)); std::string result = "'"; result += user_key.ToString(hex); diff --git a/tools/ldb_test.py b/tools/ldb_test.py index f4899587d..bbcdc18e1 100644 --- a/tools/ldb_test.py +++ b/tools/ldb_test.py @@ -426,7 +426,7 @@ class LDBTestCase(unittest.TestCase): # Pattern to expect from manifest_dump. num = "[0-9]+" st = ".*" - subpat = st + " @ " + num + ": " + num + subpat = st + " seq:" + num + ", type:" + num regex = num + ":" + num + "\[" + subpat + ".." + subpat + "\]" expected_pattern = re.compile(regex) cmd = "manifest_dump --db=%s" diff --git a/tools/sst_dump_tool.cc b/tools/sst_dump_tool.cc index cd5564fed..eea61af95 100644 --- a/tools/sst_dump_tool.cc +++ b/tools/sst_dump_tool.cc @@ -280,12 +280,10 @@ Status SstFileReader::SetOldTableOptions() { return Status::OK(); } -Status SstFileReader::ReadSequential(bool print_kv, - uint64_t read_num, - bool has_from, - const std::string& from_key, - bool has_to, - const std::string& to_key) { +Status SstFileReader::ReadSequential(bool print_kv, uint64_t read_num, + bool has_from, const std::string& from_key, + bool has_to, const std::string& to_key, + bool use_from_as_prefix) { if (!table_reader_) { return init_result_; } @@ -315,6 +313,11 @@ Status SstFileReader::ReadSequential(bool print_kv, continue; } + // the key returned is not prefixed with out 'from' key + if (use_from_as_prefix && !ikey.user_key.starts_with(from_key)) { + break; + } + // If end marker was specified, we stop before it if (has_to && BytewiseComparator()->Compare(ikey.user_key, to_key) >= 0) { break; @@ -366,6 +369,10 @@ void print_help() { --to= Key to stop reading at when executing check|scan + --prefix= + Returns all keys with this prefix when executing check|scan + Cannot be used in conjunction with --from + --read_num= Maximum number of entries to read when executing check|scan @@ -406,6 +413,7 @@ int SSTDumpTool::Run(int argc, char** argv) { bool input_key_hex = false; bool has_from = false; bool has_to = false; + bool use_from_as_prefix = false; bool show_properties = false; bool show_compression_sizes = false; bool show_summary = false; @@ -440,6 +448,9 @@ int SSTDumpTool::Run(int argc, char** argv) { } else if (strncmp(argv[i], "--to=", 5) == 0) { to_key = argv[i] + 5; has_to = true; + } else if (strncmp(argv[i], "--prefix=", 9) == 0) { + from_key = argv[i] + 9; + use_from_as_prefix = true; } else if (strcmp(argv[i], "--show_properties") == 0) { show_properties = true; } else if (strcmp(argv[i], "--show_compression_sizes") == 0) { @@ -476,13 +487,19 @@ int SSTDumpTool::Run(int argc, char** argv) { fprintf(stdout, "key=%s\n", ikey.DebugString(true).c_str()); return retc; } else { + fprintf(stderr, "Unrecognized argument '%s'\n\n", argv[i]); print_help(); exit(1); } } + if (use_from_as_prefix && has_from) { + fprintf(stderr, "Cannot specify --prefix and --from\n\n"); + exit(1); + } + if (input_key_hex) { - if (has_from) { + if (has_from || use_from_as_prefix) { from_key = rocksdb::LDBCommand::HexToString(from_key); } if (has_to) { @@ -491,6 +508,7 @@ int SSTDumpTool::Run(int argc, char** argv) { } if (dir_or_file == nullptr) { + fprintf(stderr, "file or directory must be specified.\n\n"); print_help(); exit(1); } @@ -554,10 +572,10 @@ int SSTDumpTool::Run(int argc, char** argv) { // scan all files in give file path. if (command == "" || command == "scan" || command == "check") { - st = reader.ReadSequential(command == "scan", - read_num > 0 ? (read_num - total_read) : - read_num, - has_from, from_key, has_to, to_key); + st = reader.ReadSequential( + command == "scan", read_num > 0 ? (read_num - total_read) : read_num, + has_from || use_from_as_prefix, from_key, has_to, to_key, + use_from_as_prefix); if (!st.ok()) { fprintf(stderr, "%s: %s\n", filename.c_str(), st.ToString().c_str()); diff --git a/tools/sst_dump_tool_imp.h b/tools/sst_dump_tool_imp.h index 0ec8a7fc7..f0ef04a80 100644 --- a/tools/sst_dump_tool_imp.h +++ b/tools/sst_dump_tool_imp.h @@ -22,7 +22,8 @@ class SstFileReader { Status ReadSequential(bool print_kv, uint64_t read_num, bool has_from, const std::string& from_key, bool has_to, - const std::string& to_key); + const std::string& to_key, + bool use_from_as_prefix = false); Status ReadTableProperties( std::shared_ptr* table_properties);