patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

View File

@ -0,0 +1,520 @@
/**
* 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_routine.h"
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <unistd.h>
#include "ob_admin_utils.h"
#include "share/ob_rpc_struct.h"
using namespace std;
#include "lib/time/ob_time_utility.h" // ObTimeUtility
#define ADMIN_WARN(format, ...) fprintf(stderr, format "\n", ##__VA_ARGS__)
#define DEF_COMMAND(t, cmd, v...) \
namespace oceanbase { \
namespace tools { \
class ObAdmin_##cmd \
: public ObAdminRoutine \
{ \
public: \
ObAdmin_##cmd() \
: ObAdminRoutine(#cmd, ##v) \
{ t; g_routines.push_back(this); } \
virtual int process(); \
} command_##cmd; }} \
int ObAdmin_##cmd::process()
#define TRANS target_="TRX"
#define SERVER target_="SVR"
using namespace oceanbase::tools;
using namespace oceanbase::common;
namespace oceanbase {
namespace tools {
std::vector<ObAdminRoutine*> g_routines;
} /* end of namespace tools */
} /* end of namespace oceanbase */
ObAdminRoutine::ObAdminRoutine(const string &action_name, int version, const string &args)
: action_name_(action_name), version_(version), timeout_(3000000)
{
args_ = args;
}
ObAdminRoutine::~ObAdminRoutine()
{}
bool ObAdminRoutine::match(const string &cmd) const
{
string action;
string::size_type pos;
pos = cmd.find(" ");
action = cmd.substr(0, pos);
return action == action_name_;
}
DEF_COMMAND(TRANS, dump_memtable, 1, "tenant_id:ls_id:tablet_id # dump memtable to /tmp/memtable.*")
{
int ret = OB_SUCCESS;
string arg_str;
uint64_t tablet_id;
obrpc::ObDumpMemtableArg arg;
if (cmd_ == action_name_) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("should provide partition_key");
} else {
arg_str = cmd_.substr(action_name_.length() + 1);
}
if (OB_FAIL(ret)) {
} else if (3 != sscanf(arg_str.c_str(), "%ld:%ld:%ld", &arg.tenant_id_, &arg.ls_id_, &tablet_id)) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid arg", K(ret));
} else if (FALSE_IT(arg.tablet_id_ = tablet_id)) {
} else if (OB_SUCCESS != (ret = client_->dump_memtable(arg))) {
COMMON_LOG(ERROR, "send req fail", K(ret));
}
COMMON_LOG(INFO, "dump_memtable", K(arg));
return ret;
}
DEF_COMMAND(TRANS, dump_tx_data_memtable, 1, "tenant_id:ls_id # dump tx data memtable to /tmp/tx_data_memtable.*")
{
int ret = OB_SUCCESS;
string arg_str;
obrpc::ObDumpTxDataMemtableArg arg;
if (cmd_.length() <= action_name_.length()) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("cmd is not completed.");
} else {
arg_str = cmd_.substr(action_name_.length() + 1);
}
if (OB_FAIL(ret)) {
} else if (2 != sscanf(arg_str.c_str(), "%ld:%ld", &arg.tenant_id_, &arg.ls_id_)) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid arg", K(ret));
} else if (OB_SUCCESS != (ret = client_->dump_tx_data_memtable(arg))) {
COMMON_LOG(ERROR, "send req fail", K(ret));
}
COMMON_LOG(INFO, "dump_tx_data_memtable", K(arg));
return ret;
}
DEF_COMMAND(TRANS, dump_single_tx_data, 1, "tenant_id:ls_id:tx_id # dump a single tx data to /tmp/single_tx_data.*")
{
int ret = OB_SUCCESS;
string arg_str;
obrpc::ObDumpSingleTxDataArg arg;
if (cmd_.length() <= action_name_.length()) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("cmd is not completed");
} else {
arg_str = cmd_.substr(action_name_.length() + 1);
}
if (OB_FAIL(ret)) {
} else if (3 != sscanf(arg_str.c_str(), "%ld:%ld:%ld", &arg.tenant_id_, &arg.ls_id_, &arg.tx_id_)) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid arg", KR(ret));
} else if (OB_SUCCESS != (ret = client_->dump_single_tx_data(arg))) {
COMMON_LOG(ERROR, "send req fail", K(ret));
}
COMMON_LOG(INFO, "dump_single_tx_data", K(arg));
return ret;
}
DEF_COMMAND(TRANS, force_set_replica_num, 1, "table_id:partition_idx:partition_cnt replica_num # force set replica_num")
{
return OB_NOT_SUPPORTED;
}
DEF_COMMAND(TRANS, force_set_parent, 1, "table_id:partition_idx:partition_cnt ip:port # force set parent")
{
return OB_NOT_SUPPORTED;
}
DEF_COMMAND(TRANS, force_set_server_list, 1, "replica_num ip:port ip:port ... #force set server list")
{
int ret = OB_SUCCESS;
string replica_num_str;
ObAddr server;
string server_str;
obrpc::ObForceSetServerListArg arg;
if (cmd_ == action_name_) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("should provide replica_num and ip:port");
} else {
string cmd_tail = cmd_.substr(action_name_.length() + 1);
string::size_type pos;
pos = cmd_tail.find(" ");
if (pos == string::npos) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("should provide replica_num and ip:port");
} else {
replica_num_str = cmd_tail.substr(0, pos);
arg.replica_num_ = atoi(replica_num_str.c_str());
cmd_tail = cmd_tail.substr(pos + 1);
while ((pos = cmd_tail.find(" ")) != string::npos && OB_SUCC(ret)) {
server_str = cmd_tail.substr(0, pos);
if (OB_FAIL(server.parse_from_cstring(server_str.c_str()))) {
ADMIN_WARN("server parse_from_cstring failed");
} else if (OB_FAIL(arg.server_list_.push_back(server))) {
ADMIN_WARN("server_list_ push_back failed");
} else {
cmd_tail = cmd_tail.substr(pos+1);
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(server.parse_from_cstring(cmd_tail.c_str()))) {
ADMIN_WARN("server parse_from_cstring failed");
} else if (OB_FAIL(arg.server_list_.push_back(server))) {
ADMIN_WARN("server_list_ push_back failed");
} else {
// do nothing
}
}
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(client_->force_set_server_list(arg))) {
COMMON_LOG(ERROR, "force_set_server_list failed", K(ret));
}
}
COMMON_LOG(INFO, "force_set_server_list", K(ret), "replica_num", arg.replica_num_, "server_list", arg.server_list_);
return ret;
}
DEF_COMMAND(TRANS, halt_all_prewarming, 1, "# halt all warming up, release memstores")
{
int ret = OB_SUCCESS;
if (OB_SUCCESS != (ret = client_->halt_all_prewarming())) {
COMMON_LOG(ERROR, "halt_all_warming_up", K(ret));
}
return ret;
}
DEF_COMMAND(TRANS, set_server_config, 1, "#set config")
{
int ret = OB_SUCCESS;
string sstr;
ObString config_str;
if (cmd_ == action_name_) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("should provide partition_key");
} else {
sstr = cmd_.substr(action_name_.length() + 1);
config_str.assign_ptr(sstr.c_str(), static_cast<int32_t>(sstr.length()));
}
if (OB_FAIL(ret)) {
} else if (OB_SUCCESS != client_->set_config(config_str)) {
COMMON_LOG(ERROR, "add config failed.", K(config_str), K(ret));
}
return ret;
}
DEF_COMMAND(TRANS, set_tenant_config, 1, "tenant_id config_item1=config_value1,config_item2=config_value2 # set tenant config")
{
int ret = OB_SUCCESS;
string arg_str;
ObTenantConfigArg arg;
string::size_type pos;
string tenant_id_str;
string config_str;
if (cmd_ == action_name_) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("should provide partition_key");
} else {
arg_str = cmd_.substr(action_name_.length() + 1);
// resolve tenant_id
pos = arg_str.find(" ");
if (pos == string::npos) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid format", K(ret), "str", arg_str.c_str());
} else {
tenant_id_str = arg_str.substr(0, pos);
char *end_ptr = NULL;
arg.tenant_id_ = strtoll(tenant_id_str.c_str(), &end_ptr, 10);
if (*end_ptr != '\0') {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid format", K(ret), "str", arg_str.c_str());
}
}
// resolve config_str
if (OB_SUCC(ret)) {
pos = arg_str.find_first_not_of(' ', pos);
if (pos == string::npos) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid format", K(ret), "str", arg_str.c_str());
} else {
config_str = arg_str.substr(pos);
if (config_str.length() > common::OB_MAX_EXTRA_CONFIG_LENGTH) {
ret = OB_SIZE_OVERFLOW;
COMMON_LOG(WARN, "invalid config str length", K(ret), "str", arg_str.c_str());
} else {
arg.config_str_.assign_ptr(config_str.c_str(), config_str.length());
}
}
}
}
if (OB_FAIL(ret)) {
} else if (OB_SUCCESS != client_->set_tenant_config(arg)) {
COMMON_LOG(ERROR, "add tenant config failed.", K(arg), K(ret));
}
COMMON_LOG(INFO, "set_tenant_config", K(ret), K(arg));
return ret;
}
DEF_COMMAND(SERVER, diag, 1, "#login OceanBase")
{
int ret = OB_SUCCESS;
char buf[1024];
ObString argstr(1024, 0, buf);
if (OB_FAIL(client_->get_diagnose_args(argstr))) {
ADMIN_WARN("get diagnose args from observer fail, ret: %d", ret);
} else {
vector<string> args;
tools::split(string(argstr.ptr(), argstr.length()), ' ', args);
for (vector<string>::const_iterator it = args.begin();
it != args.end();
it++) {
cout << *it << endl;
}
tools::execv("/usr/bin/mysql", args);
}
return ret;
}
DEF_COMMAND(SERVER, force_switch_ilog_file, 1, "#force switch ilog file")
{
int ret = OB_SUCCESS;
obrpc::ObForceSwitchILogFileArg arg;
arg.force_ = true;
if (OB_SUCCESS != (ret = client_->force_switch_ilog_file(arg))) {
COMMON_LOG(ERROR, "send req failed", K(ret));
}
COMMON_LOG(INFO, "force_switch_ilog_file", K(ret));
return ret;
}
DEF_COMMAND(SERVER, force_set_all_as_single_replica, 1, "#force set all as single replica")
{
int ret = OB_SUCCESS;
obrpc::ObForceSetAllAsSingleReplicaArg arg;
arg.force_ = true;
if (OB_SUCCESS != (ret = client_->force_set_all_as_single_replica(arg))) {
COMMON_LOG(ERROR, "send req failed", K(ret));
}
COMMON_LOG(INFO, "force_set_all_as_single_replica", K(ret));
return ret;
}
DEF_COMMAND(SERVER, force_create_sys_table, 1, "tenant_id:table_id:last_replay_log_id # force create sys table")
{
int ret = OB_SUCCESS;
string arg_str;
obrpc::ObForceCreateSysTableArg arg;
if (cmd_ == action_name_) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("should provide tenant_id:table_id:last_replay_log_id");
} else {
arg_str = cmd_.substr(action_name_.length() + 1);
}
if (OB_FAIL(ret)) {
} else if (3 != sscanf(arg_str.c_str(), "%ld:%ld:%ld", &arg.tenant_id_, &arg.table_id_, &arg.last_replay_log_id_)) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid arg", K(ret));
} else if (OB_SUCCESS != (ret = client_->force_create_sys_table(arg))) {
COMMON_LOG(ERROR, "send req failed", K(ret));
}
COMMON_LOG(INFO, "force create sys table", K(ret), K(arg));
return ret;
}
DEF_COMMAND(SERVER, force_set_locality, 1, "tenant_id locality # force set locality")
{
int ret = OB_SUCCESS;
string arg_str;
obrpc::ObForceSetLocalityArg arg;
if (cmd_ == action_name_) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("should provide tenant_id/locality");
} else {
arg_str = cmd_.substr(action_name_.length() + 1);
string::size_type pos;
string tenant_id_str;
string locality_str;
// resolve tenant_id
pos = arg_str.find(" ");
if (pos == string::npos) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid format", K(ret), "str", arg_str.c_str());
} else {
tenant_id_str = arg_str.substr(0, pos);
char *end_ptr = NULL;
arg.exec_tenant_id_ = strtoll(tenant_id_str.c_str(), &end_ptr, 10);
if (*end_ptr != '\0') {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid format", K(ret), "str", arg_str.c_str());
}
}
// resolve locality
if (OB_SUCC(ret)) {
pos = arg_str.find_first_not_of(' ', pos);
if (pos == string::npos) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid format", K(ret), "str", arg_str.c_str());
} else {
locality_str = arg_str.substr(pos);
if (locality_str.length() > common::MAX_LOCALITY_LENGTH) {
ret = OB_SIZE_OVERFLOW;
COMMON_LOG(WARN, "invalid locality str length", K(ret), "str", arg_str.c_str());
} else {
arg.locality_.assign_ptr(locality_str.c_str(), locality_str.length());
}
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(client_->force_set_locality(arg))) {
COMMON_LOG(ERROR, "send req failed", K(ret));
}
}
}
COMMON_LOG(INFO, "force set locality", K(ret), K(arg));
return ret;
}
DEF_COMMAND(SERVER, force_disable_blacklist, 1, "# force disable blacklist")
{
int ret = OB_SUCCESS;
if (OB_SUCCESS != (ret = client_->force_disable_blacklist())) {
COMMON_LOG(ERROR, "send req fail", K(ret));
}
return ret;
}
DEF_COMMAND(SERVER, force_enable_blacklist, 1, "# force enable blacklist")
{
int ret = OB_SUCCESS;
if (OB_SUCCESS != (ret = client_->force_enable_blacklist())) {
COMMON_LOG(ERROR, "send req fail", K(ret));
}
return ret;
}
DEF_COMMAND(SERVER, force_clear_blacklist, 1, "# force clear blacklist")
{
int ret = OB_SUCCESS;
if (OB_SUCCESS != (ret = client_->force_clear_srv_blacklist())) {
COMMON_LOG(ERROR, "send req fail", K(ret));
}
return ret;
}
DEF_COMMAND(SERVER, force_switch_leader, 1, "table_id:partition_idx:partition_cnt ip:port # force switch leader")
{
return OB_NOT_SUPPORTED;
}
DEF_COMMAND(SERVER, batch_switch_rs_leader, 1, "ip:port # batch switch rs leader")
{
int ret = OB_SUCCESS;
string pkey_str;
string new_parent_str; // ip:port
ObAddr new_leader;
obrpc::ObSwitchLeaderArg arg;
ObString cmd;
ObString action_name;
cmd.assign_ptr(cmd_.c_str(), static_cast<int32_t>(cmd_.length()));
action_name.assign_ptr(action_name_.c_str(), static_cast<int32_t>(action_name_.length()));
if (OB_UNLIKELY(cmd_ == action_name_)) {
new_leader.reset();
COMMON_LOG(INFO, "addr is default, auto batch switch rs leader",
K(cmd), K(action_name));
} else {
new_parent_str = cmd_.substr(action_name_.length() + 1);
if (OB_SUCCESS != (ret = new_leader.parse_from_cstring(new_parent_str.c_str()))) {
COMMON_LOG(ERROR, "new_leader.parse_from_cstring fail", K(new_parent_str.c_str()),
KR(ret), K(cmd), K(action_name));
}
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(client_)) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "client_ is NULL", KR(ret));
} else if (OB_SUCCESS != (ret = client_->batch_switch_rs_leader(new_leader))) {
COMMON_LOG(ERROR, "send batch switch rs leader req fail",
KR(ret), K(new_leader), K(cmd), K(action_name));
}
return ret;
}
DEF_COMMAND(SERVER, batch_switch_leader, 1, "[table_id:partition_idx;] ip:port # batch switch leader")
{
return OB_NOT_SUPPORTED;
}
DEF_COMMAND(SERVER, modify_tenant_memory, 1,
"tenant_id:memory_size:refresh_interval(s) # modify_tenant_memory")
{
int ret = OB_SUCCESS;
int64_t tenant_id = 0;
int64_t memory_size = 0;
int64_t refresh_interval = 0;
obrpc::ObTenantMemoryArg tenant_memory;
if (cmd_ == action_name_) {
ret = OB_INVALID_ARGUMENT;
ADMIN_WARN("should provide tenant_id and memory_size");
} else {
string cmd_tail = cmd_.substr(action_name_.length() + 1);
if (3 != sscanf(cmd_tail.c_str(), "%ld:%ld:%ld", &tenant_id, &memory_size, &refresh_interval)) {
ret = OB_INVALID_ARGUMENT;
COMMON_LOG(WARN, "invalid argument", K(ret), K(tenant_id), K(memory_size), K(refresh_interval));
}
}
if (OB_FAIL(ret)) {
} else {
tenant_memory.tenant_id_ = tenant_id;
tenant_memory.memory_size_ = memory_size;
tenant_memory.refresh_interval_ = refresh_interval;
COMMON_LOG(INFO, "tenant_id, memory_size, refresh_interval", K(tenant_id),
K(memory_size), K(refresh_interval));
if (OB_SUCCESS != (ret = client_->update_tenant_memory(tenant_memory))) {
COMMON_LOG(ERROR, "send req fail", K(ret));
}
}
return ret;
}
DEF_COMMAND(TRANS, kill_part_trans_ctx, 1,
"partition_id:partition_cnt:table_id trans_inc:timestamp svr_ip svr_port # kill_part_trans_ctx")
{
return OB_NOT_SUPPORTED;
}