Skip to content

Commit 02f2cda

Browse files
author
liuxuyang
committed
Add print_all_keys tool
1 parent e830be7 commit 02f2cda

2 files changed

Lines changed: 188 additions & 5 deletions

File tree

tools/CMakeLists.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
set(CORE_TOOLS
22
sst_dump.cc
3-
ldb.cc)
3+
ldb.cc
4+
cf_repairer.cc
5+
sst_corrupt_tool.cc
6+
create_test_db.cc
7+
print_all_keys.cc)
48
foreach(src ${CORE_TOOLS})
59
get_filename_component(exename ${src} NAME_WE)
610
add_executable(${exename}${ARTIFACT_SUFFIX}
@@ -15,10 +19,7 @@ if(WITH_TOOLS)
1519
write_stress.cc
1620
db_repl_stress.cc
1721
dump/rocksdb_dump.cc
18-
dump/rocksdb_undump.cc
19-
sst_corrupt_tool.cc
20-
cf_repairer.cc
21-
create_test_db.cc)
22+
dump/rocksdb_undump.cc)
2223
foreach(src ${TOOLS})
2324
get_filename_component(exename ${src} NAME_WE)
2425
add_executable(${exename}${ARTIFACT_SUFFIX}

tools/print_all_keys.cc

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2+
// This source code is licensed under both the GPLv2 (found in the
3+
// COPYING file in the root directory) and Apache 2.0 License
4+
// (found in the LICENSE.Apache file in the root directory).
5+
6+
#include <iostream>
7+
#include <string>
8+
#include <vector>
9+
10+
#include "rocksdb/db.h"
11+
12+
using namespace ROCKSDB_NAMESPACE;
13+
14+
void PrintUsage() {
15+
std::cerr << "Usage: print_all_keys <db_path> [--hex] "
16+
"[--cf=<column_family_name>] [--skip-corrupted-data-blocks]"
17+
<< std::endl;
18+
std::cerr << " --hex: Print keys and values in hexadecimal format"
19+
<< std::endl;
20+
std::cerr << " --cf=<name>: Specify column family name (default: all column "
21+
"families)"
22+
<< std::endl;
23+
std::cerr << " --skip-corrupted-data-blocks: Skip corrupted data blocks "
24+
"during iteration (for data recovery)"
25+
<< std::endl;
26+
std::cerr << " If no --cf specified, prints from all column families"
27+
<< std::endl;
28+
}
29+
30+
std::string ToHex(const std::string& str) {
31+
std::string result;
32+
for (unsigned char c : str) {
33+
char buf[3];
34+
snprintf(buf, sizeof(buf), "%02x", c);
35+
result += buf;
36+
}
37+
return result;
38+
}
39+
40+
int main(int argc, char* argv[]) {
41+
if (argc < 2) {
42+
PrintUsage();
43+
return 1;
44+
}
45+
46+
std::string db_path = argv[1];
47+
bool use_hex = false;
48+
std::string target_cf = "";
49+
bool specific_cf = false;
50+
bool skip_corrupted_data_blocks = false;
51+
52+
// Parse command line arguments
53+
for (int i = 2; i < argc; i++) {
54+
std::string arg = argv[i];
55+
if (arg == "--hex") {
56+
use_hex = true;
57+
} else if (arg.substr(0, 5) == "--cf=") {
58+
target_cf = arg.substr(5);
59+
specific_cf = true;
60+
} else if (arg == "--skip-corrupted-data-blocks") {
61+
skip_corrupted_data_blocks = true;
62+
} else {
63+
std::cerr << "Unknown option: " << argv[i] << std::endl;
64+
PrintUsage();
65+
return 1;
66+
}
67+
}
68+
69+
// First, list all column families
70+
std::vector<std::string> cf_names;
71+
Status s = DB::ListColumnFamilies(Options(), db_path, &cf_names);
72+
if (!s.ok()) {
73+
std::cerr << "Failed to list column families: " << s.ToString()
74+
<< std::endl;
75+
return 1;
76+
}
77+
78+
std::cout << "Available column families: ";
79+
for (size_t i = 0; i < cf_names.size(); i++) {
80+
std::cout << cf_names[i];
81+
if (i < cf_names.size() - 1) std::cout << ", ";
82+
}
83+
std::cout << std::endl << std::endl;
84+
85+
// If specific CF requested, check if it exists
86+
if (specific_cf) {
87+
bool found = false;
88+
for (const auto& name : cf_names) {
89+
if (name == target_cf) {
90+
found = true;
91+
break;
92+
}
93+
}
94+
if (!found) {
95+
std::cerr << "Column family '" << target_cf << "' not found!"
96+
<< std::endl;
97+
return 1;
98+
}
99+
}
100+
101+
// Prepare column family descriptors
102+
std::vector<ColumnFamilyDescriptor> column_families;
103+
for (const auto& name : cf_names) {
104+
column_families.emplace_back(name, ColumnFamilyOptions());
105+
}
106+
107+
// Open database with all column families
108+
DB* db;
109+
std::vector<ColumnFamilyHandle*> handles;
110+
Options db_options;
111+
112+
s = DB::Open(db_options, db_path, column_families, &handles, &db);
113+
if (!s.ok()) {
114+
std::cerr << "Failed to open database: " << s.ToString() << std::endl;
115+
return 1;
116+
}
117+
118+
uint64_t total_count = 0;
119+
120+
// Iterate through column families
121+
for (size_t i = 0; i < cf_names.size(); i++) {
122+
// Skip if specific CF requested and this isn't it
123+
if (specific_cf && cf_names[i] != target_cf) {
124+
continue;
125+
}
126+
127+
std::cout << "=== Column Family: " << cf_names[i] << " ===" << std::endl;
128+
129+
// Create iterator for this column family
130+
ReadOptions read_options;
131+
read_options.skip_corrupted_data_blocks = skip_corrupted_data_blocks;
132+
Iterator* it = db->NewIterator(read_options, handles[i]);
133+
134+
uint64_t cf_count = 0;
135+
for (it->SeekToFirst(); it->Valid(); it->Next()) {
136+
std::string key = it->key().ToString();
137+
std::string value = it->value().ToString();
138+
139+
if (use_hex) {
140+
std::cout << "Key: " << ToHex(key) << ", Value: " << ToHex(value)
141+
<< std::endl;
142+
} else {
143+
std::cout << "Key: " << key << ", Value: " << value << std::endl;
144+
}
145+
cf_count++;
146+
}
147+
148+
// Check for any errors that happened during the iteration
149+
s = it->status();
150+
if (!s.ok()) {
151+
if (skip_corrupted_data_blocks) {
152+
std::cerr << "Warning: Iteration completed with error in CF '"
153+
<< cf_names[i] << "': " << s.ToString() << std::endl;
154+
} else {
155+
std::cerr << "Error during iteration in CF '" << cf_names[i]
156+
<< "': " << s.ToString() << std::endl;
157+
delete it;
158+
// Clean up handles
159+
for (auto* handle : handles) {
160+
delete handle;
161+
}
162+
delete db;
163+
return 1;
164+
}
165+
}
166+
167+
std::cout << "Keys in CF '" << cf_names[i] << "': " << cf_count << std::endl
168+
<< std::endl;
169+
total_count += cf_count;
170+
171+
delete it;
172+
}
173+
174+
std::cout << "Total keys printed: " << total_count << std::endl;
175+
176+
// Clean up handles
177+
for (auto* handle : handles) {
178+
delete handle;
179+
}
180+
delete db;
181+
return 0;
182+
}

0 commit comments

Comments
 (0)