|
|
@ -1016,8 +1016,8 @@ void DumpManifestFile(Options options, std::string file, bool verbose, bool hex, |
|
|
|
/*block_cache_tracer=*/nullptr); |
|
|
|
/*block_cache_tracer=*/nullptr); |
|
|
|
Status s = versions.DumpManifest(options, file, verbose, hex, json); |
|
|
|
Status s = versions.DumpManifest(options, file, verbose, hex, json); |
|
|
|
if (!s.ok()) { |
|
|
|
if (!s.ok()) { |
|
|
|
printf("Error in processing file %s %s\n", file.c_str(), |
|
|
|
fprintf(stderr, "Error in processing file %s %s\n", file.c_str(), |
|
|
|
s.ToString().c_str()); |
|
|
|
s.ToString().c_str()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1066,45 +1066,72 @@ void ManifestDumpCommand::DoCommand() { |
|
|
|
if (!path_.empty()) { |
|
|
|
if (!path_.empty()) { |
|
|
|
manifestfile = path_; |
|
|
|
manifestfile = path_; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
bool found = false; |
|
|
|
|
|
|
|
// We need to find the manifest file by searching the directory
|
|
|
|
// We need to find the manifest file by searching the directory
|
|
|
|
// containing the db for files of the form MANIFEST_[0-9]+
|
|
|
|
// containing the db for files of the form MANIFEST_[0-9]+
|
|
|
|
|
|
|
|
|
|
|
|
auto CloseDir = [](DIR* p) { closedir(p); }; |
|
|
|
std::vector<std::string> files; |
|
|
|
std::unique_ptr<DIR, decltype(CloseDir)> d(opendir(db_path_.c_str()), |
|
|
|
Status s = options_.env->GetChildren(db_path_, &files); |
|
|
|
CloseDir); |
|
|
|
if (!s.ok()) { |
|
|
|
|
|
|
|
std::string err_msg = s.ToString(); |
|
|
|
if (d == nullptr) { |
|
|
|
err_msg.append(": Failed to list the content of "); |
|
|
|
exec_state_ = |
|
|
|
err_msg.append(db_path_); |
|
|
|
LDBCommandExecuteResult::Failed(db_path_ + " is not a directory"); |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(err_msg); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
struct dirent* entry; |
|
|
|
const std::string kManifestNamePrefix = "MANIFEST-"; |
|
|
|
while ((entry = readdir(d.get())) != nullptr) { |
|
|
|
std::string matched_file; |
|
|
|
unsigned int match; |
|
|
|
#ifdef OS_WIN |
|
|
|
uint64_t num; |
|
|
|
const char kPathDelim = '\\'; |
|
|
|
if (sscanf(entry->d_name, "MANIFEST-%" PRIu64 "%n", &num, &match) && |
|
|
|
#else |
|
|
|
match == strlen(entry->d_name)) { |
|
|
|
const char kPathDelim = '/'; |
|
|
|
if (!found) { |
|
|
|
#endif |
|
|
|
manifestfile = db_path_ + "/" + std::string(entry->d_name); |
|
|
|
for (const auto& file_path : files) { |
|
|
|
found = true; |
|
|
|
// Some Env::GetChildren() return absolute paths. Some directories' path
|
|
|
|
} else { |
|
|
|
// end with path delim, e.g. '/' or '\\'.
|
|
|
|
|
|
|
|
size_t pos = file_path.find_last_of(kPathDelim); |
|
|
|
|
|
|
|
if (pos == file_path.size() - 1) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::string fname; |
|
|
|
|
|
|
|
if (pos != std::string::npos) { |
|
|
|
|
|
|
|
// Absolute path.
|
|
|
|
|
|
|
|
fname.assign(file_path, pos + 1, file_path.size() - pos - 1); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
fname = file_path; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
uint64_t file_num = 0; |
|
|
|
|
|
|
|
FileType file_type = kLogFile; // Just for initialization
|
|
|
|
|
|
|
|
if (ParseFileName(fname, &file_num, &file_type) && |
|
|
|
|
|
|
|
file_type == kDescriptorFile) { |
|
|
|
|
|
|
|
if (!matched_file.empty()) { |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed( |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed( |
|
|
|
"Multiple MANIFEST files found; use --path to select one"); |
|
|
|
"Multiple MANIFEST files found; use --path to select one"); |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
matched_file.swap(fname); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (matched_file.empty()) { |
|
|
|
|
|
|
|
std::string err_msg("No MANIFEST found in "); |
|
|
|
|
|
|
|
err_msg.append(db_path_); |
|
|
|
|
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(err_msg); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (db_path_[db_path_.length() - 1] != '/') { |
|
|
|
|
|
|
|
db_path_.append("/"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
manifestfile = db_path_ + matched_file; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (verbose_) { |
|
|
|
if (verbose_) { |
|
|
|
printf("Processing Manifest file %s\n", manifestfile.c_str()); |
|
|
|
fprintf(stdout, "Processing Manifest file %s\n", manifestfile.c_str()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DumpManifestFile(options_, manifestfile, verbose_, is_key_hex_, json_); |
|
|
|
DumpManifestFile(options_, manifestfile, verbose_, is_key_hex_, json_); |
|
|
|
|
|
|
|
|
|
|
|
if (verbose_) { |
|
|
|
if (verbose_) { |
|
|
|
printf("Processing Manifest file %s done\n", manifestfile.c_str()); |
|
|
|
fprintf(stdout, "Processing Manifest file %s done\n", manifestfile.c_str()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1126,19 +1153,19 @@ void ListColumnFamiliesCommand::DoCommand() { |
|
|
|
std::vector<std::string> column_families; |
|
|
|
std::vector<std::string> column_families; |
|
|
|
Status s = DB::ListColumnFamilies(options_, db_path_, &column_families); |
|
|
|
Status s = DB::ListColumnFamilies(options_, db_path_, &column_families); |
|
|
|
if (!s.ok()) { |
|
|
|
if (!s.ok()) { |
|
|
|
printf("Error in processing db %s %s\n", db_path_.c_str(), |
|
|
|
fprintf(stderr, "Error in processing db %s %s\n", db_path_.c_str(), |
|
|
|
s.ToString().c_str()); |
|
|
|
s.ToString().c_str()); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
printf("Column families in %s: \n{", db_path_.c_str()); |
|
|
|
fprintf(stdout, "Column families in %s: \n{", db_path_.c_str()); |
|
|
|
bool first = true; |
|
|
|
bool first = true; |
|
|
|
for (auto cf : column_families) { |
|
|
|
for (auto cf : column_families) { |
|
|
|
if (!first) { |
|
|
|
if (!first) { |
|
|
|
printf(", "); |
|
|
|
fprintf(stdout, ", "); |
|
|
|
} |
|
|
|
} |
|
|
|
first = false; |
|
|
|
first = false; |
|
|
|
printf("%s", cf.c_str()); |
|
|
|
fprintf(stdout, "%s", cf.c_str()); |
|
|
|
} |
|
|
|
} |
|
|
|
printf("}\n"); |
|
|
|
fprintf(stdout, "}\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2761,7 +2788,7 @@ void CheckPointCommand::DoCommand() { |
|
|
|
Status status = Checkpoint::Create(db_, &checkpoint); |
|
|
|
Status status = Checkpoint::Create(db_, &checkpoint); |
|
|
|
status = checkpoint->CreateCheckpoint(checkpoint_dir_); |
|
|
|
status = checkpoint->CreateCheckpoint(checkpoint_dir_); |
|
|
|
if (status.ok()) { |
|
|
|
if (status.ok()) { |
|
|
|
printf("OK\n"); |
|
|
|
fprintf(stdout, "OK\n"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
} |
|
|
|
} |
|
|
@ -2785,7 +2812,7 @@ void RepairCommand::DoCommand() { |
|
|
|
options.info_log.reset(new StderrLogger(InfoLogLevel::WARN_LEVEL)); |
|
|
|
options.info_log.reset(new StderrLogger(InfoLogLevel::WARN_LEVEL)); |
|
|
|
Status status = RepairDB(db_path_, options); |
|
|
|
Status status = RepairDB(db_path_, options); |
|
|
|
if (status.ok()) { |
|
|
|
if (status.ok()) { |
|
|
|
printf("OK\n"); |
|
|
|
fprintf(stdout, "OK\n"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
} |
|
|
|
} |
|
|
@ -2865,7 +2892,7 @@ void BackupCommand::DoCommand() { |
|
|
|
assert(GetExecuteState().IsFailed()); |
|
|
|
assert(GetExecuteState().IsFailed()); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
printf("open db OK\n"); |
|
|
|
fprintf(stdout, "open db OK\n"); |
|
|
|
Env* custom_env = nullptr; |
|
|
|
Env* custom_env = nullptr; |
|
|
|
Env::LoadEnv(backup_env_uri_, &custom_env, &backup_env_guard_); |
|
|
|
Env::LoadEnv(backup_env_uri_, &custom_env, &backup_env_guard_); |
|
|
|
assert(custom_env != nullptr); |
|
|
|
assert(custom_env != nullptr); |
|
|
@ -2876,14 +2903,14 @@ void BackupCommand::DoCommand() { |
|
|
|
backup_options.max_background_operations = num_threads_; |
|
|
|
backup_options.max_background_operations = num_threads_; |
|
|
|
status = BackupEngine::Open(custom_env, backup_options, &backup_engine); |
|
|
|
status = BackupEngine::Open(custom_env, backup_options, &backup_engine); |
|
|
|
if (status.ok()) { |
|
|
|
if (status.ok()) { |
|
|
|
printf("open backup engine OK\n"); |
|
|
|
fprintf(stdout, "open backup engine OK\n"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
status = backup_engine->CreateNewBackup(db_); |
|
|
|
status = backup_engine->CreateNewBackup(db_); |
|
|
|
if (status.ok()) { |
|
|
|
if (status.ok()) { |
|
|
|
printf("create new backup OK\n"); |
|
|
|
fprintf(stdout, "create new backup OK\n"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -2921,11 +2948,11 @@ void RestoreCommand::DoCommand() { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (status.ok()) { |
|
|
|
if (status.ok()) { |
|
|
|
printf("open restore engine OK\n"); |
|
|
|
fprintf(stdout, "open restore engine OK\n"); |
|
|
|
status = restore_engine->RestoreDBFromLatestBackup(db_path_, db_path_); |
|
|
|
status = restore_engine->RestoreDBFromLatestBackup(db_path_, db_path_); |
|
|
|
} |
|
|
|
} |
|
|
|
if (status.ok()) { |
|
|
|
if (status.ok()) { |
|
|
|
printf("restore from backup OK\n"); |
|
|
|
fprintf(stdout, "restore from backup OK\n"); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString()); |
|
|
|
} |
|
|
|
} |
|
|
|