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); |   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 share | ||||||
| } // namespace oceanbase | } // namespace oceanbase | ||||||
|  |  | ||||||
|  | |||||||
| @ -174,11 +174,12 @@ int ObLSCreator::create_user_ls( | |||||||
|     ret = OB_INVALID_ARGUMENT; |     ret = OB_INVALID_ARGUMENT; | ||||||
|     LOG_WARN("invalid argument", KR(ret)); |     LOG_WARN("invalid argument", KR(ret)); | ||||||
|   } else if (OB_UNLIKELY(!status_info.is_valid() |   } else if (OB_UNLIKELY(!status_info.is_valid() | ||||||
|  |                          || !id_.is_user_ls() | ||||||
|                          || 0 >= zone_locality.count() |                          || 0 >= zone_locality.count() | ||||||
|                          || 0 >= paxos_replica_num |                          || 0 >= paxos_replica_num | ||||||
|                          || !create_scn.is_valid())) { |                          || !create_scn.is_valid())) { | ||||||
|     ret = OB_INVALID_ARGUMENT; |     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)); |              K(paxos_replica_num), K(create_scn), K(palf_base_info)); | ||||||
|   } else if (OB_ISNULL(proxy_)) { |   } else if (OB_ISNULL(proxy_)) { | ||||||
|     ret = OB_ERR_UNEXPECTED; |     ret = OB_ERR_UNEXPECTED; | ||||||
|  | |||||||
| @ -93,17 +93,7 @@ public: | |||||||
|    * */ |    * */ | ||||||
|   static uint64_t get_exec_tenant_id(const uint64_t tenant_id) |   static uint64_t get_exec_tenant_id(const uint64_t tenant_id) | ||||||
|   { |   { | ||||||
|     uint64_t ret_tenant_id = OB_INVALID_TENANT_ID; |     return get_private_table_exec_tenant_id(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; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  | |||||||
| @ -1228,5 +1228,71 @@ int ObLSStatusOperator::check_all_ls_has_leader( | |||||||
|   return ret; |   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 share | ||||||
| }//end of ob | }//end of ob | ||||||
|  | |||||||
| @ -334,6 +334,47 @@ public: | |||||||
|       const char *print_str, |       const char *print_str, | ||||||
|       bool &has_ls_without_leader, |       bool &has_ls_without_leader, | ||||||
|       common::ObSqlString &error_msg); |       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: | private: | ||||||
|   int get_visible_member_list_str_(const ObMemberList &member_list, |   int get_visible_member_list_str_(const ObMemberList &member_list, | ||||||
|                                   common::ObIAllocator &allocator, |                                   common::ObIAllocator &allocator, | ||||||
|  | |||||||
| @ -54,13 +54,14 @@ public: | |||||||
|  |  | ||||||
|   // LS attribute interface |   // LS attribute interface | ||||||
|   bool is_sys_ls() const { return SYS_LS_ID == id_; } |   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_scheduler_ls() const { return SCHEDULER_LS_ID == id_; } | ||||||
|   bool is_valid() const { return INVALID_LS_ID != id_; } |   bool is_valid() const { return INVALID_LS_ID != id_; } | ||||||
|   bool is_valid_with_tenant(const uint64_t tenant_id) const |   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 |     // 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()); |         || ((is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) && is_sys_ls()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 obdev
					obdev