778 lines
29 KiB
C++
778 lines
29 KiB
C++
/**
|
|
* 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_executor.h"
|
|
#include "ob_admin_dumpsst_utils.h"
|
|
#include "storage/blocksstable/ob_store_file.h"
|
|
#include "storage/ob_partition_service.h"
|
|
#include "storage/ob_table_mgr.h"
|
|
#include "storage/ob_sstable.h"
|
|
#include "storage/ob_tenant_config_mgr.h"
|
|
#include "storage/ob_tenant_config_meta_block_reader.h"
|
|
#include "storage/blocksstable/ob_micro_block_scanner.h"
|
|
#include "storage/blocksstable/ob_micro_block_index_reader.h"
|
|
#include "storage/blocksstable/ob_sstable_printer.h"
|
|
#include "observer/ob_server_struct.h"
|
|
#include "storage/ob_file_system_util.h"
|
|
#include "storage/ob_pg_storage.h"
|
|
#include "lib/net/ob_net_util.h"
|
|
|
|
using namespace oceanbase::common;
|
|
using namespace oceanbase::blocksstable;
|
|
using namespace oceanbase::storage;
|
|
#define HELP_FMT "\t%-30s%-12s\n"
|
|
|
|
namespace oceanbase
|
|
{
|
|
namespace tools
|
|
{
|
|
|
|
ObAdminDumpsstExecutor::ObAdminDumpsstExecutor()
|
|
: storage_env_(),
|
|
is_quiet_(false),
|
|
in_csv_(false),
|
|
cmd_(DUMP_MAX),
|
|
skip_log_replay_(false),
|
|
dump_macro_context_(),
|
|
reload_config_(ObServerConfig::get_instance(), GCTX), config_mgr_(ObServerConfig::get_instance(), reload_config_)
|
|
{
|
|
storage_env_.data_dir_ = data_dir_;
|
|
storage_env_.sstable_dir_ = sstable_dir_;
|
|
storage_env_.default_block_size_ = 2 * 1024 * 1024;
|
|
|
|
storage_env_.log_spec_.log_dir_ = slog_dir_;
|
|
storage_env_.log_spec_.max_log_size_ = 256 << 20;
|
|
|
|
storage_env_.clog_dir_ = clog_dir_;
|
|
storage_env_.ilog_dir_ = ilog_dir_;
|
|
storage_env_.clog_shm_path_ = clog_shm_path_;
|
|
storage_env_.ilog_shm_path_ = ilog_shm_path_;
|
|
|
|
storage_env_.bf_cache_miss_count_threshold_ = 0;
|
|
storage_env_.bf_cache_priority_ = 1;
|
|
storage_env_.index_cache_priority_ = 10;
|
|
storage_env_.user_block_cache_priority_ = 1;
|
|
storage_env_.user_row_cache_priority_ = 1;
|
|
storage_env_.fuse_row_cache_priority_ = 1;
|
|
storage_env_.clog_cache_priority_ = 1;
|
|
storage_env_.index_clog_cache_priority_ = 1;
|
|
storage_env_.ethernet_speed_ = 10000;
|
|
|
|
GCONF.datafile_size = 128 * 1024 * 1024;
|
|
}
|
|
|
|
ObAdminDumpsstExecutor::~ObAdminDumpsstExecutor()
|
|
{
|
|
ObStoreFileSystemWrapper::destroy();
|
|
}
|
|
|
|
int ObAdminDumpsstExecutor::execute(int argc, char *argv[])
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPartitionService partition_service;
|
|
UNUSED(argc);
|
|
UNUSED(argv);
|
|
|
|
if (OB_SUCC(parse_cmd(argc, argv))) {
|
|
if (is_quiet_) {
|
|
OB_LOGGER.set_log_level("ERROR");
|
|
} else {
|
|
OB_LOGGER.set_log_level("INFO");
|
|
}
|
|
|
|
lib::set_memory_limit(96 * 1024 * 1024 * 1024LL);
|
|
lib::set_tenant_memory_limit(500, 96 * 1024 * 1024 * 1024LL);
|
|
char ip_port_str[MAX_PATH_SIZE] = {};
|
|
if (skip_log_replay_ && DUMP_MACRO_DATA != cmd_) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
STORAGE_LOG(ERROR, "Only dump macro block can skip slog replay, ", K(ret));
|
|
} else if (OB_FAIL(ObIOManager::get_instance().init(2 * 1024 * 1024 * 1024LL))) {
|
|
STORAGE_LOG(ERROR, "Fail to init io manager, ", K(ret));
|
|
} else if (OB_FAIL(ObKVGlobalCache::get_instance().init(1024L, 512 * 1024 * 1024, 64 * 1024))) {
|
|
STORAGE_LOG(ERROR, "Fail to init kv cache, ", K(ret));
|
|
} else if (OB_FAIL(OB_STORE_CACHE.init(
|
|
storage_env_.index_cache_priority_,
|
|
storage_env_.user_block_cache_priority_,
|
|
storage_env_.user_row_cache_priority_,
|
|
storage_env_.fuse_row_cache_priority_,
|
|
storage_env_.bf_cache_priority_,
|
|
storage_env_.bf_cache_miss_count_threshold_))) {
|
|
STORAGE_LOG(WARN, "Fail to init OB_STORE_CACHE, ", K(ret), K(storage_env_.data_dir_));
|
|
} else if (OB_FAIL(load_config())) {
|
|
STORAGE_LOG(WARN, "fail to load config", K(ret));
|
|
} else if (OB_FAIL(GCTX.self_addr_.ip_port_to_string(ip_port_str, MAX_PATH_SIZE))) {
|
|
STORAGE_LOG(WARN, "get server ip port fail", K(ret), K(GCTX.self_addr_));
|
|
} else if (OB_FAIL(OB_FILE_SYSTEM_ROUTER.init(data_dir_,
|
|
config_mgr_.get_config().cluster.str(),
|
|
config_mgr_.get_config().cluster_id.get_value(),
|
|
config_mgr_.get_config().zone.str(),
|
|
ip_port_str))) {
|
|
STORAGE_LOG(WARN, "fail to init file system", K(ret));
|
|
} else if (OB_FAIL(ObStoreFileSystemWrapper::init(storage_env_, partition_service))) {
|
|
STORAGE_LOG(ERROR, "Fail to init store file, ", K(ret));
|
|
} else {
|
|
STORAGE_LOG(INFO, "cmd is", K(cmd_));
|
|
switch (cmd_) {
|
|
case DUMP_MACRO_DATA:
|
|
case DUMP_MACRO_META:
|
|
case DUMP_SSTABLE:
|
|
case DUMP_SSTABLE_META:
|
|
case PRINT_MACRO_BLOCK:
|
|
if (OB_FAIL(open_store_file())) {
|
|
STORAGE_LOG(ERROR, "failed to open store file", K(ret));
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
switch (cmd_) {
|
|
case DUMP_SUPER_BLOCK:
|
|
print_super_block();
|
|
break;
|
|
case DUMP_MACRO_DATA:
|
|
dump_macro_block(dump_macro_context_);
|
|
break;
|
|
case DUMP_MACRO_META:
|
|
print_macro_meta();
|
|
break;
|
|
case DUMP_SSTABLE:
|
|
dump_sstable();
|
|
break;
|
|
case PRINT_MACRO_BLOCK:
|
|
print_macro_block();
|
|
break;
|
|
case DUMP_SSTABLE_META:
|
|
dump_sstable_meta();
|
|
break;
|
|
default:
|
|
print_usage();
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminDumpsstExecutor::load_config()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
// set dump path
|
|
const char *dump_path = "etc/observer.config.bin";
|
|
config_mgr_.set_dump_path(dump_path);
|
|
if (OB_FAIL(config_mgr_.load_config())) {
|
|
STORAGE_LOG(WARN, "fail to load config", K(ret));
|
|
} else {
|
|
ObServerConfig &config = config_mgr_.get_config();
|
|
int32_t local_port = static_cast<int32_t>(config.rpc_port);
|
|
int32_t ipv4 = ntohl(obsys::ObNetUtil::get_local_addr_ipv4(config.devname));
|
|
GCTX.self_addr_.set_ipv4_addr(ipv4, local_port);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminDumpsstExecutor::parse_cmd(int argc, char *argv[])
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
int opt = 0;
|
|
const char* opt_string = "d:hf:a:i:n:qt:s:";
|
|
|
|
struct option longopts[] = {
|
|
// commands
|
|
{ "dump", 1, NULL, 'd' },
|
|
{ "help", 0, NULL, 'h' },
|
|
// options
|
|
{ "file", 1, NULL, 'f' },
|
|
{ "macro-id", 1, NULL, 'a' },
|
|
{ "micro-id", 1, NULL, 'i' },
|
|
{ "macro-size", 1, NULL, 'n' },
|
|
{ "csv", 0, NULL, 0 },
|
|
{ "table_key", 1, NULL, 't'},
|
|
{ "quiet", 0, NULL, 'q' },
|
|
{ "skip_replay", 0, NULL, 's' },
|
|
};
|
|
|
|
int index = -1;
|
|
while ((opt = getopt_long(argc, argv, opt_string, longopts, &index)) != -1) {
|
|
switch (opt) {
|
|
case 'h': {
|
|
print_usage();
|
|
exit(1);
|
|
}
|
|
case 'd': {
|
|
if (0 == strcmp(optarg, "sb") || 0 == strcmp(optarg, "super_block")) {
|
|
cmd_ = DUMP_SUPER_BLOCK;
|
|
} else if (0 == strcmp(optarg, "mb") || 0 == strcmp(optarg, "macro_block")) {
|
|
cmd_ = DUMP_MACRO_DATA;
|
|
} else if (0 == strcmp(optarg, "mm") || 0 == strcmp(optarg, "macro_meta")) {
|
|
cmd_ = DUMP_MACRO_META;
|
|
} else if (0 == strcmp(optarg, "sst") || 0 == strcmp(optarg, "sstable")) {
|
|
cmd_ = DUMP_SSTABLE;
|
|
} else if (0 == strcmp(optarg, "sstm") || 0 == strcmp(optarg, "sstable_meta")) {
|
|
cmd_ = DUMP_SSTABLE_META;
|
|
} else if (0 == strcmp(optarg, "pm") || 0 == strcmp(optarg, "print_macro")) {
|
|
cmd_ = PRINT_MACRO_BLOCK;
|
|
} else {
|
|
print_usage();
|
|
exit(1);
|
|
}
|
|
break;
|
|
}
|
|
case 'f': {
|
|
int pret = 0;
|
|
strcpy(data_dir_, optarg);
|
|
pret = snprintf(slog_dir_, OB_MAX_FILE_NAME_LENGTH, "%s/slog", data_dir_);
|
|
if (pret < 0 || pret >= OB_MAX_FILE_NAME_LENGTH) {
|
|
ret = OB_BUF_NOT_ENOUGH;
|
|
STORAGE_LOG(ERROR, "concatenate slog path fail", K(ret));
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
pret = snprintf(sstable_dir_, OB_MAX_FILE_NAME_LENGTH, "%s/sstable", data_dir_);
|
|
if (pret < 0 || pret >= OB_MAX_FILE_NAME_LENGTH) {
|
|
ret = OB_BUF_NOT_ENOUGH;
|
|
STORAGE_LOG(ERROR, "concatenate slog path fail", K(ret));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 'a': {
|
|
dump_macro_context_.macro_id_ = strtoll(optarg, NULL, 10);
|
|
break;
|
|
}
|
|
case 'i': {
|
|
dump_macro_context_.micro_id_ = strtoll(optarg, NULL, 10);
|
|
break;
|
|
}
|
|
case 'n': {
|
|
storage_env_.default_block_size_ = strtoll(optarg, NULL, 10);
|
|
break;
|
|
}
|
|
case 'q': {
|
|
is_quiet_ = true;
|
|
break;
|
|
}
|
|
case 's': {
|
|
skip_log_replay_ = true;
|
|
break;
|
|
}
|
|
case 0: {
|
|
std::string name = longopts[index].name;
|
|
if ("csv" == name) {
|
|
in_csv_ = true;
|
|
}
|
|
break;
|
|
}
|
|
case 't': {
|
|
if (OB_FAIL(parse_table_key(optarg, table_key_))) {
|
|
printf("failed to parse table key\n");
|
|
print_usage();
|
|
exit(1);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
print_usage();
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ObAdminDumpsstExecutor::print_super_block()
|
|
{
|
|
fprintf(stdout, "SuperBlock: %s\n", to_cstring(OB_FILE_SYSTEM.get_server_super_block()));
|
|
}
|
|
|
|
void ObAdminDumpsstExecutor::print_macro_block()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
STORAGE_LOG(ERROR, "not supported command", K(ret));
|
|
}
|
|
|
|
int ObAdminDumpsstExecutor::dump_macro_block(const ObDumpMacroBlockContext ¯o_block_context)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObStorageFileWithRef file_with_ref;
|
|
ObStorageFileHandle file_handle;
|
|
ObStorageFile *file = nullptr;
|
|
|
|
|
|
ObMacroBlockHandle macro_handle;
|
|
ObSSTableDataBlockReader macro_reader;
|
|
|
|
ObMacroBlockReadInfo read_info;
|
|
ObMacroBlockCtx block_ctx;
|
|
block_ctx.sstable_block_id_.macro_block_id_.set_local_block_id(macro_block_context.macro_id_);
|
|
block_ctx.sstable_block_id_.macro_block_id_in_files_ = 0;
|
|
read_info.macro_block_ctx_ = &block_ctx;
|
|
read_info.io_desc_.category_ = SYS_IO;
|
|
read_info.offset_ = 0;
|
|
read_info.size_ = ObStoreFileSystemWrapper::get_instance().get_macro_block_size();
|
|
|
|
STORAGE_LOG(INFO, "begin dump macro block", K(macro_block_context));
|
|
if (OB_FAIL(file_handle.assign(OB_FILE_SYSTEM.get_server_root_handle()))) {
|
|
STORAGE_LOG(WARN, "fail to assign file handle", K(ret));
|
|
} else if (!macro_block_context.is_valid()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
STORAGE_LOG(ERROR, "invalid macro block id", K(macro_block_context), K(ret));
|
|
} else if (OB_ISNULL(file = file_handle.get_storage_file())) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
STORAGE_LOG(ERROR, "storage file is null", K(ret), K(file_handle));
|
|
} else if (FALSE_IT(macro_handle.set_file(file))) {
|
|
} else if (OB_FAIL(file->read_block(read_info, macro_handle))) {
|
|
STORAGE_LOG(ERROR, "Fail to read macro block, ", K(ret), K(read_info));
|
|
} else if (OB_FAIL(macro_reader.init(macro_handle.get_buffer(), macro_handle.get_data_size()))) {
|
|
STORAGE_LOG(ERROR, "failed to get macro meta", K(block_ctx), K(ret));
|
|
STORAGE_LOG(ERROR, "failed to init macro reader", K(ret));
|
|
} else if (OB_FAIL(macro_reader.dump())) {
|
|
STORAGE_LOG(ERROR, "failed dump macro block", K(ret));
|
|
}
|
|
|
|
macro_handle.reset();
|
|
if (nullptr != file) {
|
|
OB_FILE_SYSTEM.free_file(file);
|
|
}
|
|
STORAGE_LOG(INFO, "finish dump macro block", K(macro_block_context));
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminDumpsstExecutor::open_store_file()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
return ret;
|
|
}
|
|
|
|
void ObAdminDumpsstExecutor::print_macro_meta()
|
|
{
|
|
// int ret = OB_SUCCESS;
|
|
const ObMacroBlockMeta *meta = NULL;
|
|
MacroBlockId macro_id(dump_macro_context_.macro_id_);
|
|
PrintHelper::print_dump_title("Macro Meta");
|
|
PrintHelper::print_dump_line("macro_block_id", dump_macro_context_.macro_id_);
|
|
PrintHelper::print_dump_line("attr", meta->attr_);
|
|
PrintHelper::print_dump_line("data_version", meta->data_version_);
|
|
PrintHelper::print_dump_line("column_number", meta->column_number_);
|
|
PrintHelper::print_dump_line("rowkey_column_number", meta->rowkey_column_number_);
|
|
PrintHelper::print_dump_line("column_index_scale", meta->column_index_scale_);
|
|
PrintHelper::print_dump_line("row_store_type", meta->row_store_type_);
|
|
PrintHelper::print_dump_line("row_count", meta->row_count_);
|
|
PrintHelper::print_dump_line("occupy_size", meta->occupy_size_);
|
|
PrintHelper::print_dump_line("data_checksum", meta->data_checksum_);
|
|
PrintHelper::print_dump_line("micro_block_count", meta->micro_block_count_);
|
|
PrintHelper::print_dump_line("micro_block_data_offset", meta->micro_block_data_offset_);
|
|
PrintHelper::print_dump_line("micro_block_index_offset", meta->micro_block_index_offset_);
|
|
PrintHelper::print_dump_line("micro_block_endkey_offset", meta->micro_block_endkey_offset_);
|
|
PrintHelper::print_dump_line("compressor", meta->compressor_);
|
|
PrintHelper::print_dump_line("table_id", meta->table_id_);
|
|
PrintHelper::print_dump_line("data_seq", meta->data_seq_);
|
|
PrintHelper::print_dump_line("schema_version", meta->schema_version_);
|
|
PrintHelper::print_dump_line("snapshot_version", meta->snapshot_version_);
|
|
PrintHelper::print_dump_line("schema_rowkey_col_cnt", meta->schema_rowkey_col_cnt_);
|
|
PrintHelper::print_dump_line("row_count_delta", meta->row_count_delta_);
|
|
PrintHelper::print_dump_line("macro_block_deletion_flag", meta->macro_block_deletion_flag_);
|
|
PrintHelper::print_dump_list_start("column_id_array");
|
|
for (int64_t i = 0; i < meta->column_number_; ++i) {
|
|
PrintHelper::print_dump_list_value(meta->column_id_array_[i], i == meta->rowkey_column_number_ - 1);
|
|
}
|
|
PrintHelper::print_dump_list_end();
|
|
PrintHelper::print_dump_list_start("column_type_array");
|
|
for (int64_t i = 0; i < meta->column_number_; ++i) {
|
|
PrintHelper::print_dump_list_value(to_cstring(meta->column_type_array_[i]), i == meta->rowkey_column_number_ - 1);
|
|
}
|
|
PrintHelper::print_dump_list_end();
|
|
PrintHelper::print_dump_list_start("column_checksum");
|
|
for (int64_t i = 0; i < meta->column_number_; ++i) {
|
|
PrintHelper::print_dump_list_value(meta->column_checksum_[i], i== meta->rowkey_column_number_ - 1);
|
|
}
|
|
PrintHelper::print_dump_list_end();
|
|
PrintHelper::print_dump_list_start("end_key");
|
|
for (int64_t i = 0; i < meta->rowkey_column_number_; ++i) {
|
|
PrintHelper::print_cell(meta->endkey_[i], in_csv_);
|
|
}
|
|
PrintHelper::print_dump_list_end();
|
|
PrintHelper::print_dump_list_start("column_order");
|
|
for (int64_t i = 0; i < meta->column_number_; ++i) {
|
|
PrintHelper::print_dump_list_value(meta->column_order_array_[i], i == meta->column_number_ - 1);
|
|
}
|
|
PrintHelper::print_dump_list_end();
|
|
PrintHelper::print_end_line();
|
|
}
|
|
|
|
void ObAdminDumpsstExecutor::dump_sstable()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObSSTable *sstable = NULL;
|
|
|
|
if (OB_FAIL(replay_slog_to_get_sstable(sstable))) {
|
|
STORAGE_LOG(ERROR, "failed to acquire table", K_(table_key), K(ret));
|
|
} else if (OB_ISNULL(sstable)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
STORAGE_LOG(ERROR, "sstable is null", K(ret));
|
|
} else {
|
|
const ObIArray<blocksstable::MacroBlockId> ¯o_array = sstable->get_macro_block_ids();
|
|
ObDumpMacroBlockContext context;
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < macro_array.count(); ++i) {
|
|
context.macro_id_ = macro_array.at(i).block_index();
|
|
if (OB_FAIL(dump_macro_block(context))) {
|
|
STORAGE_LOG(ERROR, "failed to dump macro block", K(context), K(ret));
|
|
}
|
|
}
|
|
if (OB_SUCC(ret) && sstable->has_lob_macro_blocks()) {
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < sstable->get_lob_macro_block_ids().count(); ++i) {
|
|
context.macro_id_ = sstable->get_lob_macro_block_ids().at(i).block_index();
|
|
if (OB_FAIL(dump_macro_block(context))) {
|
|
STORAGE_LOG(ERROR, "Failed to dump lob macro block", K(context), K(ret));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
printf("failed to dump sstable, ret = %d\n", ret);
|
|
}
|
|
}
|
|
|
|
void ObAdminDumpsstExecutor::dump_sstable_meta()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObSSTable *sstable = NULL;
|
|
if (OB_FAIL(replay_slog_to_get_sstable(sstable))) {
|
|
STORAGE_LOG(ERROR, "fail to acquire table", K(ret), K(table_key_));
|
|
} else if (OB_ISNULL(sstable)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
STORAGE_LOG(WARN, "error unexpected, sstable must not be NULL", K(ret));
|
|
} else {
|
|
char buf[1024];
|
|
const ObSSTableMeta &meta = sstable->get_meta();
|
|
snprintf(buf, 1024, "table_id=%ld, partition_id=%ld", table_key_.table_id_, table_key_.pkey_.get_partition_id());
|
|
PrintHelper::print_dump_title(buf);
|
|
PrintHelper::print_dump_line("index_id", meta.index_id_);
|
|
PrintHelper::print_dump_line("row_count", meta.row_count_);
|
|
PrintHelper::print_dump_line("occupy_size", meta.occupy_size_);
|
|
PrintHelper::print_dump_line("data_checksum", meta.data_checksum_);
|
|
PrintHelper::print_dump_line("row_checksum", meta.row_checksum_);
|
|
PrintHelper::print_dump_line("macro_block_count", meta.macro_block_count_);
|
|
PrintHelper::print_dump_line("use_old_macro_block_count", meta.use_old_macro_block_count_);
|
|
PrintHelper::print_dump_line("column_count", meta.column_cnt_);
|
|
PrintHelper::print_dump_line("lob_macro_block_count", meta.lob_macro_block_count_);
|
|
PrintHelper::print_dump_line("lob_use_old_macro_block_count", meta.lob_use_old_macro_block_count_);
|
|
PrintHelper::print_dump_line("schema_version", meta.schema_version_);
|
|
PrintHelper::print_dump_line("progressive_merge_start_version", meta.progressive_merge_start_version_);
|
|
PrintHelper::print_dump_line("progressive_merge_end_version", meta.progressive_merge_end_version_);
|
|
PrintHelper::print_dump_line("checksum_method", meta.checksum_method_);
|
|
meta.column_metas_.to_string(buf, 1024);
|
|
PrintHelper::print_dump_line("column_metas", buf);
|
|
meta.new_column_metas_.to_string(buf, 1024);
|
|
PrintHelper::print_dump_line("new_column_metas", buf);
|
|
}
|
|
}
|
|
|
|
int ObAdminDumpsstExecutor::replay_slog_to_get_sstable(ObSSTable *&sstable)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObBaseFileMgr file_mgr;
|
|
ObPartitionMetaRedoModule pg_mgr;
|
|
ObPartitionComponentFactory cp_fty;
|
|
|
|
if (OB_FAIL(file_mgr.init())) {
|
|
STORAGE_LOG(WARN, "fail to init file mgr", K(ret));
|
|
} else if (OB_FAIL(pg_mgr.init(&cp_fty,
|
|
&share::schema::ObMultiVersionSchemaService::get_instance(),
|
|
&file_mgr))) {
|
|
STORAGE_LOG(WARN, "fail to init pg mgr", K(ret));
|
|
} else {
|
|
ObAdminSlogReplayer replayer(file_mgr, pg_mgr, slog_dir_);
|
|
replayer.init();
|
|
if (OB_FAIL(replayer.replay_slog())) {
|
|
STORAGE_LOG(WARN, "fail to replay slog", K(ret));
|
|
} else if (OB_FAIL(replayer.get_sstable(table_key_, sstable))) {
|
|
STORAGE_LOG(WARN, "fail to get sstable", K(ret));
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
ObAdminSlogReplayer::ObAdminSlogReplayer(
|
|
ObBaseFileMgr &file_mgr,
|
|
ObPartitionMetaRedoModule &pg_mgr,
|
|
char *slog_dir)
|
|
:
|
|
svr_addr_(GCTX.self_addr_),
|
|
svr_root_(),
|
|
file_mgr_(file_mgr),
|
|
pg_mgr_(pg_mgr),
|
|
super_block_(),
|
|
pg_meta_reader_(),
|
|
tenant_file_reader_(),
|
|
slog_dir_(slog_dir)
|
|
{
|
|
}
|
|
|
|
ObAdminSlogReplayer::~ObAdminSlogReplayer()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
int ObAdminSlogReplayer::init()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
common::ObLogCursor checkpoint;
|
|
|
|
blocksstable::ObServerSuperBlock super_block;
|
|
ObStorageFileWithRef file_with_ref;
|
|
ObStorageFileHandle file_handle;
|
|
ObStorageFile *file = nullptr;
|
|
|
|
ObTenantMutilAllocatorMgr::get_instance().init();
|
|
|
|
if (OB_FAIL(file_handle.assign(OB_FILE_SYSTEM.get_server_root_handle()))) {
|
|
STORAGE_LOG(WARN, "fail to assign file handle", K(ret));
|
|
} else if (OB_FAIL(file_handle.get_storage_file()->read_super_block(super_block_))) {
|
|
STORAGE_LOG(WARN, "failed to read super block", K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminSlogReplayer::replay_slog()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
common::ObLogCursor checkpoint;
|
|
|
|
if (OB_UNLIKELY(!svr_addr_.is_valid())) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
STORAGE_LOG(WARN, "invalid source server", K(ret), K(svr_addr_));
|
|
} else if (OB_FAIL(OB_FILE_SYSTEM.alloc_file(svr_root_.file_))) {
|
|
STORAGE_LOG(WARN, "fail to alloc storage file", K(ret));
|
|
} else if (OB_FAIL(svr_root_.file_->init(svr_addr_,
|
|
ObStorageFile::FileType::SERVER_ROOT))) {
|
|
STORAGE_LOG(WARN, "fail to init original server root file", K(ret), K(svr_addr_));
|
|
} else if (OB_FAIL(svr_root_.file_->open(ObFileSystemUtil::WRITE_FLAGS))) {
|
|
STORAGE_LOG(WARN, "fail to open pg file", K(ret));
|
|
} else if (OB_FAIL(svr_root_.file_->read_super_block(super_block_))) {
|
|
STORAGE_LOG(WARN, "failed to read super block", K(ret));
|
|
} else if (OB_FAIL(read_checkpoint_and_replay_log(checkpoint))) {
|
|
STORAGE_LOG(WARN, "fail to read checkpoint and replay log", K(ret));
|
|
} else {
|
|
STORAGE_LOG(INFO, "success to replay log", K(ret));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void ObAdminSlogReplayer::reset()
|
|
{
|
|
tenant_file_reader_.reset();
|
|
super_block_.reset();
|
|
if (OB_NOT_NULL(svr_root_.file_)) {
|
|
int tmp_ret = OB_SUCCESS;
|
|
if (OB_SUCCESS != (tmp_ret = OB_FILE_SYSTEM.free_file(svr_root_.file_))) {
|
|
STORAGE_LOG(WARN, "fail to free svr root", K(tmp_ret));
|
|
}
|
|
}
|
|
}
|
|
|
|
int ObAdminSlogReplayer::get_sstable(
|
|
storage::ObITable::TableKey table_key,
|
|
storage::ObSSTable *&sstable)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
sstable = NULL;
|
|
storage::ObIPartitionGroupGuard guard;
|
|
storage::ObPGPartitionGuard pg_guard;
|
|
ObTablesHandle tables_handle;
|
|
common::ObArray<ObSSTable *> sstables;
|
|
if (OB_FAIL(pg_mgr_.get_partition(table_key.pkey_, guard)) || NULL == guard.get_partition_group()) {
|
|
STORAGE_LOG(WARN, "invalid partition", K(ret), K(table_key));
|
|
} else if (OB_FAIL(guard.get_partition_group()->get_pg_storage().get_all_sstables(tables_handle))) {
|
|
STORAGE_LOG(WARN, "failed to get tables", K(ret), K(table_key));
|
|
} else if (OB_FAIL(tables_handle.get_all_sstables(sstables))) {
|
|
STORAGE_LOG(WARN, "failed to get all sstables", K(ret), K(table_key));
|
|
} else {
|
|
for (int i = 0; i < sstables.count(); ++i) {
|
|
if (sstables.at(i)->get_key() == table_key) {
|
|
sstable = sstables.at(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret) && OB_NOT_NULL(sstable)) {
|
|
STORAGE_LOG(INFO, "success to get sstable", K(ret), K(table_key), KPC(sstable));
|
|
} else {
|
|
STORAGE_LOG(WARN, "sstable not found", K(ret), K(table_key), K(sstables));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminSlogReplayer::replay_server_slog(
|
|
const char *slog_dir,
|
|
const common::ObLogCursor &replay_start_cursor,
|
|
const ObStorageLogCommittedTransGetter &committed_trans_getter)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObStorageLogReplayer log_replayer;
|
|
ServerMetaSLogFilter filter_before_parse;
|
|
ObStorageFileHandle svr_root_handle;
|
|
if (OB_ISNULL(slog_dir) || OB_UNLIKELY(!replay_start_cursor.is_valid())) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
STORAGE_LOG(WARN, "invalid argument", K(ret), KP(slog_dir), K(replay_start_cursor));
|
|
} else if (FALSE_IT(svr_root_handle.set_storage_file_with_ref(svr_root_))) {
|
|
} else if (OB_FAIL(tenant_file_reader_.read_checkpoint(super_block_.content_.super_block_meta_,
|
|
file_mgr_, svr_root_handle))) {
|
|
STORAGE_LOG(WARN, "fail to read tenant file checkpoint", K(ret));
|
|
} else if (OB_FAIL(log_replayer.init(slog_dir, &filter_before_parse))) {
|
|
STORAGE_LOG(WARN, "fail to init log replayer", K(ret));
|
|
} else if (OB_FAIL(log_replayer.register_redo_module(OB_REDO_LOG_TENANT_FILE, &file_mgr_))) {
|
|
STORAGE_LOG(WARN, "fail to register redo module", K(ret));
|
|
} else if (OB_FAIL(log_replayer.replay(replay_start_cursor, committed_trans_getter))) {
|
|
STORAGE_LOG(WARN, "fail to replay log replayer", K(ret));
|
|
} else if (OB_FAIL(file_mgr_.replay_open_files(svr_addr_))) {
|
|
STORAGE_LOG(WARN, "fail to replay open files", K(ret));
|
|
} else {
|
|
STORAGE_LOG(INFO, "finish replay server slog");
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminSlogReplayer::replay_pg_slog(const char *slog_dir,
|
|
const common::ObLogCursor &replay_start_cursor,
|
|
const blocksstable::ObStorageLogCommittedTransGetter &committed_trans_getter,
|
|
common::ObLogCursor &checkpoint)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObStorageLogReplayer log_replayer;
|
|
PGMetaSLogFilter filter_before_parse(file_mgr_);
|
|
if (OB_ISNULL(slog_dir) || OB_UNLIKELY(!replay_start_cursor.is_valid())) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
STORAGE_LOG(WARN, "invalid argument", K(ret), KP(slog_dir), K(replay_start_cursor));
|
|
} else if (OB_FAIL(pg_meta_reader_.read_checkpoint(file_mgr_, pg_mgr_))) {
|
|
STORAGE_LOG(WARN, "fail to read checkpoint", K(ret));
|
|
} else if (OB_FAIL(log_replayer.init(slog_dir, &filter_before_parse))) {
|
|
STORAGE_LOG(WARN, "fail to init log replayer", K(ret));
|
|
} else if (OB_FAIL(log_replayer.register_redo_module(OB_REDO_LOG_PARTITION, &pg_mgr_))) {
|
|
STORAGE_LOG(WARN, "fail to register redo module", K(ret));
|
|
} else if (OB_FAIL(log_replayer.replay(replay_start_cursor, committed_trans_getter))) {
|
|
STORAGE_LOG(WARN, "fail to replay log replayer", K(ret));
|
|
} else if (OB_FAIL(log_replayer.get_active_cursor(checkpoint))){
|
|
STORAGE_LOG(WARN, "fail to get active cursor", K(ret));
|
|
} else {
|
|
STORAGE_LOG(INFO, "finish replay pg slog", K(checkpoint), K(pg_mgr_.get_pg_mgr().get_total_partition_count()));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminSlogReplayer::read_checkpoint_and_replay_log(common::ObLogCursor &checkpoint)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
char dir_name[MAX_PATH_SIZE];
|
|
common::ObLogCursor replay_start_cursor;
|
|
ObStorageLogCommittedTransGetter committed_trans_getter;
|
|
ObServerWorkingDir dir(svr_addr_, ObServerWorkingDir::DirStatus::RECOVERING);
|
|
|
|
if (OB_FAIL(dir.to_path_string(dir_name, sizeof(dir_name)))) {
|
|
STORAGE_LOG(WARN, "get server ip port fail", K(ret), K(dir));
|
|
} else if (super_block_.content_.replay_start_point_.is_valid()) {
|
|
replay_start_cursor = super_block_.content_.replay_start_point_;
|
|
} else {
|
|
replay_start_cursor.file_id_ = 1;
|
|
replay_start_cursor.log_id_ = 0;
|
|
replay_start_cursor.offset_ = 0;
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
STORAGE_LOG(INFO, "read checkpoint begin", K(slog_dir_), K(svr_addr_), K(replay_start_cursor));
|
|
if (OB_FAIL(committed_trans_getter.init(slog_dir_, replay_start_cursor))) {
|
|
STORAGE_LOG(WARN, "fail to init committed trans getter", K(ret));
|
|
} else if (OB_FAIL(replay_server_slog(slog_dir_, replay_start_cursor, committed_trans_getter))) {
|
|
STORAGE_LOG(WARN, "fail to replay tenant file slog", K(ret));
|
|
} else if (OB_FAIL(replay_pg_slog(slog_dir_, replay_start_cursor, committed_trans_getter, checkpoint))) {
|
|
STORAGE_LOG(WARN, "fail to replay pg slog", K(ret));
|
|
} else if (OB_FAIL(file_mgr_.replay_over())) {
|
|
STORAGE_LOG(WARN, "fail to replay over file mgr", K(ret));
|
|
}
|
|
STORAGE_LOG(INFO, "read checkpoint end", K(ret), K_(slog_dir), K(svr_addr_),
|
|
K(replay_start_cursor), K(checkpoint));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminSlogReplayer::ServerMetaSLogFilter::filter(
|
|
const ObISLogFilter::Param ¶m,
|
|
bool &is_filtered) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
enum ObRedoLogMainType main_type = OB_REDO_LOG_MAX;
|
|
int32_t sub_type = 0;
|
|
is_filtered = false;
|
|
ObIRedoModule::parse_subcmd(param.subcmd_, main_type, sub_type);
|
|
is_filtered = (OB_REDO_LOG_TENANT_FILE != main_type);
|
|
return ret;
|
|
}
|
|
|
|
int ObAdminSlogReplayer::PGMetaSLogFilter::filter(
|
|
const ObISLogFilter::Param ¶m,
|
|
bool &is_filtered) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
enum ObRedoLogMainType main_type = OB_REDO_LOG_MAX;
|
|
int32_t sub_type = 0;
|
|
is_filtered = false;
|
|
ObIRedoModule::parse_subcmd(param.subcmd_, main_type, sub_type);
|
|
is_filtered = (OB_REDO_LOG_PARTITION != main_type);
|
|
if (!is_filtered) {
|
|
if (OB_VIRTUAL_DATA_FILE_ID == param.attr_.data_file_id_) {
|
|
is_filtered = false;
|
|
} else {
|
|
ObTenantFileKey file_key(param.attr_.tenant_id_, param.attr_.data_file_id_);
|
|
ObTenantFileInfo file_info;
|
|
if (OB_FAIL(file_mgr_.get_tenant_file_info(file_key, file_info))) {
|
|
if (OB_ENTRY_NOT_EXIST == ret) {
|
|
is_filtered = true;
|
|
ret = OB_SUCCESS;
|
|
}
|
|
} else {
|
|
is_filtered = !file_info.is_normal_status();
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ObAdminDumpsstExecutor::print_usage()
|
|
{
|
|
printf("\n");
|
|
printf("Usage: dumpsst command [command args] [options]\n");
|
|
printf("commands:\n");
|
|
printf(HELP_FMT, "-d,--dump", "dump, args: [super_block|print_macro|macro_block|macro_meta|sstable|sstable_meta]");
|
|
printf(HELP_FMT, "-h,--help", "display this message.");
|
|
|
|
printf("options:\n");
|
|
printf(HELP_FMT, "-f,--data-file-name", "data file path");
|
|
printf(HELP_FMT, "-a,--macro-id", "macro block index");
|
|
printf(HELP_FMT, "-i,--micro-id", "micro block id, -1 means all micro blocks");
|
|
printf(HELP_FMT, "-n,--macro-size", "macro block size, in bytes");
|
|
printf(HELP_FMT, "-q,--quiet", "log level: ERROR");
|
|
printf(HELP_FMT, "-t,--table-key", "table key: table_type,table_id:partition_id,index_id,base_version:multi_version_start:snapshot_version,start_log_ts:end_log_ts:max_log_ts,major_version");
|
|
printf(HELP_FMT, "-s,--skip_replay", "skip slog replay, only work for macro_block mode");
|
|
printf("samples:\n");
|
|
printf(" dump all metas and rows in macro: \n");
|
|
printf("\tob_admin dumpsst -d pm -f block_file_path -a macro_id -i micro_id\n");
|
|
printf(" dump all rows in macro: \n");
|
|
printf("\tob_admin dumpsst -d macro_block -f block_file_path -a macro_id -i micro_id: dump rows in macro\n");
|
|
}
|
|
} //namespace tools
|
|
} //namespace oceanbase
|