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
main
Reid Horuff 8 years ago committed by Facebook Github Bot
parent e6725e8c8d
commit ebd5639b6d
  1. 2
      db/dbformat.cc
  2. 2
      tools/ldb_test.py
  3. 40
      tools/sst_dump_tool.cc
  4. 3
      tools/sst_dump_tool_imp.h

@ -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<int>(type));
std::string result = "'";
result += user_key.ToString(hex);

@ -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"

@ -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=<user_key>
Key to stop reading at when executing check|scan
--prefix=<user_key>
Returns all keys with this prefix when executing check|scan
Cannot be used in conjunction with --from
--read_num=<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());

@ -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<const TableProperties>* table_properties);

Loading…
Cancel
Save