提交 139d23a6 编写于 作者: H hy-guo 提交者: ob-robot

fix mv rewrite plan cache bug

上级 cf3bebc6
......@@ -55,6 +55,7 @@ int PCVSchemaObj::init(const ObTableSchema *schema)
schema_type_ = TABLE_SCHEMA;
table_type_ = schema->get_table_type();
is_tmp_table_ = schema->is_tmp_table();
is_mv_container_table_ = schema->mv_container_table();
// copy table name
char *buf = nullptr;
const ObString &tname = schema->get_table_name_str();
......@@ -1522,7 +1523,6 @@ int ObPlanCacheValue::check_value_version(bool need_check_schema,
if (outline_version != outline_state_.outline_version_) {
is_old_version = true;
} else if (OB_FAIL(check_dep_schema_version(schema_array,
stored_schema_objs_,
is_old_version))) {
LOG_WARN("failed to check schema obj versions", K(ret));
} else {
......@@ -1534,19 +1534,21 @@ int ObPlanCacheValue::check_value_version(bool need_check_schema,
//检查table schema version是否过期, get plan时使用
int ObPlanCacheValue::check_dep_schema_version(const ObIArray<PCVSchemaObj> &schema_array,
const ObIArray<PCVSchemaObj *> &pcv_schema_objs,
bool &is_old_version)
{
int ret = OB_SUCCESS;
is_old_version = false;
int64_t table_count = pcv_schema_objs.count();
int64_t table_count = schema_array.count();
ObSEArray<PCVSchemaObj*, 4> check_stored_schema;
if (schema_array.count() != pcv_schema_objs.count()) {
if (OB_FAIL(remove_mv_schema(schema_array, check_stored_schema))) {
LOG_WARN("failed to remove mv schema", K(ret));
} else if (schema_array.count() != check_stored_schema.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table count do not match", K(ret), K(schema_array.count()), K(pcv_schema_objs.count()));
LOG_WARN("table count do not match", K(ret), K(schema_array.count()), K(check_stored_schema.count()));
} else {
for (int64_t i = 0; OB_SUCC(ret) && !is_old_version && i < table_count; ++i) {
const PCVSchemaObj *schema_obj1 = pcv_schema_objs.at(i);
const PCVSchemaObj *schema_obj1 = check_stored_schema.at(i);
const PCVSchemaObj &schema_obj2 = schema_array.at(i);
if (nullptr == schema_obj1) {
ret = OB_ERR_UNEXPECTED;
......@@ -2062,6 +2064,41 @@ int ObPlanCacheValue::get_all_dep_schema(ObPlanCacheCtx &pc_ctx,
return ret;
}
// 针对
// 物化视图改写会使得同一条 SQL 的不同计划依赖的表不同,导致 plan cache 进入不同的 pcv set
// 在检查 pcv set 的时候跳过物化视图相关的表,使得改写与不改写的 SQL 进入同一个 pcv set
int ObPlanCacheValue::remove_mv_schema(const common::ObIArray<PCVSchemaObj> &schema_array,
common::ObIArray<PCVSchemaObj*> &check_stored_schema)
{
int ret = OB_SUCCESS;
bool need_remove = true;
int64_t j = 0;
for (int64_t i = 0; OB_SUCC(ret) && i < stored_schema_objs_.count(); ++i) {
if (OB_ISNULL(stored_schema_objs_.at(i))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid null table schema", K(ret), K(i), K(stored_schema_objs_.at(i)));
} else if (MATERIALIZED_VIEW == stored_schema_objs_.at(i)->table_type_
|| MATERIALIZED_VIEW_LOG == stored_schema_objs_.at(i)->table_type_
|| stored_schema_objs_.at(i)->is_mv_container_table_) {
if (j < schema_array.count()
&& stored_schema_objs_.at(i)->schema_id_ == schema_array.at(j).schema_id_) {
if (OB_FAIL(check_stored_schema.push_back(stored_schema_objs_.at(i)))) {
LOG_WARN("failed to push back schema", K(ret));
} else {
++j;
}
} else {
// do nothing, 仅存在于 pcv set 中的物化视图是改写出来的,抛弃
}
} else if (OB_FAIL(check_stored_schema.push_back(stored_schema_objs_.at(i)))) {
LOG_WARN("failed to push back schema", K(ret));
} else {
++j;
}
}
return ret;
}
// 对于计划所依赖的schema进行比较,注意这里不比较table schema的version信息
// table schema的version信息用于淘汰pcv set,在check_value_version时进行比较
int ObPlanCacheValue::match_dep_schema(const ObPlanCacheCtx &pc_ctx,
......@@ -2071,20 +2108,23 @@ int ObPlanCacheValue::match_dep_schema(const ObPlanCacheCtx &pc_ctx,
int ret = OB_SUCCESS;
is_same = true;
ObSQLSessionInfo *session_info = pc_ctx.sql_ctx_.session_info_;
common::ObSEArray<PCVSchemaObj*, 4> check_stored_schema;
if (OB_ISNULL(session_info)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(session_info));
} else if (schema_array.count() != stored_schema_objs_.count()) {
} else if (OB_FAIL(remove_mv_schema(schema_array, check_stored_schema))) {
LOG_WARN("failed to remove mv schema", K(ret));
} else if (schema_array.count() != check_stored_schema.count()) {
// schema objs count不匹配,可能是以下情况:
// select * from all_sequences; // 系统视图,系统视图的dependency_table有多个
// select * from all_sequences; // 普通表
is_same = false;
} else {
for (int64_t i = 0; OB_SUCC(ret) && is_same && i < schema_array.count(); i++) {
if (OB_ISNULL(stored_schema_objs_.at(i))) {
if (OB_ISNULL(check_stored_schema.at(i))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid null table schema",
K(ret), K(i), K(schema_array.at(i)), K(stored_schema_objs_.at(i)));
K(ret), K(i), K(schema_array.at(i)), K(check_stored_schema.at(i)));
} else if (TMP_TABLE == schema_array.at(i).table_type_
&& schema_array.at(i).is_tmp_table_) { // check for mysql tmp table
// 如果包含临时表
......@@ -2100,13 +2140,13 @@ int ObPlanCacheValue::match_dep_schema(const ObPlanCacheCtx &pc_ctx,
is_same = ((session_info->get_sessid_for_table() == sessid_) &&
(session_info->get_sess_create_time() == sess_create_time_));
} else if (lib::is_oracle_mode()
&& TABLE_SCHEMA == stored_schema_objs_.at(i)->schema_type_
&& !stored_schema_objs_.at(i)->match_compare(schema_array.at(i))) {
&& TABLE_SCHEMA == check_stored_schema.at(i)->schema_type_
&& !check_stored_schema.at(i)->match_compare(schema_array.at(i))) {
// 检查oracle模式下普通表是否与系统表同名
is_same = false;
} else if (lib::is_oracle_mode()
&& SYNONYM_SCHEMA == stored_schema_objs_.at(i)->schema_type_) {
is_same = (stored_schema_objs_.at(i)->database_id_ == schema_array.at(i).database_id_);
&& SYNONYM_SCHEMA == check_stored_schema.at(i)->schema_type_) {
is_same = (check_stored_schema.at(i)->database_id_ == schema_array.at(i).database_id_);
} else {
// do nothing
}
......
......@@ -64,6 +64,7 @@ struct PCVSchemaObj
bool is_tmp_table_;
bool is_explicit_db_name_;
common::ObIAllocator *inner_alloc_;
bool is_mv_container_table_;
PCVSchemaObj():
tenant_id_(common::OB_INVALID_ID),
......@@ -74,7 +75,8 @@ struct PCVSchemaObj
table_type_(share::schema::MAX_TABLE_TYPE),
is_tmp_table_(false),
is_explicit_db_name_(false),
inner_alloc_(nullptr) {}
inner_alloc_(nullptr),
is_mv_container_table_(false) {}
explicit PCVSchemaObj(ObIAllocator *alloc):
tenant_id_(common::OB_INVALID_ID),
......@@ -85,7 +87,8 @@ struct PCVSchemaObj
table_type_(share::schema::MAX_TABLE_TYPE),
is_tmp_table_(false),
is_explicit_db_name_(false),
inner_alloc_(alloc) {}
inner_alloc_(alloc),
is_mv_container_table_(false) {}
int init(const share::schema::ObTableSchema *schema);
int init_with_synonym(const ObSimpleSynonymSchema *schema);
......@@ -134,7 +137,8 @@ struct PCVSchemaObj
K_(table_type),
K_(table_name),
K_(is_tmp_table),
K_(is_explicit_db_name));
K_(is_explicit_db_name),
K_(is_mv_container_table));
};
class ObPlanCacheValue :public common::ObDLinkBase<ObPlanCacheValue>
......@@ -333,9 +337,11 @@ private:
share::schema::ObSchemaGetterGuard *schema_guard);
int check_dep_schema_version(const common::ObIArray<PCVSchemaObj> &schema_array,
const common::ObIArray<PCVSchemaObj *> &pcv_schema_objs,
bool &is_old_version);
int remove_mv_schema(const common::ObIArray<PCVSchemaObj> &schema_array,
common::ObIArray<PCVSchemaObj*> &stored_schema_objs);
int match_dep_schema(const ObPlanCacheCtx &pc_ctx,
const common::ObIArray<PCVSchemaObj> &schema_array,
bool &is_same);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册