From 40f2f0e0c6f7cefbd757ff2135e713a7de4ac7cf Mon Sep 17 00:00:00 2001 From: obdev Date: Sat, 28 Jan 2023 15:38:06 +0800 Subject: [PATCH] Add check_ls_exist interface --- .../simple_server/test_ls_status_operator.cpp | 54 +++++++++++++++ src/share/ls/ob_ls_creator.cpp | 3 +- src/share/ls/ob_ls_i_life_manager.h | 12 +--- src/share/ls/ob_ls_status_operator.cpp | 66 +++++++++++++++++++ src/share/ls/ob_ls_status_operator.h | 41 ++++++++++++ src/share/ob_ls_id.h | 5 +- 6 files changed, 167 insertions(+), 14 deletions(-) diff --git a/mittest/simple_server/test_ls_status_operator.cpp b/mittest/simple_server/test_ls_status_operator.cpp index c37acd5268..68413e14d3 100644 --- a/mittest/simple_server/test_ls_status_operator.cpp +++ b/mittest/simple_server/test_ls_status_operator.cpp @@ -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 diff --git a/src/share/ls/ob_ls_creator.cpp b/src/share/ls/ob_ls_creator.cpp index 46786ebe44..f2e3a33ae5 100644 --- a/src/share/ls/ob_ls_creator.cpp +++ b/src/share/ls/ob_ls_creator.cpp @@ -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; diff --git a/src/share/ls/ob_ls_i_life_manager.h b/src/share/ls/ob_ls_i_life_manager.h index 2e87fca239..61345e2dd0 100644 --- a/src/share/ls/ob_ls_i_life_manager.h +++ b/src/share/ls/ob_ls_i_life_manager.h @@ -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: diff --git a/src/share/ls/ob_ls_status_operator.cpp b/src/share/ls/ob_ls_status_operator.cpp index 2d37fa96ec..de2612ffb2 100644 --- a/src/share/ls/ob_ls_status_operator.cpp +++ b/src/share/ls/ob_ls_status_operator.cpp @@ -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 diff --git a/src/share/ls/ob_ls_status_operator.h b/src/share/ls/ob_ls_status_operator.h index 02c47cda78..eae2e043de 100644 --- a/src/share/ls/ob_ls_status_operator.h +++ b/src/share/ls/ob_ls_status_operator.h @@ -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, diff --git a/src/share/ob_ls_id.h b/src/share/ob_ls_id.h index 515b75ae8c..007d452c53 100644 --- a/src/share/ob_ls_id.h +++ b/src/share/ob_ls_id.h @@ -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()); }