[CP] [CP] Fix returning rowid error when different versions of the client are run together
This commit is contained in:
		| @ -239,8 +239,6 @@ int ObAllVirtualPsItemInfo::get_next_row_from_specified_tenant(uint64_t tenant_i | ||||
|         } else if (OB_ISNULL(stmt_item)) { | ||||
|           ret = OB_ERR_UNEXPECTED; | ||||
|           SERVER_LOG(WARN, "stmt_item is NULL", K(ret)); | ||||
|         } else { | ||||
|           // done | ||||
|         } | ||||
|         SERVER_LOG(DEBUG, "all setup", K(ret), K(tmp_ret), KP(stmt_info), KP(stmt_item)); | ||||
|  | ||||
|  | ||||
| @ -919,9 +919,12 @@ int ObSql::do_add_ps_cache(const PsCacheInfoCtx &info_ctx, | ||||
|     ObPsStmtItem *ps_stmt_item = NULL; | ||||
|     ObPsStmtInfo *ref_stmt_info = NULL; | ||||
|     bool duplicate_prepare = false; | ||||
|     ObPsSqlKey ps_key; | ||||
|     ps_key.db_id_ = db_id; | ||||
|     ps_key.ps_sql_ = info_ctx.normalized_sql_; | ||||
|     ps_key.is_client_return_hidden_rowid_ = session.is_client_return_rowid(); | ||||
|     // add stmt item | ||||
|     if (OB_FAIL(ps_cache->get_or_add_stmt_item(db_id, | ||||
|                                                info_ctx.normalized_sql_, | ||||
|     if (OB_FAIL(ps_cache->get_or_add_stmt_item(ps_key, | ||||
|                                                is_contain_tmp_tbl, | ||||
|                                                ps_stmt_item))) { | ||||
|       LOG_WARN("get or create stmt item faield", K(ret), K(db_id), K(info_ctx.normalized_sql_)); | ||||
| @ -1638,6 +1641,10 @@ int ObSql::handle_ps_prepare(const ObString &stmt, | ||||
|       bool need_do_real_prepare = false; | ||||
|       uint64_t db_id = OB_INVALID_ID; | ||||
|       (void)session.get_database_id(db_id); | ||||
|       ObPsSqlKey ps_key; | ||||
|       ps_key.db_id_ = db_id; | ||||
|       ps_key.ps_sql_ = stmt; | ||||
|       ps_key.is_client_return_hidden_rowid_ = session.is_client_return_rowid(); | ||||
|       ObPsStmtId inner_stmt_id = OB_INVALID_STMT_ID; | ||||
|       ObPsStmtId client_stmt_id = OB_INVALID_STMT_ID; | ||||
|       ObPsStmtInfo *stmt_info = NULL; | ||||
| @ -1665,7 +1672,7 @@ int ObSql::handle_ps_prepare(const ObString &stmt, | ||||
|                    K(db_id), K(stmt), K(need_do_real_prepare), K(context.secondary_namespace_), | ||||
|                    K(result.is_simple_ps_protocol())); | ||||
|         } | ||||
|       } else if (OB_FAIL(ps_cache->ref_stmt_item(db_id, stmt, stmt_item))) { | ||||
|       } else if (OB_FAIL(ps_cache->ref_stmt_item(ps_key, stmt_item))) { | ||||
|         if (OB_HASH_NOT_EXIST == ret) { | ||||
|           ret = OB_SUCCESS; | ||||
|           need_do_real_prepare = true; | ||||
| @ -1700,7 +1707,7 @@ int ObSql::handle_ps_prepare(const ObString &stmt, | ||||
|         LOG_WARN("fail to check schema version", K(ret)); | ||||
|       } else if (is_expired) { | ||||
|         stmt_info->set_is_expired(); | ||||
|         if (OB_FAIL(ps_cache->erase_stmt_item(inner_stmt_id, stmt_info->get_sql_key()))) { | ||||
|         if (OB_FAIL(ps_cache->erase_stmt_item(inner_stmt_id, ps_key))) { | ||||
|           LOG_WARN("fail to erase stmt item", K(ret), K(*stmt_info)); | ||||
|         } | ||||
|         need_do_real_prepare = true; | ||||
|  | ||||
| @ -27,6 +27,7 @@ namespace sql | ||||
| int ObPsSqlKey::deep_copy(const ObPsSqlKey &other, common::ObIAllocator &allocator) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   flag_ = other.flag_; | ||||
|   db_id_ = other.db_id_; | ||||
|   inc_id_ = other.inc_id_; | ||||
|   if (OB_FAIL(ObPsSqlUtils::deep_copy_str(allocator, other.ps_sql_, ps_sql_))) { | ||||
| @ -38,6 +39,7 @@ int ObPsSqlKey::deep_copy(const ObPsSqlKey &other, common::ObIAllocator &allocat | ||||
| ObPsSqlKey &ObPsSqlKey::operator=(const ObPsSqlKey &other) | ||||
| { | ||||
|   if (this != &other) { | ||||
|     flag_ = other.flag_; | ||||
|     db_id_ = other.db_id_; | ||||
|     inc_id_ = other.inc_id_; | ||||
|     ps_sql_ = other.ps_sql_; | ||||
| @ -47,7 +49,8 @@ ObPsSqlKey &ObPsSqlKey::operator=(const ObPsSqlKey &other) | ||||
|  | ||||
| bool ObPsSqlKey::operator==(const ObPsSqlKey &other) const | ||||
| { | ||||
|   return db_id_ == other.db_id_ && | ||||
|   return flag_ == other.flag_ && | ||||
|          db_id_ == other.db_id_ && | ||||
|          inc_id_ == other.inc_id_ && | ||||
|          ps_sql_.compare(other.ps_sql_) == 0; | ||||
| } | ||||
| @ -55,6 +58,7 @@ bool ObPsSqlKey::operator==(const ObPsSqlKey &other) const | ||||
| int64_t ObPsSqlKey::hash() const | ||||
| { | ||||
|   uint64_t hash_val = 0; | ||||
|   hash_val = murmurhash(&flag_, sizeof(uint32_t), hash_val); | ||||
|   hash_val = murmurhash(&db_id_, sizeof(uint64_t), hash_val); | ||||
|   hash_val = murmurhash(&inc_id_, sizeof(uint64_t), hash_val); | ||||
|   ps_sql_.hash(hash_val, hash_val); | ||||
|  | ||||
| @ -30,20 +30,24 @@ struct ObPsSqlKey | ||||
| { | ||||
| public: | ||||
|   ObPsSqlKey() | ||||
|     : db_id_(OB_INVALID_ID), | ||||
|     : flag_(0), | ||||
|       db_id_(OB_INVALID_ID), | ||||
|       inc_id_(OB_INVALID_ID), | ||||
|       ps_sql_() | ||||
|   {} | ||||
|   ObPsSqlKey(uint64_t db_id, | ||||
|              const common::ObString &ps_sql) | ||||
|     : db_id_(db_id), | ||||
|     : flag_(0), | ||||
|       db_id_(db_id), | ||||
|       inc_id_(OB_INVALID_ID), | ||||
|       ps_sql_(ps_sql) | ||||
|   {} | ||||
|   ObPsSqlKey(uint64_t db_id, | ||||
|   ObPsSqlKey(uint32_t flag, | ||||
|              uint64_t db_id, | ||||
|              uint64_t inc_id, | ||||
|              const common::ObString &ps_sql) | ||||
|     : db_id_(db_id), | ||||
|     : flag_(flag), | ||||
|       db_id_(db_id), | ||||
|       inc_id_(inc_id), | ||||
|       ps_sql_(ps_sql) | ||||
|   {} | ||||
| @ -52,15 +56,40 @@ public: | ||||
|   int hash(uint64_t &hash_val) const { hash_val = hash(); return OB_SUCCESS; } | ||||
|   ObPsSqlKey &operator=(const ObPsSqlKey &other); | ||||
|   bool operator==(const ObPsSqlKey &other) const; | ||||
|   void set_is_client_return_rowid() | ||||
|   { | ||||
|     is_client_return_hidden_rowid_ = true; | ||||
|   } | ||||
|   bool get_is_client_return_rowid() | ||||
|   { | ||||
|     return is_client_return_hidden_rowid_; | ||||
|   } | ||||
|   void set_flag(uint32_t flag) | ||||
|   { | ||||
|     flag_ = flag; | ||||
|   } | ||||
|   uint32_t get_flag() const | ||||
|   { | ||||
|     return flag_; | ||||
|   } | ||||
|   void reset() | ||||
|   { | ||||
|     flag_ = 0; | ||||
|     db_id_ = OB_INVALID_ID; | ||||
|     inc_id_ = OB_INVALID_ID; | ||||
|     ps_sql_.reset(); | ||||
|   } | ||||
|   TO_STRING_KV(K_(db_id), K_(inc_id), K_(ps_sql)); | ||||
|   TO_STRING_KV(K_(flag), K_(db_id), K_(inc_id), K_(ps_sql)); | ||||
|  | ||||
| public: | ||||
|   union | ||||
|   { | ||||
|     uint32_t flag_; | ||||
|     struct { | ||||
|       uint32_t is_client_return_hidden_rowid_ : 1; | ||||
|       uint32_t reserved_ : 31; | ||||
|     }; | ||||
|   }; | ||||
|   uint64_t db_id_; | ||||
|   // MySQL allows session-level temporary tables with the same name to have different schema definitions. | ||||
|   // In order to distinguish this scenario, an incremental id is used to generate different prepared | ||||
|  | ||||
| @ -233,17 +233,16 @@ int ObPsCache::get_stmt_info_guard(const ObPsStmtId ps_stmt_id, | ||||
| //2.set stmt_id_map_返回OB_HASH_EXIST时,尝试从stmt_id_map_中获取stmt_item | ||||
| //  1)获取成功,返回stmt_item | ||||
| //  2) 报OB_HASH_NOT_EXIST, 则递归调get_or_add_stmt_item,尝试重新创建 | ||||
| int ObPsCache::get_or_add_stmt_item(uint64_t db_id, | ||||
|                                     const ObString &ps_sql, | ||||
| int ObPsCache::get_or_add_stmt_item(const ObPsSqlKey &ps_key, | ||||
|                                     const bool is_contain_tmp_tbl, | ||||
|                                     ObPsStmtItem *&ps_item_value) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   ObPsStmtId new_stmt_id = gen_new_ps_stmt_id(); | ||||
|   ObPsStmtItem tmp_item_value(new_stmt_id); | ||||
|   tmp_item_value.assign_sql_key(ObPsSqlKey(db_id, | ||||
|                                            is_contain_tmp_tbl ? new_stmt_id : OB_INVALID_ID, | ||||
|                                            ps_sql)); | ||||
|   ObPsSqlKey tmp_ps_key = ps_key; | ||||
|   tmp_ps_key.inc_id_ = is_contain_tmp_tbl ? new_stmt_id : OB_INVALID_ID; | ||||
|   tmp_item_value.assign_sql_key(tmp_ps_key); | ||||
|   //will deep copy | ||||
|   ObPsStmtItem *new_item_value = NULL; | ||||
|   //由于stmt_id_map_中的value是ObPsStmtItem的指针,因此这里需要copy整个内存 | ||||
| @ -261,26 +260,26 @@ int ObPsCache::get_or_add_stmt_item(uint64_t db_id, | ||||
|     } | ||||
|   } | ||||
|   if (OB_SUCC(ret)) { | ||||
|     const ObPsSqlKey ps_sql_key = new_item_value->get_sql_key(); | ||||
|     const ObPsSqlKey inner_ps_key = new_item_value->get_sql_key(); | ||||
|     new_item_value->check_erase_inc_ref_count(); //inc ref count for ps cache, ignore ret; | ||||
|     ret = stmt_id_map_.set_refactored(ps_sql_key, new_item_value); | ||||
|     ret = stmt_id_map_.set_refactored(inner_ps_key, new_item_value); | ||||
|     if (OB_SUCC(ret)) { | ||||
|       //do nothing | ||||
|       LOG_INFO("add stmt item", K(ps_sql_key), K(*new_item_value)); | ||||
|       LOG_INFO("add stmt item", K(inner_ps_key), K(*new_item_value)); | ||||
|       ps_item_value = new_item_value; | ||||
|     } else if (OB_HASH_EXIST == ret) { | ||||
|       ret = OB_SUCCESS; | ||||
|       //may be other session has set | ||||
|       //inc ref count | ||||
|       ObPsStmtItem *tmp_item_value = NULL; | ||||
|       if (OB_FAIL(ref_stmt_item(ps_sql_key, tmp_item_value))) { | ||||
|       if (OB_FAIL(inner_ref_stmt_item(inner_ps_key, tmp_item_value))) { | ||||
|         LOG_WARN("get stmt item failed", K(ret)); | ||||
|         if (OB_HASH_NOT_EXIST == ret) {//stmt item被删除,需要重新创建 | ||||
|           if (OB_FAIL(get_or_add_stmt_item(db_id, ps_sql, is_contain_tmp_tbl, ps_item_value))) { | ||||
|           if (OB_FAIL(get_or_add_stmt_item(ps_key, is_contain_tmp_tbl, ps_item_value))) { | ||||
|             LOG_WARN("fail to get or add stmt item", K(ret)); | ||||
|           } | ||||
|         } else { | ||||
|           LOG_WARN("unexpected error", K(ret), K(ps_sql_key)); | ||||
|           LOG_WARN("unexpected error", K(ret), K(inner_ps_key)); | ||||
|         } | ||||
|       } else { | ||||
|         if (OB_ISNULL(tmp_item_value)) { | ||||
| @ -322,7 +321,7 @@ int ObPsCache::get_or_add_stmt_item(uint64_t db_id, | ||||
| //   1) OB_SUCCESS: 成功获取ps_stmt_item | ||||
| //   2) OB_HASH_NOT_EXIST: a.stmt_id_map_中本身就不存在当前key b.开始key对应的引用计数为0,重试若干次后变为该错误码 | ||||
| //   3) OB_EGAIN: 尝试了MAX_RETRY_CNT,ps_stmt_item的ref_count仍旧为0 | ||||
| int ObPsCache::ref_stmt_item(const ObPsSqlKey &ps_sql_key, | ||||
| int ObPsCache::inner_ref_stmt_item(const ObPsSqlKey &ps_sql_key, | ||||
|                                    ObPsStmtItem *&ps_stmt_item) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
| @ -377,24 +376,19 @@ int ObPsCache::deref_stmt_item(const ObPsSqlKey &ps_sql_key) | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObPsCache::ref_stmt_item(const uint64_t db_id, | ||||
|                              const ObString &ps_sql, | ||||
|                              ObPsStmtItem *&stmt_item) | ||||
| int ObPsCache::ref_stmt_item(const ObPsSqlKey &ps_sql_key, ObPsStmtItem *&stmt_item) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   stmt_item = NULL; | ||||
|   if (ps_sql.empty()) { | ||||
|   stmt_item = nullptr; | ||||
|   if (ps_sql_key.ps_sql_.empty()) { | ||||
|     ret = OB_INVALID_ARGUMENT; | ||||
|     LOG_WARN("empty sql", K(ret), K(ps_sql)); | ||||
|   } else { | ||||
|     ObPsSqlKey ps_sql_key(db_id, ps_sql); | ||||
|     if (OB_FAIL(ref_stmt_item(ps_sql_key, stmt_item))) { | ||||
|     LOG_WARN("empty sql", K(ret), K(ps_sql_key)); | ||||
|   } else if (OB_FAIL(inner_ref_stmt_item(ps_sql_key, stmt_item))) { | ||||
|     LOG_WARN_IGNORE_PS_NOTFOUND(ret, "ps item value not exist", K(ret), K(ps_sql_key)); | ||||
|   } else if (OB_ISNULL(stmt_item)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("get stmt id failed", K(ret)); | ||||
|   } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -88,15 +88,14 @@ public: | ||||
|   // always make sure stmt_id is inner_stmt_id!!! | ||||
|   int64_t get_tenant_id() const { return tenant_id_; } | ||||
|   int get_stmt_info_guard(const ObPsStmtId ps_stmt_id, ObPsStmtInfoGuard &guard); | ||||
|   int ref_stmt_item(const uint64_t db_id, const common::ObString &ps_sql, ObPsStmtItem *&stmt_item); | ||||
|   int ref_stmt_item(const ObPsSqlKey &ps_sql_key, ObPsStmtItem *&stmt_item); | ||||
|   int ref_stmt_info(const ObPsStmtId stmt_id, ObPsStmtInfo *&ps_stmt_info); | ||||
|   int deref_stmt_info(const ObPsStmtId stmt_id); | ||||
|   int deref_all_ps_stmt(const ObIArray<ObPsStmtId> &ps_stmt_ids); | ||||
|   int ref_stmt_item(const ObPsSqlKey &ps_sql_key, ObPsStmtItem *&ps_stmt_item); | ||||
|   int inner_ref_stmt_item(const ObPsSqlKey &ps_sql_key, ObPsStmtItem *&ps_stmt_item); | ||||
|   int deref_stmt_item(const ObPsSqlKey &ps_sql_key); | ||||
|   int deref_ps_stmt(const ObPsStmtId stmt_id, bool erase_item = false); | ||||
|   int get_or_add_stmt_item(const uint64_t db_id, | ||||
|                            const common::ObString &ps_sql, | ||||
|   int get_or_add_stmt_item(const ObPsSqlKey &ps_key, | ||||
|                            const bool is_contain_tmp_tbl, | ||||
|                            ObPsStmtItem *&ps_item_value); | ||||
|   int get_or_add_stmt_info(const PsCacheInfoCtx &info_ctx, | ||||
| @ -128,6 +127,7 @@ public: | ||||
|                            ObPsStmtInfo &stmt_info, | ||||
|                            bool &is_expired); | ||||
|   int erase_stmt_item(ObPsStmtId stmt_id, const ObPsSqlKey &ps_key); | ||||
|  | ||||
| private: | ||||
|   int inner_cache_evict(bool is_evict_all); | ||||
|   int fill_ps_stmt_info(const ObResultSet &result, | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 obdev
					obdev