2012-10-31 18:47:18 +00:00
|
|
|
// Copyright (c) 2012 Facebook. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#ifndef LEVELDB_UTIL_LDB_H_
|
|
|
|
#define LEVELDB_UTIL_LDB_H_
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include "leveldb/db.h"
|
LDB can read WAL.
Summary:
Add option to read WAL and print a summary for each record.
facebook task => #1885013
E.G. Output :
./ldb dump_wal --walfile=/tmp/leveldbtest-5907/dbbench/026122.log --header
Sequence,Count,ByteSize
49981,1,100033
49981,1,100033
49982,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49984,1,100033
49981,1,100033
49982,1,100033
Test Plan:
Works run
./ldb read_wal --wal-file=/tmp/leveldbtest-5907/dbbench/000078.log --header
Reviewers: dhruba, heyongqiang
Reviewed By: dhruba
CC: emayanke, leveldb, zshao
Differential Revision: https://reviews.facebook.net/D6675
2012-11-13 00:45:45 +00:00
|
|
|
#include "leveldb/env.h"
|
2012-10-31 18:47:18 +00:00
|
|
|
#include "leveldb/options.h"
|
|
|
|
#include "leveldb/iterator.h"
|
|
|
|
#include "leveldb/slice.h"
|
|
|
|
#include "db/version_set.h"
|
|
|
|
#include "util/logging.h"
|
|
|
|
|
|
|
|
namespace leveldb {
|
|
|
|
|
|
|
|
class LDBCommandExecuteResult {
|
|
|
|
public:
|
|
|
|
enum State {
|
|
|
|
EXEC_NOT_STARTED = 0, EXEC_SUCCEED = 1, EXEC_FAILED = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
LDBCommandExecuteResult() {
|
|
|
|
state_ = EXEC_NOT_STARTED;
|
|
|
|
message_ = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
LDBCommandExecuteResult(State state, std::string& msg) {
|
|
|
|
state_ = state;
|
|
|
|
message_ = msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ToString() {
|
|
|
|
std::string ret;
|
|
|
|
switch (state_) {
|
|
|
|
case EXEC_SUCCEED:
|
|
|
|
break;
|
|
|
|
case EXEC_FAILED:
|
2012-11-21 00:14:04 +00:00
|
|
|
ret.append("Failed: ");
|
2012-10-31 18:47:18 +00:00
|
|
|
break;
|
|
|
|
case EXEC_NOT_STARTED:
|
2012-11-21 00:14:04 +00:00
|
|
|
ret.append("Not started: ");
|
2012-10-31 18:47:18 +00:00
|
|
|
}
|
|
|
|
if (!message_.empty()) {
|
|
|
|
ret.append(message_);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Reset() {
|
|
|
|
state_ = EXEC_NOT_STARTED;
|
|
|
|
message_ = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsSucceed() {
|
|
|
|
return state_ == EXEC_SUCCEED;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsNotStarted() {
|
|
|
|
return state_ == EXEC_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsFailed() {
|
|
|
|
return state_ == EXEC_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LDBCommandExecuteResult SUCCEED(std::string msg) {
|
|
|
|
return LDBCommandExecuteResult(EXEC_SUCCEED, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static LDBCommandExecuteResult FAILED(std::string msg) {
|
|
|
|
return LDBCommandExecuteResult(EXEC_FAILED, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
State state_;
|
|
|
|
std::string message_;
|
|
|
|
|
|
|
|
bool operator==(const LDBCommandExecuteResult&);
|
|
|
|
bool operator!=(const LDBCommandExecuteResult&);
|
|
|
|
};
|
|
|
|
|
|
|
|
class LDBCommand {
|
|
|
|
public:
|
|
|
|
|
|
|
|
/* Constructor */
|
|
|
|
LDBCommand(std::string& db_name, std::vector<std::string>& args) :
|
|
|
|
db_path_(db_name),
|
|
|
|
db_(NULL) {
|
2012-12-05 23:37:03 +00:00
|
|
|
parse_open_args(args);
|
2012-10-31 18:47:18 +00:00
|
|
|
}
|
|
|
|
|
LDB can read WAL.
Summary:
Add option to read WAL and print a summary for each record.
facebook task => #1885013
E.G. Output :
./ldb dump_wal --walfile=/tmp/leveldbtest-5907/dbbench/026122.log --header
Sequence,Count,ByteSize
49981,1,100033
49981,1,100033
49982,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49984,1,100033
49981,1,100033
49982,1,100033
Test Plan:
Works run
./ldb read_wal --wal-file=/tmp/leveldbtest-5907/dbbench/000078.log --header
Reviewers: dhruba, heyongqiang
Reviewed By: dhruba
CC: emayanke, leveldb, zshao
Differential Revision: https://reviews.facebook.net/D6675
2012-11-13 00:45:45 +00:00
|
|
|
LDBCommand(std::vector<std::string>& args) :
|
|
|
|
db_path_(""),
|
|
|
|
db_(NULL) {
|
2012-12-05 23:37:03 +00:00
|
|
|
parse_open_args(args);
|
LDB can read WAL.
Summary:
Add option to read WAL and print a summary for each record.
facebook task => #1885013
E.G. Output :
./ldb dump_wal --walfile=/tmp/leveldbtest-5907/dbbench/026122.log --header
Sequence,Count,ByteSize
49981,1,100033
49981,1,100033
49982,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49984,1,100033
49981,1,100033
49982,1,100033
Test Plan:
Works run
./ldb read_wal --wal-file=/tmp/leveldbtest-5907/dbbench/000078.log --header
Reviewers: dhruba, heyongqiang
Reviewed By: dhruba
CC: emayanke, leveldb, zshao
Differential Revision: https://reviews.facebook.net/D6675
2012-11-13 00:45:45 +00:00
|
|
|
}
|
|
|
|
|
2012-12-05 23:37:03 +00:00
|
|
|
virtual leveldb::Options PrepareOptionsForOpenDB();
|
2012-10-31 18:47:18 +00:00
|
|
|
|
2012-11-09 02:45:19 +00:00
|
|
|
virtual bool NoDBOpen() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-10-31 18:47:18 +00:00
|
|
|
virtual ~LDBCommand() {
|
|
|
|
if (db_ != NULL) {
|
|
|
|
delete db_;
|
|
|
|
db_ = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print the help message */
|
|
|
|
static void Help(std::string& ret) {
|
2012-12-05 23:37:03 +00:00
|
|
|
ret.append("--db=DB_PATH [");
|
|
|
|
ret.append(LDBCommand::BLOOM_ARG);
|
|
|
|
ret.append("<int,e.g.:14>] [");
|
|
|
|
ret.append(LDBCommand::COMPRESSION_TYPE_ARG);
|
2012-12-21 06:56:58 +00:00
|
|
|
ret.append("<no|snappy|zlib|bzip2>] [");
|
2012-12-16 02:57:31 +00:00
|
|
|
ret.append(LDBCommand::BLOCK_SIZE);
|
2012-12-21 06:56:58 +00:00
|
|
|
ret.append("<block_size_in_bytes>] [");
|
2012-12-16 02:57:31 +00:00
|
|
|
ret.append(LDBCommand::AUTO_COMPACTION);
|
2012-12-21 06:56:58 +00:00
|
|
|
ret.append("<true|false>] [");
|
|
|
|
ret.append(LDBCommand::WRITE_BUFFER_SIZE_ARG);
|
|
|
|
ret.append("<int,e.g.:4194304>] [");
|
|
|
|
ret.append(LDBCommand::FILE_SIZE_ARG);
|
|
|
|
ret.append("<int,e.g.:2097152>] ");
|
2012-10-31 18:47:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Run the command, and return the execute result. */
|
|
|
|
void Run() {
|
|
|
|
if (!exec_state_.IsNotStarted()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-12-05 23:37:03 +00:00
|
|
|
if (db_ == NULL && !NoDBOpen()) {
|
2012-10-31 18:47:18 +00:00
|
|
|
OpenDB();
|
2012-12-05 23:37:03 +00:00
|
|
|
if (!exec_state_.IsNotStarted()) {
|
|
|
|
return;
|
|
|
|
}
|
2012-10-31 18:47:18 +00:00
|
|
|
}
|
2012-12-05 23:37:03 +00:00
|
|
|
|
2012-10-31 18:47:18 +00:00
|
|
|
DoCommand();
|
|
|
|
if (exec_state_.IsNotStarted()) {
|
|
|
|
exec_state_ = LDBCommandExecuteResult::SUCCEED("");
|
|
|
|
}
|
2012-11-09 02:45:19 +00:00
|
|
|
|
|
|
|
if (db_ != NULL) {
|
|
|
|
CloseDB ();
|
|
|
|
}
|
2012-10-31 18:47:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void DoCommand() = 0;
|
|
|
|
|
|
|
|
LDBCommandExecuteResult GetExecuteState() {
|
|
|
|
return exec_state_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearPreviousRunState() {
|
|
|
|
exec_state_.Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string HexToString(const std::string& str) {
|
|
|
|
std::string parsed;
|
2012-11-06 20:02:18 +00:00
|
|
|
for (unsigned int i = 0; i < str.length();) {
|
2012-10-31 18:47:18 +00:00
|
|
|
int c;
|
|
|
|
sscanf(str.c_str() + i, "%2X", &c);
|
|
|
|
parsed.push_back(c);
|
|
|
|
i += 2;
|
|
|
|
}
|
|
|
|
return parsed;
|
|
|
|
}
|
|
|
|
|
2012-12-26 23:15:54 +00:00
|
|
|
static std::string StringToHex(const std::string& str) {
|
|
|
|
std::string result;
|
|
|
|
char buf[10];
|
|
|
|
for (size_t i = 0; i < str.length(); i++) {
|
|
|
|
snprintf(buf, 10, "%02X", (unsigned char)str[i]);
|
|
|
|
result += buf;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char* DELIM;
|
|
|
|
static bool ParseKeyValue(const std::string& line,
|
|
|
|
std::string* key,
|
|
|
|
std::string* value,
|
|
|
|
bool hex) {
|
|
|
|
size_t pos = line.find(DELIM);
|
|
|
|
if (pos != std::string::npos) {
|
|
|
|
(*key) = line.substr(0, pos);
|
|
|
|
(*value) = line.substr(pos + strlen(DELIM));
|
|
|
|
if (hex) {
|
|
|
|
(*key) = HexToString(*key);
|
|
|
|
(*value) = HexToString(*value);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string PrintKeyValue(const std::string& key,
|
|
|
|
const std::string& value,
|
|
|
|
bool hex) {
|
|
|
|
std::string result;
|
|
|
|
result.append(hex ? StringToHex(key) : key);
|
|
|
|
result.append(DELIM);
|
|
|
|
result.append(hex ? StringToHex(value) : value);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2012-10-31 18:47:18 +00:00
|
|
|
protected:
|
|
|
|
|
|
|
|
void OpenDB() {
|
|
|
|
leveldb::Options opt = PrepareOptionsForOpenDB();
|
2012-12-05 23:37:03 +00:00
|
|
|
if (!exec_state_.IsNotStarted()) {
|
|
|
|
return;
|
|
|
|
}
|
2012-10-31 18:47:18 +00:00
|
|
|
// Open the DB.
|
|
|
|
leveldb::Status st = leveldb::DB::Open(opt, db_path_, &db_);
|
|
|
|
if (!st.ok()) {
|
|
|
|
std::string msg = st.ToString();
|
|
|
|
exec_state_ = LDBCommandExecuteResult::FAILED(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CloseDB () {
|
|
|
|
if (db_ != NULL) {
|
|
|
|
delete db_;
|
|
|
|
db_ = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char* FROM_ARG;
|
|
|
|
static const char* END_ARG;
|
|
|
|
static const char* HEX_ARG;
|
|
|
|
LDBCommandExecuteResult exec_state_;
|
|
|
|
std::string db_path_;
|
|
|
|
leveldb::DB* db_;
|
2012-12-05 23:37:03 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
static const char* BLOOM_ARG;
|
|
|
|
static const char* COMPRESSION_TYPE_ARG;
|
2012-12-16 02:57:31 +00:00
|
|
|
static const char* BLOCK_SIZE;
|
|
|
|
static const char* AUTO_COMPACTION;
|
2012-12-21 06:56:58 +00:00
|
|
|
static const char* WRITE_BUFFER_SIZE_ARG;
|
|
|
|
static const char* FILE_SIZE_ARG;
|
2012-12-05 23:37:03 +00:00
|
|
|
std::vector<std::string> open_args_;
|
|
|
|
void parse_open_args(std::vector<std::string>& args);
|
2012-10-31 18:47:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Compactor: public LDBCommand {
|
|
|
|
public:
|
|
|
|
Compactor(std::string& db_name, std::vector<std::string>& args);
|
|
|
|
|
|
|
|
virtual ~Compactor() {}
|
|
|
|
|
|
|
|
static void Help(std::string& ret);
|
|
|
|
|
|
|
|
virtual void DoCommand();
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool null_from_;
|
|
|
|
std::string from_;
|
|
|
|
bool null_to_;
|
|
|
|
std::string to_;
|
|
|
|
bool hex_;
|
|
|
|
};
|
|
|
|
|
|
|
|
class DBDumper: public LDBCommand {
|
|
|
|
public:
|
|
|
|
DBDumper(std::string& db_name, std::vector<std::string>& args);
|
|
|
|
virtual ~DBDumper() {}
|
|
|
|
static void Help(std::string& ret);
|
|
|
|
virtual void DoCommand();
|
|
|
|
private:
|
|
|
|
bool null_from_;
|
|
|
|
std::string from_;
|
|
|
|
bool null_to_;
|
|
|
|
std::string to_;
|
|
|
|
int max_keys_;
|
|
|
|
bool count_only_;
|
|
|
|
bool print_stats_;
|
|
|
|
bool hex_;
|
|
|
|
bool hex_output_;
|
|
|
|
|
|
|
|
static const char* MAX_KEYS_ARG;
|
|
|
|
static const char* COUNT_ONLY_ARG;
|
|
|
|
static const char* STATS_ARG;
|
|
|
|
static const char* HEX_OUTPUT_ARG;
|
|
|
|
};
|
|
|
|
|
2012-12-17 01:06:51 +00:00
|
|
|
class DBLoader: public LDBCommand {
|
|
|
|
public:
|
|
|
|
DBLoader(std::string& db_name, std::vector<std::string>& args);
|
|
|
|
virtual ~DBLoader() {}
|
|
|
|
static void Help(std::string& ret);
|
|
|
|
virtual void DoCommand();
|
|
|
|
|
|
|
|
virtual leveldb::Options PrepareOptionsForOpenDB();
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool hex_input_;
|
|
|
|
bool create_if_missing_;
|
|
|
|
bool disable_wal_;
|
|
|
|
|
|
|
|
static const char* HEX_INPUT_ARG;
|
|
|
|
static const char* CREATE_IF_MISSING_ARG;
|
|
|
|
static const char* DISABLE_WAL_ARG;
|
|
|
|
};
|
|
|
|
|
2012-12-26 23:15:54 +00:00
|
|
|
class DBQuerier: public LDBCommand {
|
|
|
|
public:
|
|
|
|
DBQuerier(std::string& db_name, std::vector<std::string>& args);
|
|
|
|
virtual ~DBQuerier() {}
|
|
|
|
static void Help(std::string& ret);
|
|
|
|
virtual void DoCommand();
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool hex_;
|
|
|
|
|
|
|
|
static const char* HEX_ARG;
|
|
|
|
|
|
|
|
static const char* HELP_CMD;
|
|
|
|
static const char* GET_CMD;
|
|
|
|
static const char* PUT_CMD;
|
|
|
|
static const char* DELETE_CMD;
|
|
|
|
};
|
|
|
|
|
2012-10-31 18:47:18 +00:00
|
|
|
class ReduceDBLevels : public LDBCommand {
|
|
|
|
public:
|
|
|
|
|
|
|
|
ReduceDBLevels (std::string& db_name, std::vector<std::string>& args);
|
|
|
|
|
|
|
|
~ReduceDBLevels() {}
|
|
|
|
|
|
|
|
virtual leveldb::Options PrepareOptionsForOpenDB();
|
|
|
|
|
|
|
|
virtual void DoCommand();
|
|
|
|
|
2012-11-09 02:45:19 +00:00
|
|
|
virtual bool NoDBOpen() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Help(std::string& msg);
|
2012-10-31 18:47:18 +00:00
|
|
|
static std::vector<std::string> PrepareArgs(int new_levels,
|
|
|
|
bool print_old_level = false);
|
|
|
|
|
|
|
|
private:
|
2012-11-09 02:45:19 +00:00
|
|
|
int old_levels_;
|
2012-10-31 18:47:18 +00:00
|
|
|
int new_levels_;
|
|
|
|
bool print_old_levels_;
|
|
|
|
|
|
|
|
static const char* NEW_LEVLES_ARG;
|
|
|
|
static const char* PRINT_OLD_LEVELS_ARG;
|
2012-11-09 02:45:19 +00:00
|
|
|
|
|
|
|
Status GetOldNumOfLevels(leveldb::Options& opt, int* levels);
|
2012-10-31 18:47:18 +00:00
|
|
|
};
|
|
|
|
|
LDB can read WAL.
Summary:
Add option to read WAL and print a summary for each record.
facebook task => #1885013
E.G. Output :
./ldb dump_wal --walfile=/tmp/leveldbtest-5907/dbbench/026122.log --header
Sequence,Count,ByteSize
49981,1,100033
49981,1,100033
49982,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49984,1,100033
49981,1,100033
49982,1,100033
Test Plan:
Works run
./ldb read_wal --wal-file=/tmp/leveldbtest-5907/dbbench/000078.log --header
Reviewers: dhruba, heyongqiang
Reviewed By: dhruba
CC: emayanke, leveldb, zshao
Differential Revision: https://reviews.facebook.net/D6675
2012-11-13 00:45:45 +00:00
|
|
|
class WALDumper : public LDBCommand {
|
|
|
|
public:
|
|
|
|
|
|
|
|
WALDumper (std::vector<std::string>& args);
|
|
|
|
|
|
|
|
~WALDumper() {}
|
|
|
|
|
|
|
|
virtual bool NoDBOpen() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Help(std::string& ret);
|
|
|
|
virtual void DoCommand();
|
|
|
|
private:
|
|
|
|
bool print_header_;
|
|
|
|
std::string wal_file_;
|
2012-10-31 18:47:18 +00:00
|
|
|
|
LDB can read WAL.
Summary:
Add option to read WAL and print a summary for each record.
facebook task => #1885013
E.G. Output :
./ldb dump_wal --walfile=/tmp/leveldbtest-5907/dbbench/026122.log --header
Sequence,Count,ByteSize
49981,1,100033
49981,1,100033
49982,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49981,1,100033
49982,1,100033
49983,1,100033
49984,1,100033
49981,1,100033
49982,1,100033
Test Plan:
Works run
./ldb read_wal --wal-file=/tmp/leveldbtest-5907/dbbench/000078.log --header
Reviewers: dhruba, heyongqiang
Reviewed By: dhruba
CC: emayanke, leveldb, zshao
Differential Revision: https://reviews.facebook.net/D6675
2012-11-13 00:45:45 +00:00
|
|
|
static const char* WAL_FILE_ARG;
|
|
|
|
};
|
|
|
|
}
|
2012-10-31 18:47:18 +00:00
|
|
|
#endif
|