Add check_ls_exist interface

This commit is contained in:
obdev
2023-01-28 15:38:06 +08:00
committed by ob-robot
parent 594a8d9f94
commit 40f2f0e0c6
6 changed files with 167 additions and 14 deletions

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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,

View File

@ -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());
}