Add check_ls_exist interface
This commit is contained in:
@ -254,6 +254,60 @@ TEST_F(TestLSStatusOperator, add_tenant)
|
||||
}
|
||||
ASSERT_EQ(OB_ITER_END, ret);
|
||||
}*/
|
||||
|
||||
TEST_F(TestLSStatusOperator, test_check_ls_exist)
|
||||
{
|
||||
uint64_t user_tenant_id = OB_INVALID_TENANT_ID;
|
||||
ASSERT_EQ(OB_SUCCESS, create_tenant());
|
||||
ASSERT_EQ(OB_SUCCESS, get_tenant_id(user_tenant_id));
|
||||
uint64_t meta_tenant_id = gen_meta_tenant_id(user_tenant_id);
|
||||
|
||||
ObLSID user_ls_id(1001);
|
||||
ObLSID uncreated_ls_id(6666);
|
||||
ObLSID invalid_ls_id(123);
|
||||
const uint64_t not_exist_tenant_id = 1234;
|
||||
ObLSStatusOperator::ObLSExistState state;
|
||||
|
||||
// user tenant
|
||||
ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(user_tenant_id, SYS_LS, state));
|
||||
ASSERT_TRUE(state.is_existing());
|
||||
state.reset();
|
||||
ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(user_tenant_id, user_ls_id, state));
|
||||
ASSERT_TRUE(state.is_existing());
|
||||
state.reset();
|
||||
ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(user_tenant_id, uncreated_ls_id, state));
|
||||
ASSERT_TRUE(state.is_uncreated());
|
||||
|
||||
common::ObMySQLProxy &inner_proxy = get_curr_simple_server().get_observer().get_mysql_proxy();
|
||||
ObSqlString sql;
|
||||
int64_t affected_rows = 0;
|
||||
ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("delete from oceanbase.__all_ls_status where tenant_id = %lu and ls_id = %ld", user_tenant_id, ObLSID::SYS_LS_ID));
|
||||
ASSERT_EQ(OB_SUCCESS, inner_proxy.write(ObLSLifeIAgent::get_exec_tenant_id(user_tenant_id), sql.ptr(), affected_rows));
|
||||
state.reset();
|
||||
ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(user_tenant_id, SYS_LS, state));
|
||||
ASSERT_TRUE(state.is_deleted());
|
||||
|
||||
ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(user_tenant_id, invalid_ls_id, state));
|
||||
|
||||
// meta tenant
|
||||
state.reset();
|
||||
ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(meta_tenant_id, SYS_LS, state));
|
||||
ASSERT_TRUE(state.is_existing());
|
||||
ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(meta_tenant_id, user_ls_id, state));
|
||||
ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(meta_tenant_id, invalid_ls_id, state));
|
||||
|
||||
// sys tenant
|
||||
state.reset();
|
||||
ASSERT_EQ(OB_SUCCESS, ObLSStatusOperator::check_ls_exist(OB_SYS_TENANT_ID, SYS_LS, state));
|
||||
ASSERT_TRUE(state.is_existing());
|
||||
ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(OB_SYS_TENANT_ID, user_ls_id, state));
|
||||
ASSERT_EQ(OB_INVALID_ARGUMENT, ObLSStatusOperator::check_ls_exist(OB_SYS_TENANT_ID, invalid_ls_id, state));
|
||||
|
||||
// not exist tenant
|
||||
ASSERT_EQ(OB_TENANT_NOT_EXIST, ObLSStatusOperator::check_ls_exist(not_exist_tenant_id, SYS_LS, state));
|
||||
|
||||
}
|
||||
|
||||
} // namespace share
|
||||
} // namespace oceanbase
|
||||
|
||||
|
||||
@ -174,11 +174,12 @@ int ObLSCreator::create_user_ls(
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", KR(ret));
|
||||
} else if (OB_UNLIKELY(!status_info.is_valid()
|
||||
|| !id_.is_user_ls()
|
||||
|| 0 >= zone_locality.count()
|
||||
|| 0 >= paxos_replica_num
|
||||
|| !create_scn.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", KR(ret), K(status_info), K(zone_locality),
|
||||
LOG_WARN("invalid argument", KR(ret), K(status_info), K_(id), K(zone_locality),
|
||||
K(paxos_replica_num), K(create_scn), K(palf_base_info));
|
||||
} else if (OB_ISNULL(proxy_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
|
||||
@ -93,17 +93,7 @@ public:
|
||||
* */
|
||||
static uint64_t get_exec_tenant_id(const uint64_t tenant_id)
|
||||
{
|
||||
uint64_t ret_tenant_id = OB_INVALID_TENANT_ID;
|
||||
if (is_sys_tenant(tenant_id)) {
|
||||
ret_tenant_id = tenant_id;
|
||||
} else if (is_meta_tenant(tenant_id)) {
|
||||
// ls of meta tenant in sys tenant
|
||||
ret_tenant_id = OB_SYS_TENANT_ID;
|
||||
} else {
|
||||
// all ls of user tenant in meta tenant
|
||||
ret_tenant_id = gen_meta_tenant_id(tenant_id);
|
||||
}
|
||||
return ret_tenant_id;
|
||||
return get_private_table_exec_tenant_id(tenant_id);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -1228,5 +1228,71 @@ int ObLSStatusOperator::check_all_ls_has_leader(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLSStatusOperator::check_ls_exist(
|
||||
const uint64_t tenant_id,
|
||||
const ObLSID &ls_id,
|
||||
ObLSExistState &state)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
state.reset();
|
||||
schema::ObSchemaGetterGuard schema_guard;
|
||||
bool tenant_exist = false;
|
||||
ObSqlString sql;
|
||||
if (OB_UNLIKELY(!ls_id.is_valid_with_tenant(tenant_id))) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid args", KR(ret), K(tenant_id), K(ls_id));
|
||||
} else if (OB_ISNULL(GCTX.schema_service_) || OB_ISNULL(GCTX.sql_proxy_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("GCTX has null ptr", KR(ret));
|
||||
} else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
|
||||
LOG_WARN("fail to get tenant schema guard", KR(ret));
|
||||
} else if (OB_FAIL(schema_guard.check_tenant_exist(tenant_id, tenant_exist))) {
|
||||
LOG_WARN("fail to check tenant exist", KR(ret), K(tenant_id));
|
||||
} else if (OB_UNLIKELY(!tenant_exist)) {
|
||||
ret = OB_TENANT_NOT_EXIST;
|
||||
LOG_WARN("tenant not exist", KR(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(sql.assign_fmt(
|
||||
"SELECT (SELECT COUNT(*) > 0 FROM %s WHERE tenant_id = %lu AND ls_id = %ld) AS ls_is_existing, "
|
||||
"MAX(ls_id) < %ld AS ls_is_uncreated FROM %s WHERE tenant_id = %lu",
|
||||
OB_ALL_LS_STATUS_TNAME,
|
||||
tenant_id,
|
||||
ls_id.id(),
|
||||
ls_id.id(),
|
||||
OB_ALL_LS_STATUS_TNAME,
|
||||
tenant_id))) {
|
||||
LOG_WARN("assign sql failed", KR(ret), K(tenant_id), K(ls_id), K(sql));
|
||||
} else {
|
||||
SMART_VAR(ObISQLClient::ReadResult, result) {
|
||||
bool ls_is_existing = false;
|
||||
bool ls_is_uncreated = false;
|
||||
common::sqlclient::ObMySQLResult *res = NULL;
|
||||
uint64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id);
|
||||
if (OB_FAIL(GCTX.sql_proxy_->read(result, exec_tenant_id, sql.ptr()))) {
|
||||
LOG_WARN("execute sql failed", KR(ret),
|
||||
K(tenant_id), K(ls_id), K(exec_tenant_id), K(sql));
|
||||
} else if (OB_ISNULL(res = result.get_result())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get mysql result failed", KR(ret),
|
||||
K(tenant_id), K(ls_id), K(exec_tenant_id), K(sql));
|
||||
} else if (OB_FAIL(res->next())) {
|
||||
LOG_WARN("next failed", KR(ret), K(tenant_id), K(ls_id), K(sql));
|
||||
} else if (OB_FAIL(res->get_bool("ls_is_existing", ls_is_existing))) {
|
||||
LOG_WARN("fail to get ls_is_existing", KR(ret), K(tenant_id), K(ls_id));
|
||||
} else if (OB_FAIL(res->get_bool("ls_is_uncreated", ls_is_uncreated))) {
|
||||
LOG_WARN("fail to get ls_is_uncreated", KR(ret), K(tenant_id), K(ls_id));
|
||||
} else if (ls_is_existing) {
|
||||
state.set_existing();
|
||||
} else if (ls_is_uncreated) {
|
||||
state.set_uncreated();
|
||||
} else {
|
||||
state.set_deleted();
|
||||
}
|
||||
LOG_INFO("check ls exist finished", KR(ret),
|
||||
K(tenant_id), K(ls_id), K(state), K(ls_is_existing), K(ls_is_uncreated));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}//end of share
|
||||
}//end of ob
|
||||
|
||||
@ -334,6 +334,47 @@ public:
|
||||
const char *print_str,
|
||||
bool &has_ls_without_leader,
|
||||
common::ObSqlString &error_msg);
|
||||
|
||||
struct ObLSExistState final
|
||||
{
|
||||
public:
|
||||
enum State
|
||||
{
|
||||
INVALID_STATE = -1,
|
||||
EXISTING,
|
||||
DELETED,
|
||||
UNCREATED,
|
||||
MAX_STATE
|
||||
};
|
||||
ObLSExistState() : state_(INVALID_STATE) {}
|
||||
~ObLSExistState() {}
|
||||
void reset() { state_ = INVALID_STATE; }
|
||||
void set_existing() { state_ = EXISTING; }
|
||||
void set_deleted() { state_ = DELETED; }
|
||||
void set_uncreated() { state_ = UNCREATED; }
|
||||
bool is_valid() const { return state_ > INVALID_STATE && state_ < MAX_STATE; }
|
||||
bool is_existing() const { return EXISTING == state_; }
|
||||
bool is_deleted() const { return DELETED == state_; }
|
||||
bool is_uncreated() const { return UNCREATED == state_; }
|
||||
|
||||
TO_STRING_KV(K_(state));
|
||||
private:
|
||||
State state_;
|
||||
};
|
||||
|
||||
/* check if the ls exists by __all_virtual_ls_status
|
||||
*
|
||||
* @param[in] tenant_id: target tenant_id
|
||||
* @param[in] ls_id: target ls_id
|
||||
* @param[out] state: EXISTING/DELETED/UNCREATED
|
||||
* @return
|
||||
* - OB_SUCCESS: check successfully
|
||||
* - OB_TENANT_NOT_EXIST: tenant not exist
|
||||
* - OB_INVALID_ARGUMENT: invalid ls_id or tenant_id
|
||||
* - other: other failures
|
||||
*/
|
||||
static int check_ls_exist(const uint64_t tenant_id, const ObLSID &ls_id, ObLSExistState &state);
|
||||
|
||||
private:
|
||||
int get_visible_member_list_str_(const ObMemberList &member_list,
|
||||
common::ObIAllocator &allocator,
|
||||
|
||||
@ -54,13 +54,14 @@ public:
|
||||
|
||||
// LS attribute interface
|
||||
bool is_sys_ls() const { return SYS_LS_ID == id_; }
|
||||
bool is_user_ls() const { return id_ > MIN_USER_LS_ID && SCHEDULER_LS_ID != id_; }
|
||||
bool is_scheduler_ls() const { return SCHEDULER_LS_ID == id_; }
|
||||
bool is_valid() const { return INVALID_LS_ID != id_; }
|
||||
bool is_valid_with_tenant(const uint64_t tenant_id) const
|
||||
{
|
||||
// 1. User tenant support all valid LS
|
||||
// 1. User tenant have SYS LS and User LS
|
||||
// 2. SYS tenant and Meta tenant only have SYS LS
|
||||
return (is_user_tenant(tenant_id) && is_valid())
|
||||
return (is_user_tenant(tenant_id) && (is_sys_ls() || is_user_ls()))
|
||||
|| ((is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) && is_sys_ls());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user