提交 b5266f04 编写于 作者: S simonjoylet 提交者: LINGuanRen

patch ob_admin

上级 04ecb035
add_executable(ob_admin
clog_tool/cmd_args_parser.h
clog_tool/ob_admin_clog_v2_executor.cpp
clog_tool/ob_admin_clog_v2_executor.h
clog_tool/ob_func_utils.cpp
clog_tool/ob_func_utils.h
clog_tool/ob_ilog_entry_parser.cpp
clog_tool/ob_ilog_entry_parser.h
clog_tool/ob_log_entry_filter.cpp
clog_tool/ob_log_entry_filter.h
clog_tool/ob_log_entry_parser.cpp
clog_tool/ob_log_entry_parser.h
usec_tool/ob_admin_usec_executor.cpp
usec_tool/ob_admin_usec_executor.h
ob_admin_executor.h
slog_tool/ob_admin_slog_executor.cpp
dumpsst/ob_admin_dumpsst_executor.cpp
dumpsst/ob_admin_cmp_micro_executor.cpp
dumpsst/ob_admin_dumpsst_utils.cpp
dumpsst/ob_admin_dumpsst_print_helper.cpp
archive_tool/ob_fake_archive_log_file_store.cpp
archive_tool/ob_admin_log_archive_executor.cpp
archive_tool/ob_archive_entry_parser.cpp
archive_tool/ob_archive_fake_entry_iterator.cpp
archive_tool/ob_archive_fake_file_store.cpp
backup_tool/ob_admin_dump_backup_data_executor.cpp
ob_admin_executor.cpp
main.cpp)
......@@ -32,4 +36,4 @@ target_link_libraries(ob_admin
target_include_directories(ob_admin
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR})
\ No newline at end of file
${CMAKE_CURRENT_SOURCE_DIR})
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX CLOG
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "ob_admin_log_archive_executor.h"
#include "../clog_tool/ob_func_utils.h"
#include "../clog_tool/ob_log_entry_filter.h"
#include "../clog_tool/ob_log_entry_parser.h"
#include "../clog_tool/cmd_args_parser.h"
#include "ob_fake_archive_log_file_store.h"
#include "archive/ob_archive_entry_iterator.h"
#include "clog/ob_log_entry.h"
#include "share/ob_version.h"
#include "archive/ob_log_archive_struct.h"
#include "ob_archive_entry_parser.h"
using namespace oceanbase::common;
using namespace oceanbase::clog;
using namespace oceanbase::archive;
namespace oceanbase
{
namespace tools
{
#define getcfg(key) getenv(key)
int ObAdminLogArchiveExecutor::execute(int argc, char *argv[])
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(argc < 4) || OB_ISNULL(argv)) {
print_usage();
ret = OB_INVALID_ARGUMENT;
} else if (OB_FAIL(parse_options(argc, argv))) {
LOG_WARN("failed to parse options", K(ret));
} else {
int new_argc = argc - optind;
char **new_argv = argv + optind;
if (OB_NEED_RETRY != (ret = CmdCallSimple(new_argc, new_argv, dump_log):OB_NEED_RETRY)) {
LOG_INFO("finish dump_log ", K(ret));
} else if (OB_NEED_RETRY != (ret = CmdCallSimple(new_argc, new_argv, dump_index):OB_NEED_RETRY)) {
LOG_INFO("finish dump_index ", K(ret));
} else if (OB_NEED_RETRY != (ret = CmdCallSimple(new_argc, new_argv, dump_key):OB_NEED_RETRY)) {
LOG_INFO("finish dump_key ", K(ret));
} else {
fprintf(stderr, "failed %d", ret);
print_usage();
}
}
return ret;
}
void ObAdminLogArchiveExecutor::print_usage()
{
fprintf(stdout,
"Usages:\n"
"ob_admin archive_tool dump_log data_files ## ./ob_admin archive_tool dump_log 1 2 3\n"
"ob_admin archive_tool dump_index index_files ## ./ob_admin archive_tool dump_index 1 2 3\n"
"ob_admin archive_tool dump_key archive_key_files ## ./ob_admin archive_tool dump_key 1100611139403779_0\n"
);
}
int ObAdminLogArchiveExecutor::dump_log(int argc, char *argv[])
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(argc < 1) || OB_ISNULL(argv)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(argc), K(ret));
} else {
LOG_INFO("begin to dump all archive log file", K(ret));
for (int64_t i = 0; i < argc; ++i) {
if (OB_FAIL(dump_single_file(argv[i])) && OB_ITER_END != ret) {
LOG_WARN("failed to dump log ", K(argv[i]), K(ret));
} else if (OB_ITER_END == ret) {
ret = OB_SUCCESS;
} else {/*do nothing*/}
}
if (OB_FAIL(ret)) {
print_usage();
}
}
return ret;
}
int ObAdminLogArchiveExecutor::dump_index(int argc, char *argv[])
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(argc < 1) || OB_ISNULL(argv)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(argc), K(ret));
} else {
LOG_INFO("begin to dump archive index file", K(ret));
for (int64_t i = 0; i < argc; ++i) {
if (OB_FAIL(dump_single_index_file(argv[i])) && OB_ITER_END != ret) {
LOG_WARN("failed to dump log ", K(argv[i]), K(ret));
} else if (OB_ITER_END == ret) {
ret = OB_SUCCESS;
}
}
}
return ret;
}
int ObAdminLogArchiveExecutor::dump_key(int argc, char *argv[])
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(argc < 1) || OB_ISNULL(argv)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(argc), K(ret));
} else {
LOG_INFO("begin to dump archive index file", K(ret));
for (int64_t i = 0; i < argc; ++i) {
if (OB_FAIL(dump_single_key_file(argv[i])) && OB_ITER_END != ret) {
LOG_WARN("failed to dump log ", K(argv[i]), K(ret));
} else if (OB_ITER_END == ret) {
ret = OB_SUCCESS;
}
}
}
return ret;
}
int ObAdminLogArchiveExecutor::dump_single_file(const char *path)
{
int ret = OB_SUCCESS;
uint64_t file_id = 0;
ObArchiveEntryParser entry_parser;
if (OB_FAIL(file_name_parser(path, file_id))) {
LOG_WARN("failed to parse file name", K(path), K(ret));
} else if (OB_FAIL(entry_parser.init(file_id, tenant_id_, DB_host_, DB_port_))) {
LOG_WARN("failed to init entry parser", K(path), K(ret));
} else if (OB_FAIL(entry_parser.dump_all_entry(path))) {
if (OB_ITER_END == ret) {
LOG_INFO("succ to dump_all_entry", K(path));
} else {
LOG_WARN("failed to dump_all_entry", K(path), K(ret));
}
} else {/*do nothing*/}
return ret;
}
int ObAdminLogArchiveExecutor::dump_single_index_file(const char *path)
{
int ret = OB_SUCCESS;
int fd = -1;
char *buf = NULL;
int64_t buf_len = -1;
uint64_t file_id = -1;
if (OB_FAIL(mmap_log_file(path, buf, buf_len, fd))) {
LOG_WARN("failed to mmap_log_file", K(path), K(ret));
} else if (OB_FAIL(file_name_parser(path, file_id))) {
LOG_WARN("failed to parse file name", K(path), K(ret));
} else {
ObArchiveIndexFileInfo info;
int64_t pos = 0;
while (OB_SUCCESS == ret && pos < buf_len) {
info.reset();
if (OB_FAIL(info.deserialize(buf, buf_len, pos))) {
LOG_WARN("deserialize info fail", K(ret), K(buf), K(buf_len));
} else {
fprintf(stdout, "$$$ %s\n", to_cstring(info));
}
}
}
if (fd >= 0) {
close(fd);
}
return ret;
}
int ObAdminLogArchiveExecutor::dump_single_key_file(const char *path)
{
int ret = OB_SUCCESS;
int fd = -1;
char *buf = NULL;
int64_t buf_len = -1;
if (OB_FAIL(mmap_log_file(path, buf, buf_len, fd))) {
LOG_WARN("failed to mmap_log_file", K(path), K(ret));
} else {
ObArchiveKeyContent key_content;
int64_t pos = 0;
if (OB_FAIL(key_content.deserialize(buf, buf_len, pos))) {
LOG_WARN("deserialize info fail", K(ret), K(buf), K(buf_len));
} else {
fprintf(stdout, "$$$ %s, %s\n", path, to_cstring(key_content));
}
}
if (fd >= 0) {
close(fd);
}
return ret;
}
int ObAdminLogArchiveExecutor::mmap_log_file(const char *path, char *&buf_out, int64_t &buf_len, int &fd)
{
int ret = OB_SUCCESS;
void *buf = NULL;
struct stat stat_buf;
const int64_t FILE_MAX_SIZE = 64 * 1024 * 1024;
if (OB_ISNULL(path)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid log file path is NULL", K(ret));
} else if (-1 == (fd = open(path, O_RDONLY))) {
ret = OB_IO_ERROR;
CLOG_LOG(ERROR, "open file fail", K(path), KERRMSG, K(ret));
} else if (-1 == fstat(fd, &stat_buf)) {
ret = OB_IO_ERROR;
CLOG_LOG(ERROR, "stat_buf error", K(path), KERRMSG, K(ret));
} else if (stat_buf.st_size > FILE_MAX_SIZE) {
ret = OB_INVALID_ARGUMENT;
CLOG_LOG(ERROR, "invalid file size", K(path), K(stat_buf.st_size), K(ret));
} else if (MAP_FAILED == (buf = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0)) || NULL == buf) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed to mmap file", K(path), K(errno), KERRMSG, K(ret));
} else {
buf_out = static_cast<char *>(buf);
buf_len = stat_buf.st_size;
}
return ret;
}
}//namespace tools
}//namespace oceanbase
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OB_ADMIN_LOG_ARCHIVE_EXECUTOR_H_
#define OB_ADMIN_LOG_ARCHIVE_EXECUTOR_H_
#include "../ob_admin_executor.h"
#include "../clog_tool/ob_log_entry_filter.h"
namespace oceanbase
{
using namespace clog;
namespace tools
{
class ObAdminLogArchiveExecutor : public ObAdminExecutor
{
public:
ObAdminLogArchiveExecutor(){}
virtual ~ObAdminLogArchiveExecutor(){}
virtual int execute(int argc, char *argv[]);
int dump_single_file(const char *path);
int dump_single_index_file(const char *path);
int dump_single_key_file(const char *path);
private:
int dump_log(int argc, char *argv[]);
int dump_index(int argc, char *argv[]);
int dump_key(int argc, char *argv[]);
void print_usage();
int mmap_log_file(const char *path, char *&buf_out, int64_t &buf_len, int &fd);
};
}
}
#endif /* OB_ADMIN_LOG_ARCHIVE_V2_H_ */
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include "ob_archive_entry_parser.h"
#include "archive/ob_log_archive_define.h"
#include "archive/ob_archive_entry_iterator.h"
#include "archive/ob_archive_block.h"
#include "ob_archive_fake_entry_iterator.h"
#include "ob_archive_fake_file_store.h"
#include <string.h>
namespace oceanbase
{
using namespace common;
using namespace memtable;
using namespace storage;
using namespace archive;
namespace archive
{
int ObArchiveEntryParser::init(uint64_t file_id,
const uint64_t tenant_id,
const common::ObString &host,
const int32_t port)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(is_inited_)) {
ret = OB_INIT_TWICE;
} else if (OB_UNLIKELY(OB_INVALID_FILE_ID == file_id)) {
ret = OB_INVALID_ARGUMENT;
CLOG_LOG(WARN, "invalid buf or buf_len", K(file_id), K(ret));
} else {
file_id_ = file_id;
tenant_id_ = tenant_id;
if (!host.empty() && port > 0) {
if (OB_SUCCESS != client_.init()) {
CLOG_LOG(WARN, "failed to init net client", K(ret));
} else if (OB_SUCCESS != client_.get_proxy(rpc_proxy_)) {
CLOG_LOG(WARN, "failed to get_proxy", K(ret));
}
host_addr_.set_ip_addr(host, port);
rpc_proxy_.set_server(host_addr_);
}
is_inited_ = true;
}
return ret;
}
int ObArchiveEntryParser::dump_all_entry(const char *path)
{
int ret = OB_SUCCESS;
ObArchiveFakeFileStore file_store;
ObArchiveFakeEntryIterator iter;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
CLOG_LOG(ERROR, "log entry parser is not inited", K(is_inited_), K(ret));
} else if (OB_FAIL(file_store.init_for_dump(path))) {
CLOG_LOG(WARN, "init for dump fail", K(ret), K(path));
} else if (OB_FAIL(iter.init(tenant_id_, &file_store, &rpc_proxy_))) {
CLOG_LOG(WARN, "iter init fail", K(ret));
} else {
while (OB_SUCC(ret)) {
clog::ObLogEntry entry;
const int64_t fake_pos = 1;
bool unused_flag = false;
int64_t unused_checksum = -1;
if (OB_FAIL(iter.next_entry(entry, unused_flag, unused_checksum))) {
CLOG_LOG(WARN, "next entry fail", K(ret));
} else if (OB_FAIL(dump_clog_entry(entry, fake_pos))) {
CLOG_LOG(WARN, "dump clog entry fail", K(ret));
}
}
if (OB_ITER_END == ret) {
ret = OB_SUCCESS;
}
}
return ret;
}
}//end of namespace clog
}//end of namespace oceanbase
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_ARCHIVE_OB_ARCHIVE_ENTRY_PARSER_
#define OCEANBASE_ARCHIVE_OB_ARCHIVE_ENTRY_PARSER_
#include "../clog_tool/ob_log_entry_parser.h"
#include "../clog_tool/ob_func_utils.h"
#include "archive/ob_archive_entry_iterator.h"
namespace oceanbase
{
namespace archive
{
class ObArchiveEntryParser : public clog::ObLogEntryParserImpl
{
public:
ObArchiveEntryParser() : is_inited_(false),
file_id_(0),
tenant_id_(0) {}
virtual ~ObArchiveEntryParser() {}
int init(uint64_t file_id, const uint64_t tenant_id, const common::ObString &host,
const int32_t port);
bool is_inited() const {return is_inited_;}
int dump_all_entry_1();
int dump_all_entry(const char *path);
TO_STRING_KV(K(is_inited_),
K(file_id_),
K(tenant_id_));
protected:
int parse_next_entry_();
int get_entry_type_(ObArchiveItemType &item_type);
void advance_(const int64_t step);
void skip_block_offset_tail_();
protected:
static const int64_t MAGIC_NUM_LEN = 2L;
static const int64_t PRINT_BUF_SIZE = 5 * 1024 * 1024;
bool is_inited_;
uint64_t file_id_;
uint64_t tenant_id_;
DISALLOW_COPY_AND_ASSIGN(ObArchiveEntryParser);
};
}//end of namespace clog
}//end of namespace oceanbase
#endif //OCEANBASE_ARCHIVE_OB_ARCHIVE_ENTRY_PARSER_
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include "ob_archive_fake_entry_iterator.h"
namespace oceanbase
{
using namespace clog;
namespace archive
{
ObArchiveFakeEntryIterator::~ObArchiveFakeEntryIterator()
{
inited_ = false;
rpc_proxy_ = nullptr;
}
int ObArchiveFakeEntryIterator::init(const uint64_t tenant_id,
ObIArchiveLogFileStore *file_store,
obrpc::ObSrvRpcProxy *rpc_proxy)
{
int ret = OB_SUCCESS;
common::ObPGKey fake_key(1, 0, 0);
const uint64_t fake_file_id = 1;
const uint64_t tmp_tenant_id = 0 == tenant_id ? 1 : tenant_id;
if (OB_ISNULL(file_store) || NULL == rpc_proxy) {
ret = OB_INVALID_ARGUMENT;
ARCHIVE_LOG(ERROR, "invalid argument", K(ret), K(file_store), K(rpc_proxy));
} else if (OB_FAIL(ObArchiveEntryIterator::init(file_store, fake_key, fake_file_id, 0, 1000, false, tmp_tenant_id))) {
ARCHIVE_LOG(WARN, "init fail", K(ret));
} else {
rpc_proxy_ = rpc_proxy;
}
return ret;
}
}
}
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_ARCHIVE_FAKE_ENTRY_ITERATOR_
#define OCEANBASE_ARCHIVE_FAKE_ENTRY_ITERATOR_
#include "archive/ob_archive_entry_iterator.h"
#include "../clog_tool/ob_log_entry_parser.h"
namespace oceanbase
{
namespace archive
{
class ObArchiveFakeEntryIterator : public ObArchiveEntryIterator
{
public:
ObArchiveFakeEntryIterator(): inited_(false), rpc_proxy_(nullptr) {}
virtual ~ObArchiveFakeEntryIterator();
int init(const uint64_t tenant_id,
ObIArchiveLogFileStore *file_store,
obrpc::ObSrvRpcProxy *rpc_proxy);
private:
bool inited_;
obrpc::ObSrvRpcProxy *rpc_proxy_;
};
} // namespace archive
} // namespace oceanbase
#endif /* OCEANBASE_ARCHIVE_FAKE_ENTRY_ITERATOR_ */
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <utime.h>
#include <dirent.h>
#include "ob_archive_fake_file_store.h"
namespace oceanbase
{
using namespace clog;
namespace archive
{
int ObArchiveFakeFileStore::init_for_dump(const char *path)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(path)) {
ret = OB_INVALID_ARGUMENT;
ARCHIVE_LOG(ERROR, "invalid argument", KR(ret), K(path));
} else {
MEMCPY(path_, path, MAX_PATH_LENGTH);
inited_ = true;
}
return ret;
}
int ObArchiveFakeFileStore::read_data_direct(const ObArchiveReadParam &param,
ObReadBuf &rbuf,
ObReadRes &res)
{
int ret = OB_SUCCESS;
int fd = 0;
if (OB_UNLIKELY(! inited_)) {
ret = OB_NOT_INIT;
ARCHIVE_LOG(WARN, "ObArchiveLogFileStore not init", K(ret), K(param));
} else if (-1 == (fd = ::open(path_, O_RDONLY))) {
ret = OB_IO_ERROR;
ARCHIVE_LOG(WARN, "open fail", K(ret), K(fd));
} else {
const int64_t buf_size = param.read_len_;
const int64_t offset = param.offset_;
int64_t read_size = 0;
int64_t one_read_size = 0;
while (OB_SUCC(ret) && read_size < buf_size) {
one_read_size = ::pread(fd, rbuf.buf_ + read_size, buf_size - read_size, offset + read_size);
if (0 == one_read_size) {
break;
} else if (one_read_size < 0) {
ret = OB_IO_ERROR;
ARCHIVE_LOG(ERROR, "one read size small than zero", K(ret));
} else {
read_size += one_read_size;
}
}
if (OB_SUCC(ret)) {
::close(fd);
res.buf_ = rbuf.buf_;
res.data_len_ = read_size;
}
}
return ret;
}
}
}
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_ARCHIVE_FAKE_FILE_STORE_
#define OCEANBASE_ARCHIVE_FAKE_FILE_STORE_
#include "archive/ob_archive_log_file_store.h"
#include "archive/ob_log_archive_struct.h"
#include "clog/ob_log_reader_interface.h"
namespace oceanbase
{
namespace archive
{
class ObArchiveFakeFileStore : public ObIArchiveLogFileStore
{
static const int64_t MAX_PATH_LENGTH = 1000;
public:
virtual int init_for_dump(const char *path);
virtual int read_data_direct(const ObArchiveReadParam &param,
clog::ObReadBuf &rbuf,
clog::ObReadRes &res);
private:
bool inited_;
char path_[MAX_PATH_LENGTH];
};
}
}
#endif /* OCEANBASE_ARCHIVE_FAKE_FILE_STORE_ */
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX ARCHIVE
#include "ob_fake_archive_log_file_store.h"
#include "archive/ob_log_archive_struct.h"
#include "clog/ob_log_reader_interface.h"
namespace oceanbase
{
using namespace clog;
using namespace common;
using namespace archive;
namespace tools
{
void ObFakeArchiveLogFileStore::reset()
{
is_inited_ = false;
is_last_file_ = true;
buf_ = NULL;
buf_len_ = -1;
file_id_ = -1;
}
int ObFakeArchiveLogFileStore::init(char *buf,
int64_t buf_len,
const int64_t file_id)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0 || file_id <=0)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), KP(buf), K(buf_len), K(file_id));
} else {
is_last_file_ = true;//工具默认每个文件都是最后一个文件, 末尾会有写失败的遗留数据
buf_ = buf;
buf_len_ = buf_len;
file_id_ = file_id;
is_inited_ = true;
}
return ret;
}
int ObFakeArchiveLogFileStore::get_file_meta(const uint64_t file_id,
bool &is_last_log_file,
int64_t &file_len)
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("not inited", K(ret));
} else if (OB_UNLIKELY(file_id_ != file_id)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid file_id", K(ret));
} else {
is_last_log_file = is_last_file_;
file_len = buf_len_;
}
return ret;
}
int ObFakeArchiveLogFileStore::read_data_direct(const ObArchiveReadParam &param,
clog::ObReadBuf &rbuf,
clog::ObReadRes &res)
{
int ret = OB_SUCCESS;
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("not inited", K(ret));
} else if (OB_UNLIKELY(!param.is_valid()
|| !rbuf.is_valid()
|| param.file_id_ != file_id_
|| param.read_len_ > rbuf.buf_len_)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), K(param), K(rbuf), K(buf_len_), K(file_id_));
} else if (param.offset_ + param.read_len_ > buf_len_) {
const int64_t data_len = buf_len_ - param.offset_;
MEMCPY(rbuf.buf_, buf_ + param.offset_, data_len);
res.buf_ = rbuf.buf_;
res.data_len_ = data_len;
} else {
MEMCPY(rbuf.buf_, buf_ + param.offset_, param.read_len_);
res.buf_ = rbuf.buf_;
res.data_len_ = param.read_len_;
}
return ret;
}
}//end of namespace
}
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OB_FAKE_ARCHIVE_LOG_FILE_STORE_H_
#define OB_FAKE_ARCHIVE_LOG_FILE_STORE_H_
#include "archive/ob_archive_log_file_store.h"
namespace oceanbase
{
namespace clog
{
struct ObReadBuf;
struct ObReadRes;
}
namespace archive
{
struct ObArchiveReadParam;
}
namespace tools
{
//used for ob_admin
class ObFakeArchiveLogFileStore : public archive::ObIArchiveLogFileStore
{
public:
ObFakeArchiveLogFileStore() {reset();}
virtual ~ObFakeArchiveLogFileStore(){reset();}
void reset();
public:
virtual int init() {return common::OB_NOT_SUPPORTED;};
int init(char *buf, int64_t buf_len, const int64_t file_id);
public:
virtual int get_file_meta(const uint64_t file_id, bool &is_last_log_file, int64_t &file_len);
/*param:读取日志的文件file_id, offset, len 等信息
* 因为源端存储介质的访问可能会出现卡住等情况,需要给本次读取加一个timeout
* 在超时之前,该接口必须返回
* 这个接口上层调用者保证offset+len未超过文件长度,filestore本身不需要判断
* 所读取的数据是否越界
* */
//TODO(yaoying.yyy):param file_id_t
virtual int read_data_direct(const archive::ObArchiveReadParam &param,
clog::ObReadBuf &rbuf,
clog::ObReadRes &res);
private:
bool is_inited_;
bool is_last_file_;
char *buf_;
int64_t buf_len_;
int64_t file_id_;
};
}//end of namespace tools
}//end of namespace oceanbase
#endif /* OB_FAKE_ARCHIVE_LOG_FILE_STORE_H_ */
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OB_ADMIN_DUMPBACKUP_EXECUTOR_H_
#define OB_ADMIN_DUMPBACKUP_EXECUTOR_H_
#include "../ob_admin_executor.h"
#include "../dumpsst/ob_admin_dumpsst_print_helper.h"
#include "lib/container/ob_array.h"
#include "share/backup/ob_backup_struct.h"
#include "share/backup/ob_extern_backup_info_mgr.h"
#include "share/backup/ob_log_archive_backup_info_mgr.h"
#include "storage/ob_partition_base_data_physical_restore.h"
#include "share/backup/ob_tenant_name_mgr.h"
#include "storage/blocksstable/ob_block_sstable_struct.h"
#include "storage/blocksstable/ob_macro_block_meta_mgr.h"
#include "storage/blocksstable/ob_store_file.h"
#include "storage/ob_i_table.h"
#include "observer/ob_server_struct.h"
#include "observer/ob_srv_network_frame.h"
#include "observer/omt/ob_worker_processor.h"
#include "observer/omt/ob_multi_tenant.h"
#include "storage/ob_i_table.h"
#include "storage/backup/ob_partition_backup_struct.h"
namespace oceanbase
{
namespace tools
{
typedef common::hash::ObHashMap<storage::ObITable::TableKey,
common::ObArray<storage::ObBackupTableMacroIndex> *> TableMacroIndexMap;
enum ObBackupMacroIndexVersion
{
BACKUP_MACRO_INDEX_VERSION_1, // before 2.2.77
BACKUP_MACRO_INDEX_VERSION_2, // after 3.1
};
class ObAdminDumpBackupDataReaderUtil
{
public:
static int get_data_type(
const char *data_path,
const char *storage_info,
ObBackupFileType &data_type);
static int get_backup_data_common_header(
const char *data_path,
const char *storage_info,
share::ObBackupCommonHeader &common_header);
static int get_backup_data(
const char *data_path,
const char *storage_info,
char *&buf,
int64_t &file_length,
common::ObIAllocator &allocator);
static int get_meta_index(
blocksstable::ObBufferReader &buffer_reader,
share::ObBackupCommonHeader &common_header,
common::ObIArray<ObBackupMetaIndex> &meta_index_array);
static int get_backup_data(
const char *data_path,
const char *storage_info,
char *&buf,
const int64_t offset,
const int64_t data_length,
common::ObIAllocator &allocator);
static int get_meta_header(
const char *buf,
const int64_t read_size,
share::ObBackupMetaHeader &common_header);
static int get_macro_block_index(
blocksstable::ObBufferReader &buffer_reader,
share::ObBackupCommonHeader &common_header,
common::ObIArray<ObBackupMacroIndex> &macro_index_array);
static int get_macro_block_index_v2(
blocksstable::ObBufferReader &buffer_reader,
common::ObIAllocator &allocator,
TableMacroIndexMap &map);
private:
static int add_sstable_index(
const storage::ObITable::TableKey &table_key,
const common::ObIArray<storage::ObBackupTableMacroIndex> &index_list,
common::ObIAllocator &allocator,
TableMacroIndexMap &index_map);
static int get_table_key_ptr(
common::ObIAllocator &allocator,
common::ObArray<storage::ObITable::TableKey *> &table_key_ptrs,
const storage::ObITable::TableKey &table_key,
const storage::ObITable::TableKey *&table_key_ptr);
};
class ObAdminDumpBackupDataExecutor : public ObAdminExecutor
{
public:
ObAdminDumpBackupDataExecutor();
virtual ~ObAdminDumpBackupDataExecutor();
virtual int execute(int argc, char *argv[]);
private:
int parse_cmd(int argc, char *argv[]);
void print_common_header();
void print_common_header(const share::ObBackupCommonHeader &common_header);
void print_meta_header(const share::ObBackupMetaHeader &meta_header);
void print_backup_info();
void print_backup_tenant_info();
void print_clog_backup_info();
void print_backup_set_info();
void print_backup_piece_info();
void print_backup_single_piece_info();
void print_backup_set_file_info();
void print_pg_list();
void print_meta_index();
int print_meta_index_(
const share::ObBackupCommonHeader &common_header,
const common::ObIArray<ObBackupMetaIndex> &meta_index_array);
void print_meta_data();
void print_partition_group_meta(
const char *buf,
const int64_t size);
void print_partition_meta(
const char *buf,
const int64_t size);
void print_sstable_meta(
const char *buf,
const int64_t size);
void print_table_keys(
const char *buf,
const int64_t size);
void print_partition_group_meta_info(
const char *buf,
const int64_t size);
void print_macro_data_index();
int get_macro_data_index_version(int64_t &version);
void print_macro_data_index_v1(
const char *buf,
const int64_t size);
int print_macro_data_index_v1_(
const share::ObBackupCommonHeader &common_header,
const common::ObIArray<ObBackupMacroIndex> &macro_index_array);
void print_macro_data_index_v2(
const char *buf,
const int64_t size);
int print_macro_data_index_v2_(
const TableMacroIndexMap &index_map);
void print_macro_block();
void print_tenant_name_info();
void print_tenant_name_info_meta(const ObTenantNameSimpleMgr::ObTenantNameMeta &meta);
void print_tenant_name_info(const int64_t idx,
const ObTenantNameSimpleMgr::ObTenantNameInfo &info);
void print_usage();
void print_macro_meta();
void print_super_block();
int dump_macro_block(const int64_t macro_id);
void dump_sstable();
void dump_sstable_meta();
int open_store_file();
void print_archive_block_meta();
void print_archive_index_file();
int check_exist(const char *data_path, const char *storage_info);
private:
static const int64_t MAX_BACKUP_ID_STR_LENGTH = 64;
private:
char data_path_[common::OB_MAX_URI_LENGTH];
char input_data_path_[common::OB_MAX_URI_LENGTH];
char storage_info_[share::OB_MAX_BACKUP_STORAGE_INFO_LENGTH];
share::ObBackupCommonHeader common_header_;
common::ObArenaAllocator allocator_;
bool is_quiet_;
int64_t offset_;
int64_t data_length_;
bool check_exist_;
};
} //namespace tools
} //namespace oceanbase
#endif /* OB_ADMIN_DUMPBACKUP_EXECUTOR_H_ */
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include "ob_admin_cmp_micro_executor.h"
#include "lib/compress/ob_compressor_pool.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
namespace oceanbase
{
using namespace common;
using namespace blocksstable;
using namespace storage;
namespace tools
{
int ObAdminCmpMicroExecutor::execute(int argc, char *argv[])
{
int ret = OB_SUCCESS;
if (OB_FAIL(parse_cmd(argc, argv))) {
STORAGE_LOG(WARN, "failed to parse_cmd", K(argc), K(ret));
} else if (OB_FAIL(open_file())) {
STORAGE_LOG(WARN, "failed to open file 1", K(ret));
} else if (OB_FAIL(read_header())){
STORAGE_LOG(WARN, "failed to read macro hreader", K(ret));
} else if (OB_FAIL(compare_micro())) {
STORAGE_LOG(WARN, "failed to compare micro", K(ret));
}
return ret;
}
int ObAdminCmpMicroExecutor::open_file()
{
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < 2; ++i) {
if (0 > (fd_[i] = ::open(data_file_path_[i], O_RDWR))) {
ret = OB_IO_ERROR;
STORAGE_LOG(WARN, "failed to open data_file", K(data_file_path_[i]), K(ret), K(errno), KERRMSG);
} else {
STORAGE_LOG(INFO, "open file success", K(data_file_path_[i]));
}
}
return ret;
}
int ObAdminCmpMicroExecutor::read_header()
{
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < 2; ++i) {
int64_t pos = 0;
ObMacroBlockCommonHeader commo_header;
if (NULL == (macro_buf_[i] = (char*)::malloc(MACRO_BLOCK_SIZE))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
STORAGE_LOG(WARN, "failed to allocate macro buffer", K(ret), K(i));
} else if (NULL == (uncomp_micro_[i] = (char*)::malloc(MACRO_BLOCK_SIZE))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
STORAGE_LOG(WARN, "failed to allocate micro buffer", K(ret), K(i));
} else if (0 > pread(fd_[i], macro_buf_[i], MACRO_BLOCK_SIZE, macro_id_[i] * MACRO_BLOCK_SIZE)) {
ret = OB_IO_ERROR;
STORAGE_LOG(WARN, "failed to read macro block", K(ret), K(i), K(macro_id_[i]), K(errno), KERRMSG);
} else if (OB_FAIL(commo_header.deserialize(macro_buf_[i], MACRO_BLOCK_SIZE, pos))) {
STORAGE_LOG(WARN, "failed to deserialize common header", K(ret), K(i), K(commo_header), K(pos));
} else {
header_[i] = reinterpret_cast<ObSSTableMacroBlockHeader*>(macro_buf_[i] + pos);
}
}
if (OB_SUCC(ret) && (header_[0]->micro_block_count_ != header_[1]->micro_block_count_
|| 0 != strcmp(header_[0]->compressor_name_, header_[1]->compressor_name_))) {
ret = OB_ERR_UNEXPECTED;
STORAGE_LOG(ERROR, "micro block count not match", K(*header_[0]), K(*header_[1]));
}
return ret;
}
int ObAdminCmpMicroExecutor::compare_micro()
{
int ret = OB_SUCCESS;
char *micro_data[2];
micro_data[0] = macro_buf_[0] + header_[0]->micro_block_data_offset_;
micro_data[1] = macro_buf_[1] + header_[1]->micro_block_data_offset_;
for (int64_t i = 0; OB_SUCC(ret) && i < header_[0]->micro_block_count_; ++i) {
for (int64_t idx = 0; OB_SUCC(ret) && idx < 2; ++idx) {
if (OB_FAIL(read_micro(micro_data[idx], idx))) {
STORAGE_LOG(WARN, "failed to read micro", K(ret), K(idx) , K(i));
}
}
if (record_header_[0].data_zlength_ != record_header_[1].data_zlength_
|| record_header_[0].data_length_ != record_header_[1].data_length_) {
STORAGE_LOG(WARN, "data length not equal", K(ret), K(record_header_[0]), K(record_header_[1]), K(i));
}
if (0 != MEMCMP(micro_buf_[0], micro_buf_[1], record_header_[0].data_zlength_)) {
STORAGE_LOG(WARN, "micro_buf not equal", K(i));
}
if (record_header_[0].data_length_ != record_header_[0].data_zlength_) {
for (int64_t idx = 0; OB_SUCC(ret) && idx < 2; ++idx) {
if (OB_FAIL(decompress_micro(idx))) {
STORAGE_LOG(WARN, "failed to read micro", K(ret), K(idx), K(i));
}
}
if (0 != MEMCMP(uncomp_micro_[0], uncomp_micro_[1], record_header_[0].data_length_)) {
print_micro_meta(0);
print_micro_meta(1);
for (int64_t c = 0; c < record_header_[0].data_length_; ++c) {
if (uncomp_micro_[0][c] != uncomp_micro_[1][c]) {
STORAGE_LOG(WARN, "found diff point", K(c), KPHEX(uncomp_micro_[0] + c, 1), KPHEX(uncomp_micro_[1] + c, 1));
break;
}
}
STORAGE_LOG(WARN, "uncomp_micro_ not equal", K(i), KPHEX(uncomp_micro_[0], record_header_[0].data_length_), KPHEX(uncomp_micro_[1], record_header_[1].data_length_));
}
}
}
return ret;
}
int ObAdminCmpMicroExecutor::read_micro(char *&micro_data, const int64_t idx)
{
char *cur_micro = micro_data;
record_header_[idx] = *reinterpret_cast<ObRecordHeaderV3*>(micro_data);
micro_data += record_header_[idx].get_serialize_size();
micro_buf_[idx] = micro_data;
micro_data += record_header_[idx].data_zlength_;
return ObRecordHeaderV3::deserialize_and_check_record(cur_micro, record_header_[idx].data_zlength_ + record_header_[idx].get_serialize_size(), MICRO_BLOCK_HEADER_MAGIC);
}
int ObAdminCmpMicroExecutor::decompress_micro(const int64_t idx)
{
int ret = OB_SUCCESS;
ObCompressor *compressor = NULL;
int64_t uncomp_size = 0;
if (OB_FAIL(ObCompressorPool::get_instance().get_compressor(header_[idx]->compressor_name_, compressor))) {
STORAGE_LOG(WARN, "failed to get compressor", K(ret), K(header_[idx]->compressor_name_));
} else if (OB_FAIL(compressor->decompress(micro_buf_[idx], record_header_[idx].data_zlength_, uncomp_micro_[idx], MACRO_BLOCK_SIZE, uncomp_size))) {
STORAGE_LOG(WARN, "failed to decompress", K(ret) , K(idx), K(record_header_[idx]));
} else if (uncomp_size != record_header_[idx].data_length_) {
ret = OB_ERR_UNEXPECTED;
STORAGE_LOG(ERROR, "uncomp size not match", K(uncomp_size), K(record_header_[idx]));
} else {
STORAGE_LOG(INFO, "decompress success", K(uncomp_size), K(record_header_[idx].data_length_), K(idx));
}
return ret;
}
int ObAdminCmpMicroExecutor::parse_cmd(int argc, char *argv[])
{
int ret = OB_SUCCESS;
int opt = 0;
const char* opt_string = "a:b:c:d:";
struct option longopts[] = {
// commands
{ "data_dir_0", 1, NULL, 'a' },
// options
{ "data_dir_1", 1, NULL, 'b' },
{ "macro-id-0", 1, NULL, 'c' },
{ "macro-id-1", 1, NULL, 'd' },
};
int index = -1;
while ((opt = getopt_long(argc, argv, opt_string, longopts, &index)) != -1) {
switch (opt) {
case 'a': {
if (OB_FAIL(databuff_printf(data_file_path_[0], OB_MAX_FILE_NAME_LENGTH, "%s/%s/%s",
optarg, BLOCK_SSTBALE_DIR_NAME, BLOCK_SSTBALE_FILE_NAME))) {
STORAGE_LOG(WARN, "failed to databuff_printf block file path", K(ret), K(optarg));
}
break;
}
case 'b': {
if (OB_FAIL(databuff_printf(data_file_path_[1], OB_MAX_FILE_NAME_LENGTH, "%s/%s/%s",
optarg, BLOCK_SSTBALE_DIR_NAME, BLOCK_SSTBALE_FILE_NAME))) {
STORAGE_LOG(WARN, "failed to databuff_printf block file path", K(ret), K(optarg));
}
break;
}
case 'c': {
macro_id_[0] = strtoll(optarg, NULL, 10);
break;
}
case 'd': {
macro_id_[1] = strtoll(optarg, NULL, 10);
break;
}
default: {
exit(1);
}
}
}
return ret;
}
void ObAdminCmpMicroExecutor::print_micro_meta(const int64_t idx)
{
ObMicroBlockHeaderV2 *micro_header = reinterpret_cast<ObMicroBlockHeaderV2*>(uncomp_micro_[idx]);
STORAGE_LOG(INFO, "micro meta", K(idx), K(*micro_header));
}
}
}
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_TOOLS_OB_ADMIN_CMP_MICRO_EXECUTOR_H
#define OCEANBASE_TOOLS_OB_ADMIN_CMP_MICRO_EXECUTOR_H
#include "../ob_admin_executor.h"
#include "storage/blocksstable/ob_block_sstable_struct.h"
namespace oceanbase
{
namespace tools
{
class ObAdminCmpMicroExecutor : public ObAdminExecutor
{
public:
ObAdminCmpMicroExecutor() {}
virtual ~ObAdminCmpMicroExecutor() {}
virtual int execute(int argc, char *argv[]);
private:
int parse_cmd(int argc, char *argv[]);
int open_file();
int read_header();
int compare_micro();
int read_micro(char *&micro_data, const int64_t idx);
int decompress_micro(const int64_t idx);
void print_micro_meta(const int64_t idx);
private:
static const int64_t MACRO_BLOCK_SIZE = 2 << 20;
char data_file_path_[2][common::OB_MAX_FILE_NAME_LENGTH];
int64_t macro_id_[2];
int fd_[2];
blocksstable::ObRecordHeaderV3 record_header_[2];
char *micro_buf_[2];
char *uncomp_micro_[2];
char *macro_buf_[2];
blocksstable::ObSSTableMacroBlockHeader *header_[2];
};
}
}
#endif /* OCEANBASE_TOOLS_OB_ADMIN_CMP_MICRO_EXECUTOR_H */
此差异已折叠。
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OB_ADMIN_DUMPSST_EXECUTOR_H_
#define OB_ADMIN_DUMPSST_EXECUTOR_H_
#include "../ob_admin_executor.h"
#include "lib/container/ob_array.h"
#include "share/config/ob_config_manager.h"
#include "storage/blocksstable/ob_block_sstable_struct.h"
#include "storage/blocksstable/ob_macro_block_meta_mgr.h"
#include "storage/blocksstable/ob_store_file.h"
#include "storage/ob_i_table.h"
#include "observer/ob_server_struct.h"
#include "observer/ob_srv_network_frame.h"
#include "observer/omt/ob_worker_processor.h"
#include "observer/omt/ob_multi_tenant.h"
#include "observer/ob_server_reload_config.h"
#include "storage/blocksstable/ob_store_file_system.h"
#include "storage/ob_tenant_file_super_block_checkpoint_reader.h"
#include "storage/ob_server_pg_meta_checkpoint_reader.h"
namespace oceanbase
{
namespace storage
{
class ObBaseFileMgr;
class ObPartitionMetaRedoModule;
}
namespace tools
{
enum ObAdminDumpsstCmd
{
DUMP_MACRO_META,
DUMP_SUPER_BLOCK,
DUMP_MACRO_DATA,
PRINT_MACRO_BLOCK,
DUMP_SSTABLE,
DUMP_SSTABLE_META,
DUMP_MAX,
};
struct ObDumpMacroBlockContext final
{
public:
ObDumpMacroBlockContext()
: macro_id_(-1), micro_id_(-1), tenant_id_(common::OB_INVALID_ID), file_id_(-1)
{}
~ObDumpMacroBlockContext() = default;
bool is_valid() const { return macro_id_ >= 0; }
TO_STRING_KV(K_(macro_id), K_(micro_id), K_(tenant_id), K_(file_id));
int64_t macro_id_;
int64_t micro_id_;
uint64_t tenant_id_;
int64_t file_id_;
};
class ObAdminDumpsstExecutor : public ObAdminExecutor
{
public:
ObAdminDumpsstExecutor();
virtual ~ObAdminDumpsstExecutor();
virtual int execute(int argc, char *argv[]);
private:
int parse_cmd(int argc, char *argv[]);
void print_macro_block();
void print_usage();
void print_macro_meta();
void print_super_block();
int dump_macro_block(const ObDumpMacroBlockContext &context);
void dump_sstable();
void dump_sstable_meta();
int open_store_file();
int load_config();
int replay_slog_to_get_sstable(storage::ObSSTable *&sstable);
blocksstable::ObStorageEnv storage_env_;
char data_dir_[common::OB_MAX_FILE_NAME_LENGTH];
char slog_dir_[common::OB_MAX_FILE_NAME_LENGTH];
char clog_dir_[common::OB_MAX_FILE_NAME_LENGTH];
char ilog_dir_[common::OB_MAX_FILE_NAME_LENGTH];
char clog_shm_path_[common::OB_MAX_FILE_NAME_LENGTH];
char ilog_shm_path_[common::OB_MAX_FILE_NAME_LENGTH];
char sstable_dir_[common::OB_MAX_FILE_NAME_LENGTH];
bool is_quiet_;
bool in_csv_;
ObAdminDumpsstCmd cmd_;
storage::ObITable::TableKey table_key_;
bool skip_log_replay_;
ObDumpMacroBlockContext dump_macro_context_;
observer::ObServerReloadConfig reload_config_;
common::ObConfigManager config_mgr_;
};
class ObAdminSlogReplayer final
{
public:
explicit ObAdminSlogReplayer(storage::ObBaseFileMgr &file_mgr,
storage::ObPartitionMetaRedoModule &pg_mgr,
char *slog_dir);
virtual ~ObAdminSlogReplayer();
int replay_slog();
int init();
void reset();
int get_sstable(storage::ObITable::TableKey table_key, storage::ObSSTable *&sstable);
private:
int read_checkpoint_and_replay_log(common::ObLogCursor &checkpoint);
int replay_server_slog(
const char *slog_dir,
const common::ObLogCursor &replay_start_cursor,
const blocksstable::ObStorageLogCommittedTransGetter &committed_trans_getter);
int replay_pg_slog(const char *slog_dir,
const common::ObLogCursor &replay_start_cursor,
const blocksstable::ObStorageLogCommittedTransGetter &committed_trans_getter,
common::ObLogCursor &checkpoint);
private:
class ServerMetaSLogFilter : public blocksstable::ObISLogFilter
{
public:
ServerMetaSLogFilter() = default;
virtual ~ServerMetaSLogFilter() = default;
virtual int filter(const ObISLogFilter::Param &param, bool &is_filtered) const override;
};
class PGMetaSLogFilter : public blocksstable::ObISLogFilter
{
public:
explicit PGMetaSLogFilter(storage::ObBaseFileMgr &file_mgr) : file_mgr_(file_mgr) {};
virtual ~PGMetaSLogFilter() = default;
virtual int filter(const ObISLogFilter::Param &param, bool &is_filtered) const override;
private:
storage::ObBaseFileMgr &file_mgr_;
};
const common::ObAddr svr_addr_;
blocksstable::ObStorageFileWithRef svr_root_;
storage::ObBaseFileMgr &file_mgr_;
storage::ObPartitionMetaRedoModule &pg_mgr_;
blocksstable::ObServerSuperBlock super_block_;
storage::ObServerPGMetaCheckpointReader pg_meta_reader_;
storage::ObTenantFileSuperBlockCheckpointReader tenant_file_reader_;
char *slog_dir_;
DISALLOW_COPY_AND_ASSIGN(ObAdminSlogReplayer);
};
} //namespace tools
} //namespace oceanbase
#endif /* OB_ADMIN_DUMPSST_EXECUTOR_H_ */
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include "ob_admin_dumpsst_print_helper.h"
namespace oceanbase
{
using namespace storage;
using namespace common;
using namespace blocksstable;
namespace tools
{
const std::string PrintHelper::term(",");
const std::string PrintHelper::trans_term("\\,");
#define FPRINTF(args...) fprintf(stderr, ##args)
#define P_BAR() FPRINTF("|")
#define P_DASH() FPRINTF("------------------------------")
#define P_END_DASH() FPRINTF("--------------------------------------------------------------------------------")
#define P_NAME(key) FPRINTF("%s", (key))
#define P_NAME_FMT(key) FPRINTF("%30s", (key))
#define P_VALUE_STR_B(key) FPRINTF("[%s]", (key))
#define P_VALUE_INT_B(key) FPRINTF("[%d]", (key))
#define P_VALUE_BINT_B(key) FPRINTF("[%ld]", (key))
#define P_VALUE_STR(key) FPRINTF("%s", (key))
#define P_VALUE_INT(key) FPRINTF("%d", (key))
#define P_VALUE_BINT(key) FPRINTF("%ld", (key))
#define P_NAME_BRACE(key) FPRINTF("{%s}", (key))
#define P_COLOR(color) FPRINTF(color)
#define P_LB() FPRINTF("[")
#define P_RB() FPRINTF("]")
#define P_LBRACE() FPRINTF("{")
#define P_RBRACE() FPRINTF("}")
#define P_COLON() FPRINTF(":")
#define P_COMMA() FPRINTF(",")
#define P_TAB() FPRINTF("\t")
#define P_LINE_NAME(key) FPRINTF("%30s", (key))
#define P_LINE_VALUE(key, type) P_LINE_VALUE_##type((key))
#define P_LINE_VALUE_INT(key) FPRINTF("%-30d", (key))
#define P_LINE_VALUE_BINT(key) FPRINTF("%-30ld", (key))
#define P_LINE_VALUE_STR(key) FPRINTF("%-30s", (key))
#define P_END() FPRINTF("\n")
#define P_TAB_LEVEL(level) \
do { \
for (int64_t i = 1; i < (level); ++i) { \
P_TAB(); \
if (i != level - 1) P_BAR(); \
} \
} while (0)
#define P_DUMP_LINE(type) \
do { \
P_TAB_LEVEL(level); \
P_BAR(); \
P_LINE_NAME(name); \
P_BAR(); \
P_LINE_VALUE(value, type); \
P_END(); \
} while (0)
#define P_DUMP_LINE_COLOR(type) \
do { \
P_COLOR(LIGHT_GREEN); \
P_TAB_LEVEL(level); \
P_BAR(); \
P_COLOR(CYAN); \
P_LINE_NAME(name); \
P_BAR(); \
P_COLOR(NONE_COLOR); \
P_LINE_VALUE(value, type); \
P_END(); \
} while (0)
void PrintHelper::print_dump_title(const char *title, const int64_t level)
{
if (isatty(fileno(stderr))) {
P_COLOR(LIGHT_GREEN);
}
P_TAB_LEVEL(level);
P_DASH();
P_NAME_BRACE(title);
P_DASH();
P_END();
}
void PrintHelper::print_end_line(const int64_t level)
{
if (isatty(fileno(stderr))) {
P_COLOR(LIGHT_GREEN);
}
P_TAB_LEVEL(level);
P_END_DASH();
P_END();
if (isatty(fileno(stderr))) {
P_COLOR(NONE_COLOR);
}
}
void PrintHelper::print_dump_title(const char *title, const int64_t &value, const int64_t level)
{
if (isatty(fileno(stderr))) {
P_COLOR(LIGHT_GREEN);
}
P_TAB_LEVEL(level);
P_DASH();
P_LBRACE();
P_NAME(title);
P_VALUE_BINT_B(value);
P_RBRACE();
P_DASH();
P_END();
if (isatty(fileno(stderr))) {
P_COLOR(NONE_COLOR);
}
}
void PrintHelper::print_dump_line(const char *name, const uint32_t &value, const int64_t level)
{
if (isatty(fileno(stderr))) {
P_DUMP_LINE_COLOR(INT);
} else {
P_DUMP_LINE(INT);
}
}
void PrintHelper::print_dump_line(const char *name, const uint64_t &value, const int64_t level)
{
if (isatty(fileno(stderr))) {
P_DUMP_LINE_COLOR(BINT);
} else {
P_DUMP_LINE(BINT);
}
}
void PrintHelper::print_dump_line(const char *name, const int32_t &value, const int64_t level)
{
if (isatty(fileno(stderr))) {
P_DUMP_LINE_COLOR(INT);
} else {
P_DUMP_LINE(INT);
}
}
void PrintHelper::print_dump_line(const char *name, const int64_t &value, const int64_t level)
{
if (isatty(fileno(stderr))) {
P_DUMP_LINE_COLOR(BINT);
} else {
P_DUMP_LINE(BINT);
}
}
void PrintHelper::print_dump_line(const char *name, const char *value, const int64_t level)
{
if (isatty(fileno(stderr))) {
P_DUMP_LINE_COLOR(STR);
} else {
P_DUMP_LINE(STR);
}
}
void PrintHelper::print_dump_list_start(const char *name, const int64_t level)
{
if (isatty(fileno(stderr))) {
P_COLOR(LIGHT_GREEN);
P_TAB_LEVEL(level);
P_BAR();
P_COLOR(CYAN);
P_NAME_FMT(name);
P_BAR();
P_COLOR(NONE_COLOR);
P_LB();
} else {
P_TAB_LEVEL(level);
P_BAR();
P_NAME_FMT(name);
P_BAR();
P_LB();
}
}
void PrintHelper::print_dump_list_value(const int64_t &value, const bool is_last)
{
P_VALUE_BINT(value);
if (!is_last) {
P_COMMA();
}
}
void PrintHelper::print_dump_list_value(const int32_t &value, const bool is_last)
{
P_VALUE_INT(value);
if (!is_last) {
P_COMMA();
}
}
void PrintHelper::print_dump_list_value(const char *value, const bool is_last)
{
P_VALUE_STR(value);
if (!is_last) {
P_COMMA();
}
}
void PrintHelper::print_dump_list_end()
{
if (isatty(fileno(stderr))) {
P_RB();
P_END();
P_COLOR(NONE_COLOR);
} else {
P_RB();
P_END();
}
}
void PrintHelper::print_dump_cols_info_start(const char *n1, const char *n2, const char *n3, const char *n4)
{
if (isatty(fileno(stderr))) {
P_COLOR(LIGHT_GREEN);
}
FPRINTF("--------{%-15s %15s %15s %15s}----------\n", n1, n2, n3, n4);
}
void PrintHelper::print_dump_cols_info_line(const int32_t &v1, const char *v2, const int64_t &v3, const int64_t &v4)
{
if (isatty(fileno(stderr))) {
P_COLOR(LIGHT_GREEN);
P_BAR();
P_COLOR(NONE_COLOR);
FPRINTF("\t[%-15d %15s %15ld %15ld]\n", v1, v2, v3, v4);
} else {
P_BAR();
FPRINTF("\t[%-15d %15s %15ld %15ld]\n", v1, v2, v3, v4);
}
}
void PrintHelper::print_row_title(const bool use_csv, const ObStoreRow *row, const int64_t row_index)
{
// print title
if (!use_csv) {
if (isatty(fileno(stderr))) {
P_COLOR(LIGHT_GREEN);
P_BAR();
P_COLOR(CYAN);
P_NAME("ROW");
P_VALUE_BINT_B(row_index);
P_COLON();
if (OB_NOT_NULL(row->trans_id_ptr_)) {
P_NAME("trans_id=");
P_VALUE_BINT_B(row->trans_id_ptr_->hash());
P_COMMA();
} else {
P_NAME("trans_id=");
P_VALUE_INT_B(0);
P_COMMA();
}
P_NAME("flag=");
P_VALUE_BINT_B(row->flag_);
P_COMMA();
P_NAME("first_dml=");
P_VALUE_INT_B(row->get_first_dml());
P_COMMA();
P_NAME("dml=");
P_VALUE_INT_B(row->get_dml());
P_COMMA();
P_NAME("multi_version_row_flag=");
P_VALUE_INT_B(row->row_type_flag_.flag_);
P_BAR();
P_COLOR(NONE_COLOR);
} else {
P_BAR();
P_NAME("ROW");
P_VALUE_BINT_B(row_index);
P_COLON();
if (OB_NOT_NULL(row->trans_id_ptr_)) {
P_NAME("trans_id=");
P_VALUE_BINT_B(row->trans_id_ptr_->hash());
P_COMMA();
} else {
P_NAME("trans_id=");
P_VALUE_INT_B(0);
P_COMMA();
}
P_NAME("flag=");
P_VALUE_BINT_B(row->flag_);
P_COMMA();
P_NAME("first_dml=");
P_VALUE_INT_B(row->get_first_dml());
P_COMMA();
P_NAME("dml=");
P_VALUE_INT_B(row->get_dml());
P_COMMA();
P_NAME("multi_version_row_flag=");
P_VALUE_INT_B(row->row_type_flag_.flag_);
P_BAR();
}
}
}
void PrintHelper::print_cell(const ObObj &cell, const bool use_csv)
{
if (!use_csv) {
P_VALUE_STR_B(to_cstring(cell));
} else {
int64_t pos = 0;
char buf[MAX_BUF_SIZE];
cell.print_sql_literal(buf, MAX_BUF_SIZE, pos);
P_NAME(buf);
P_COMMA();
}
}
void PrintHelper::replace_all(std::string &str, const std::string &from, const std::string &to)
{
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length();
}
}
}
}
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <string.h>
#include <stdint.h>
#include "storage/blocksstable/ob_block_sstable_struct.h"
#define NONE_COLOR "\033[m"
#define RED "\033[0;32;31m"
#define LIGHT_RED "\033[1;31m"
#define GREEN "\033[0;32;32m"
#define LIGHT_GREEN "\033[1;32m"
#define BLUE "\033[0;32;34m"
#define LIGHT_BLUE "\033[1;34m"
#define DARY_GRAY "\033[1;30m"
#define CYAN "\033[0;36m"
#define LIGHT_CYAN "\033[1;36m"
#define PURPLE "\033[0;35m"
#define LIGHT_PURPLE "\033[1;35m"
#define BROWN "\033[0;33m"
#define YELLOW "\033[1;33m"
#define LIGHT_GRAY "\033[0;37m"
//#define WHITE "\033[1;37m"
namespace oceanbase
{
namespace tools
{
static const int64_t MAX_BUF_SIZE = 65 * 1024L;
class PrintHelper
{
public:
static const std::string term;
static const std::string trans_term;
static void print_dump_title(const char *name, const int64_t &value, const int64_t level = 1);
static void print_dump_title(const char *name, const int64_t level = 1);
static void print_dump_line(const char *name, const int32_t &value, const int64_t level = 1);
static void print_dump_line(const char *name, const int64_t &value, const int64_t level = 1);
static void print_dump_line(const char *name, const uint32_t &value, const int64_t level = 1);
static void print_dump_line(const char *name, const uint64_t &value, const int64_t level = 1);
static void print_dump_line(const char *name, const char *value, const int64_t level = 1);
static void print_row_title(const bool use_csv, const storage::ObStoreRow *row, const int64_t row_index);
static void print_cell(const common::ObObj &cell, const bool use_csv);
static void print_end_line(const int64_t level = 1);
static void print_dump_list_start(const char *name, const int64_t level = 1);
static void print_dump_list_end();
static void print_dump_list_value(const int64_t &value, const bool is_last);
static void print_dump_list_value(const int32_t &value, const bool is_last);
static void print_dump_list_value(const char *value, const bool is_last);
static void print_dump_cols_info_start(const char *n1, const char *n2,
const char *n3, const char *n4);
static void print_dump_cols_info_line(const int32_t &v1, const char *v2,
const int64_t &v3, const int64_t & v4);
private:
static void replace_all(std::string &str, const std::string &from, const std::string &to);
};
}
}
此差异已折叠。
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <unistd.h>
#include "common/rowkey/ob_rowkey.h"
#include "storage/ob_i_store.h"
#include "storage/ob_partition_store.h"
#include "storage/blocksstable/ob_column_map.h"
#include "storage/blocksstable/ob_block_sstable_struct.h"
#include "storage/blocksstable/ob_macro_block_common_header.h"
#include "storage/blocksstable/slog/ob_base_storage_logger.h"
#include "ob_admin_dumpsst_print_helper.h"
#define ALLOC_OBJECT_1(allocator, obj, T, ...) \
do \
{ \
obj = NULL; \
void *tmp = reinterpret_cast<void *>(allocator.alloc(sizeof(T))); \
if (NULL == tmp) \
{ \
_OB_LOG(WARN, "alloc mem for %s", #T); \
} \
else \
{ \
obj = new(tmp) T( __VA_ARGS__ ); \
} \
} \
while (0)
namespace oceanbase
{
namespace tools
{
int parse_string(const char* src, const char del, const char* dst[], int64_t& size);
int parse_table_key(const char *str, storage::ObITable::TableKey &table_key);
int parse_partition_key(const char *str, ObPartitionKey &pkey);
int parse_version_range(const char *str, ObVersionRange &version_range);
int parse_log_ts_range(const char *str, ObLogTsRange &log_ts_range);
struct DataBlock
{
DataBlock() : data_(NULL), size_(0) {}
const char *data_;
int64_t size_;
void reset()
{
data_ = NULL;
size_ = 0;
}
};
struct MacroBlock : public DataBlock
{
MacroBlock() : DataBlock(), macro_id_(-1), common_header_() {}
int setup(const char *data, const int64_t size, const int64_t macro_id);
bool is_valid() const
{
return macro_id_ >= 0
&& data_ != NULL
&& size_ > 0
&& common_header_.is_valid();
}
void reset()
{
macro_id_ = -1;
common_header_.reset();
DataBlock::reset();
}
TO_STRING_KV(KP_(data),
K_(size),
K_(macro_id));
int64_t macro_id_;
blocksstable::ObMacroBlockCommonHeader common_header_;
};
struct MicroBlock : public DataBlock
{
MicroBlock() : DataBlock(),
row_store_type_(-1),
micro_id_(-1),
column_map_(NULL),
column_id_list_(NULL),
column_cnt_(0)
{}
int setup(const char *data, const int64_t size, const int64_t micro_id,
const blocksstable::ObColumnMap *column_map, const int64_t row_store_type,
const uint16_t *column_id_list, const int64_t column_cnt);
void reset()
{
row_store_type_ = -1;
column_map_ = NULL;
micro_id_ = -1;
column_cnt_ = 0;
column_id_list_ = NULL;
DataBlock::reset();
}
bool is_valid() const
{
return data_ != NULL
&& size_ > 0
&& micro_id_ >= 0
&& column_map_ != NULL
&& column_id_list_ != NULL
&& column_cnt_ > 0;
}
TO_STRING_KV(KP_(data),
K_(size),
K_(micro_id),
K_(row_store_type),
K_(column_cnt));
int64_t row_store_type_;
int64_t micro_id_;
const blocksstable::ObColumnMap *column_map_;
const uint16_t *column_id_list_;
int64_t column_cnt_;
};
template <typename T>
class DataBlockReader
{
public:
virtual int64_t count() const = 0;
virtual int set_index(const int64_t index) = 0;
virtual int64_t get_index() const = 0;
virtual int get_value(const T *&value) = 0;
virtual int dump(const int64_t index) = 0;
public:
static void dump_common_header(const blocksstable::ObMacroBlockCommonHeader *common_header);
static void dump_sstable_header(const blocksstable::ObSSTableMacroBlockHeader *sstable_header);
static void dump_linked_header(const blocksstable::ObLinkedMacroBlockHeader *linked_header);
static void dump_row(const storage::ObStoreRow *row, const bool use_csv = false);
};
template <typename T>
void DataBlockReader<T>::dump_common_header(const blocksstable::ObMacroBlockCommonHeader *common_header)
{
PrintHelper::print_dump_title("Common Header");
fprintf(stdout, "%s\n", to_cstring(*common_header));
PrintHelper::print_end_line();
}
template <typename T>
void DataBlockReader<T>::dump_sstable_header(const blocksstable::ObSSTableMacroBlockHeader *sstable_header)
{
PrintHelper::print_dump_title("SSTable Header");
PrintHelper::print_dump_line("header_size", sstable_header->header_size_);
PrintHelper::print_dump_line("version", sstable_header->version_);
PrintHelper::print_dump_line("magic", sstable_header->magic_);
PrintHelper::print_dump_line("attr", sstable_header->attr_);
PrintHelper::print_dump_line("table_id", sstable_header->table_id_);
PrintHelper::print_dump_line("data_version", sstable_header->data_version_);
PrintHelper::print_dump_line("column_count", sstable_header->column_count_);
PrintHelper::print_dump_line("rowkey_column_count", sstable_header->rowkey_column_count_);
PrintHelper::print_dump_line("row_store_type", sstable_header->row_store_type_);
PrintHelper::print_dump_line("row_count", sstable_header->row_count_);
PrintHelper::print_dump_line("occupy_size", sstable_header->occupy_size_);
PrintHelper::print_dump_line("micro_block_count", sstable_header->micro_block_count_);
PrintHelper::print_dump_line("micro_block_size", sstable_header->micro_block_size_);
PrintHelper::print_dump_line("micro_block_data_offset", sstable_header->micro_block_data_offset_);
PrintHelper::print_dump_line("micro_block_index_offset", sstable_header->micro_block_index_offset_);
PrintHelper::print_dump_line("micro_block_index_size", sstable_header->micro_block_index_size_);
PrintHelper::print_dump_line("micro_block_endkey_offset", sstable_header->micro_block_endkey_offset_);
PrintHelper::print_dump_line("micro_block_endkey_size", sstable_header->micro_block_endkey_size_);
PrintHelper::print_dump_line("data_checksum", sstable_header->data_checksum_);
PrintHelper::print_dump_line("compressor_name", sstable_header->compressor_name_);
PrintHelper::print_dump_line("data_seq", sstable_header->data_seq_);
PrintHelper::print_dump_line("partition_id", sstable_header->partition_id_);
PrintHelper::print_end_line();
}
template <typename T>
void DataBlockReader<T>::dump_linked_header(const blocksstable::ObLinkedMacroBlockHeader *linked_header)
{
PrintHelper::print_dump_title("Lined Header");
PrintHelper::print_dump_line("header_size", linked_header->header_size_);
PrintHelper::print_dump_line("version", linked_header->version_);
PrintHelper::print_dump_line("magic", linked_header->magic_);
PrintHelper::print_dump_line("attr", linked_header->attr_);
PrintHelper::print_dump_line("meta_data_offset", linked_header->meta_data_offset_);
PrintHelper::print_dump_line("meta_data_count", linked_header->meta_data_count_);
PrintHelper::print_dump_line("previous_block_index", linked_header->previous_block_index_);
PrintHelper::print_dump_line("total_previous_count", linked_header->total_previous_count_);
PrintHelper::print_dump_line("user_data1", linked_header->user_data1_);
PrintHelper::print_dump_line("user_data1", linked_header->user_data2_);
PrintHelper::print_end_line();
}
template <typename T>
void DataBlockReader<T>::dump_row(const storage::ObStoreRow *row, const bool use_csv)
{
for (int64_t i = 0; i < row->row_val_.count_; ++i) {
common::ObObj &cell = row->row_val_.cells_[i];
PrintHelper::print_cell(cell, use_csv);
}
fprintf(stderr, "\n");
}
class MacroBlockReader : public DataBlockReader<MicroBlock>
{
public:
MacroBlockReader() : sstable_header_(NULL),
macro_meta_(NULL),
column_id_list_(NULL),
column_type_list_(NULL),
column_checksum_(NULL),
curr_micro_block_id_(-1),
cur_mib_rh_(NULL),
is_inited_(false)
{}
virtual ~MacroBlockReader() {};
int init(const char *data, const int64_t size, const int64_t macro_id, const blocksstable::ObMacroBlockMeta *macro_meta);
virtual int64_t count() const override;
virtual int set_index(const int64_t index) override;
virtual int64_t get_index() const override;
virtual int get_value(const MicroBlock *&value) override;
virtual int dump(const int64_t micro_id) override;
void reset();
private:
int parse_micro_block_index();
void dump_micro_index(const ObRowkey& endkey, const blocksstable::ObPosition& datapos,
const blocksstable::ObPosition& keypos, const bool mark_deletion, int32_t num);
int parse_micro_block_key(const char* buf, int64_t& pos, int64_t row_end_pos,
const ObObjMeta* type_list, ObObj* objs, int32_t rowkey_count);
void parse_one_micro_block_index(const char* index_ptr, const int64_t idx,
blocksstable::ObPosition& datapos, blocksstable::ObPosition& keypos);
int build_column_map();
int set_current_micro_block();
int dump_header();
int get_micro_block_payload_buffer(const char* compressor_name,
const char* buf,
const int64_t size,
const char*& out,
int64_t& outsize,
const blocksstable::ObRecordHeaderV3 *&rh);
private:
static const int64_t ALL_MINOR_INDEX = -1;
MacroBlock macro_block_;
const blocksstable::ObSSTableMacroBlockHeader *sstable_header_;
const blocksstable::ObMacroBlockMeta *macro_meta_;
const uint16_t * column_id_list_;
const common::ObObjMeta *column_type_list_;
const int64_t *column_checksum_;
int64_t curr_micro_block_id_;
MicroBlock curr_micro_block_;
common::ObSEArray<blocksstable::ObPosition, 100> micro_index_pos_;
common::ObSEArray<blocksstable::ObPosition, 100> micro_index_keys_;
common::ObSEArray<bool, 100> micro_mark_deletions_;
blocksstable::ObColumnMap column_map_;
const blocksstable::ObRecordHeaderV3 *cur_mib_rh_;
common::ObArenaAllocator allocator_;
bool is_inited_;
};
class MicroBlockIReader : public DataBlockReader<storage::ObStoreRow>
{
public:
virtual int64_t count() const = 0;
virtual int set_index(const int64_t index) = 0;
virtual int64_t get_index() const = 0;
virtual int get_value(const storage::ObStoreRow *&value) = 0;
virtual int dump(const int64_t index) = 0;
virtual int init(const MicroBlock &micro_block) = 0;
};
class FlatMicroBlockReader : public MicroBlockIReader
{
public:
FlatMicroBlockReader() : micro_block_header_(NULL),
index_buffer_(NULL),
curr_row_index_(0),
is_inited_(false)
{}
virtual int init(const MicroBlock &micro_block) override;
virtual int64_t count() const override;
virtual int set_index(const int64_t index) override;
virtual int64_t get_index() const override;
virtual int get_value(const storage::ObStoreRow *&value) override;
virtual int dump(const int64_t index) override;
void reset();
private:
static void dump_micro_header(const blocksstable::ObMicroBlockHeader* micro_block_header);
private:
MicroBlock micro_block_;
const blocksstable::ObMicroBlockHeader *micro_block_header_;
const int32_t *index_buffer_;
blocksstable::ObFlatRowReader reader_;
int64_t curr_row_index_;
common::ObObj columns_[common::OB_MAX_COLUMN_NUMBER];
storage::ObStoreRow curr_row_;
common::ObArenaAllocator allocator_;
bool is_inited_;
};
class MicroBlockReader : public DataBlockReader<storage::ObStoreRow>
{
public:
MicroBlockReader() : micro_reader_(NULL), is_inited_(false) {}
int init(const MicroBlock &micro_block);
virtual int64_t count() const override;
virtual int set_index(const int64_t index) override;
virtual int64_t get_index() const override;
virtual int get_value(const storage::ObStoreRow *&value) override;
virtual int dump(const int64_t index) override;
void reset();
private:
MicroBlock micro_block_;
MicroBlockIReader *micro_reader_;
FlatMicroBlockReader flat_micro_reader_;
bool is_inited_;
};
class ObDumpsstPartition
{
public:
int deserialize(const char *buf, const int64_t buf_len, int64_t &pos);
int get_latest_store();
private:
storage::ObPartitionStore store_;
};
class ObDumpsstPartitionImage : public blocksstable::ObIRedoModule
{
public:
static ObDumpsstPartitionImage &get_instance();
int init();
virtual int replay(const blocksstable::ObRedoModuleReplayParam &param) override
{
UNUSEDx(param);
return common::OB_SUCCESS;
}
virtual int parse(
const int64_t subcmd,
const char *buf,
const int64_t len,
FILE *stream) override
{
UNUSEDx(subcmd, buf, len, stream);
return common::OB_SUCCESS;
}
private:
ObDumpsstPartitionImage() {}
~ObDumpsstPartitionImage() {}
};
}
}
......@@ -18,6 +18,11 @@
#include "ob_admin_executor.h"
#include "clog_tool/ob_admin_clog_v2_executor.h"
#include "usec_tool/ob_admin_usec_executor.h"
#include "slog_tool/ob_admin_slog_executor.h"
#include "dumpsst/ob_admin_dumpsst_executor.h"
#include "dumpsst/ob_admin_cmp_micro_executor.h"
#include "archive_tool/ob_admin_log_archive_executor.h"
#include "backup_tool/ob_admin_dump_backup_data_executor.h"
using namespace oceanbase::common;
using namespace oceanbase::tools;
......@@ -27,7 +32,11 @@ void print_usage()
fprintf(stderr,
"\nUSAGE:\n"
" ob_admin clog_tool\n"
" ob_admin usec_tool\n");
" ob_admin usec_tool\n"
" ob_admin slog_tool\n"
" ob_admin dumpsst\n"
" ob_admin archive_tool\n"
" ob_admin dump_backup\n");
}
int main(int argc, char *argv[])
......@@ -51,6 +60,16 @@ int main(int argc, char *argv[])
executor = new ObAdminClogV2Executor();
} else if (0 == strcmp("usec_tool", argv[1])) {
executor = new ObAdminUsecExecutor();
} else if (0 == strcmp("slog_tool", argv[1])) {
executor = new ObAdminSlogExecutor();
} else if (0 == strcmp("dumpsst", argv[1])) {
executor = new ObAdminDumpsstExecutor();
} else if (0 == strcmp("cmp_micro", argv[1])) {
executor = new ObAdminCmpMicroExecutor();
} else if (0 == strcmp("archive_tool", argv[1])) {
executor = new ObAdminLogArchiveExecutor();
} else if (0 == strcmp("dump_backup", argv[1])) {
executor = new ObAdminDumpBackupDataExecutor();
} else {
print_usage();
}
......
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX COMMON
#include "ob_admin_slog_executor.h"
#include "storage/blocksstable/slog/ob_base_storage_logger.h"
#include "storage/blocksstable/ob_macro_block_meta_mgr.h"
#include "storage/ob_partition_service.h"
#include "storage/ob_table_mgr.h"
#include "storage/ob_tenant_config_mgr.h"
#include "storage/ob_tenant_file_mgr.h"
#include "../dumpsst/ob_admin_dumpsst_utils.h"
using namespace oceanbase::share;
using namespace oceanbase::common;
using namespace oceanbase::blocksstable;
using namespace oceanbase::storage;
namespace oceanbase
{
namespace tools
{
ObAdminSlogExecutor::ObAdminSlogExecutor()
: log_dir_(NULL),
log_file_id_(0)
{
}
int ObAdminSlogExecutor::execute(int argc, char *argv[])
{
int ret = OB_SUCCESS;
reset();
ObPartitionMetaRedoModule partition_module;
ObBaseFileMgr file_mgr;
if (OB_FAIL(parse_cmd(argc - 1, argv + 1))) {
LOG_WARN("fail to parse cmd", K(ret));
} else {
if (NULL != log_dir_ && log_file_id_ > 0) {
if (OB_FAIL(SLOGGER.register_redo_module(OB_REDO_LOG_PARTITION, &partition_module))) {
LOG_WARN("fail to register partition module", K(ret));
} else if (OB_FAIL(SLOGGER.register_redo_module(OB_REDO_LOG_MACROBLOCK,
&ObMacroBlockMetaMgr::get_instance()))) {
LOG_WARN("fail to register macro module", K(ret));
} else if (OB_FAIL(SLOGGER.register_redo_module(OB_REDO_LOG_TABLE_MGR,
&ObTableMgr::get_instance()))) {
LOG_WARN("fail to register table module", K(ret));
} else if (OB_FAIL(SLOGGER.register_redo_module(OB_REDO_LOG_TENANT_CONFIG,
&ObTenantConfigMgr::get_instance()))) {
LOG_WARN("fail to register tenant config module", K(ret));
} else if (OB_FAIL(SLOGGER.register_redo_module(OB_REDO_LOG_TENANT_FILE, &file_mgr))) {
LOG_WARN("fail to register tenant file module", K(ret));
} else if (OB_FAIL(SLOGGER.parse_log(log_dir_, log_file_id_, stdout))) {
LOG_WARN("fail to parse log file", K(ret));
}
}
}
return ret;
}
void ObAdminSlogExecutor::reset()
{
log_dir_ = NULL;
log_file_id_ = 0;
}
int ObAdminSlogExecutor::parse_cmd(int argc, char *argv[])
{
int ret = OB_SUCCESS;
int opt = 0;
const char* opt_string = "hf:";
struct option longopts[] =
{{"help", 0, NULL, 'h' },
{"log_file_path", 1, NULL, 'f' }};
while ((opt = getopt_long(argc, argv, opt_string, longopts, NULL)) != -1) {
switch (opt) {
case 'h': {
print_usage();
break;
}
case 'f': {
//find the last separator from the right of log_file_pathַ
char *p = strrchr(optarg, '/');
if (NULL == p) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("log_file_path is not correct, ", K(ret), K(optarg));
} else {
//separate the log_dir and log_name by '\0'
*p = '\0';
log_dir_ = optarg;
log_file_id_ = atoi(p + 1);
}
break;
}
default: {
print_usage();
ret = OB_INVALID_ARGUMENT;
}
}
}
return ret;
}
void ObAdminSlogExecutor::print_usage()
{
fprintf(stderr, "\nUsage: ob_admin slog_tool -f log_file_name\n");
}
}
}
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OB_ADMIN_SLOG_EXECUTOR_H_
#define OB_ADMIN_SLOG_EXECUTOR_H_
#include "../ob_admin_executor.h"
namespace oceanbase
{
namespace tools
{
class ObAdminSlogExecutor : public ObAdminExecutor
{
public:
ObAdminSlogExecutor();
virtual ~ObAdminSlogExecutor() = default;
virtual int execute(int argc, char *argv[]);
void reset();
private:
int parse_cmd(int argc, char *argv[]);
void print_usage();
private:
char *log_dir_;
int64_t log_file_id_;
};
}
}
#endif /* OB_ADMIN_SLOG_EXECUTOR_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册