diff --git a/src/pl/sys_package/ob_dbms_stats.cpp b/src/pl/sys_package/ob_dbms_stats.cpp index 7127dbb5e3..161efa6db9 100644 --- a/src/pl/sys_package/ob_dbms_stats.cpp +++ b/src/pl/sys_package/ob_dbms_stats.cpp @@ -319,10 +319,9 @@ int ObDbmsStats::gather_table_index_stats(ObExecContext &ctx, } if (OB_SUCC(ret)) { index_param.is_index_stat_ = true; - index_param.need_global_ = data_param.need_global_; - index_param.need_approx_global_ = data_param.need_approx_global_; - index_param.need_part_ = data_param.need_part_; - index_param.need_subpart_ = data_param.need_subpart_; + index_param.global_stat_param_ = data_param.global_stat_param_; + index_param.part_stat_param_.assign_without_part_type(data_param.part_stat_param_); + index_param.subpart_stat_param_.assign_without_part_type(data_param.subpart_stat_param_); index_param.data_table_name_ = data_param.tab_name_; if (index_param.force_ && OB_FAIL(ObDbmsStatsLockUnlock::fill_stat_locked(ctx, index_param))) { @@ -392,16 +391,15 @@ int ObDbmsStats::fast_gather_index_stats(ObExecContext &ctx, //glboal index can't reuse the partition data in fast gather index } else if (index_schema->is_global_index_table()) { index_param.is_global_index_ = true; - index_param.need_global_ = data_param.need_global_ || data_param.need_global_; - index_param.need_approx_global_ = false; - index_param.need_part_ = false; - index_param.need_subpart_ = false; + index_param.global_stat_param_ = data_param.global_stat_param_; + index_param.global_stat_param_.gather_approx_ = false; + index_param.part_stat_param_.reset_gather_stat(); + index_param.subpart_stat_param_.reset_gather_stat(); //local index the partition is same as data table } else { - index_param.need_global_ = data_param.need_global_; - index_param.need_approx_global_ = data_param.need_approx_global_; - index_param.need_part_ = data_param.need_part_; - index_param.need_subpart_ = data_param.need_subpart_; + index_param.global_stat_param_ = data_param.global_stat_param_; + index_param.part_stat_param_ = data_param.part_stat_param_; + index_param.subpart_stat_param_ = data_param.subpart_stat_param_; } if (OB_SUCC(ret) && is_fast_gather) { if (OB_FAIL(ObIndexStatsEstimator::fast_gather_index_stats(ctx, data_param, @@ -662,25 +660,7 @@ int ObDbmsStats::set_index_stats(ObExecContext &ctx, ParamStore ¶ms, ObObj & } else if (OB_FAIL(num_nummicroblks.extract_valid_int64_with_trunc(set_index_param.nummicroblks_))) { LOG_WARN("extract_valid_int64_with_trunc failed", K(ret), K(num_nummicroblks)); } else { - if (index_stat_param.part_name_.empty()) { - index_stat_param.need_global_ = true; - index_stat_param.need_part_ = false; - index_stat_param.need_subpart_ = false; - } else if (!index_stat_param.is_subpart_name_) { - index_stat_param.need_global_ = false; - index_stat_param.need_part_ = true; - index_stat_param.need_subpart_ = false; - } else { - index_stat_param.need_global_ = false; - index_stat_param.need_part_ = false; - index_stat_param.need_subpart_ = true; - } - if (!index_stat_param.need_part_) { - index_stat_param.part_infos_.reset(); - } - if (!index_stat_param.need_subpart_) { - index_stat_param.subpart_infos_.reset(); - } + decide_modified_part(index_stat_param, false/* cascade_part */); } if (OB_FAIL(ret)) { } else if (OB_FAIL(set_index_param.table_param_.assign(index_stat_param))) { @@ -751,26 +731,9 @@ int ObDbmsStats::delete_table_stats(ObExecContext &ctx, ParamStore ¶ms, ObOb stat_param.column_params_.reset(); } if (OB_SUCC(ret)) { - if (stat_param.part_name_.empty()) { - stat_param.need_global_ = true; - stat_param.need_part_ = cascade_parts; - stat_param.need_subpart_ = cascade_parts; - } else if (!stat_param.is_subpart_name_) { - stat_param.need_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = cascade_parts; + decide_modified_part(stat_param, cascade_parts); + if (!stat_param.part_name_.empty()) { cascade_indexes = false; - } else { - stat_param.need_global_ = false; - stat_param.need_part_ = false; - stat_param.need_subpart_ = true; - cascade_indexes = false; - } - if (!stat_param.need_part_) { - stat_param.part_infos_.reset(); - } - if (!stat_param.need_subpart_) { - stat_param.subpart_infos_.reset(); } } if (OB_SUCC(ret)) { @@ -855,28 +818,7 @@ int ObDbmsStats::delete_column_stats(ObExecContext &ctx, ParamStore ¶ms, ObO } if (OB_SUCC(ret)) { - if (stat_param.part_name_.empty()) { - stat_param.need_global_ = true; - stat_param.need_part_ = cascade_parts; - stat_param.need_subpart_ = cascade_parts; - } else if (!stat_param.is_subpart_name_) { - stat_param.need_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = cascade_parts; - } else { - stat_param.need_global_ = false; - stat_param.need_part_ = false; - stat_param.need_subpart_ = true; - } - if (!stat_param.need_part_) { - stat_param.part_infos_.reset(); - } - if (!stat_param.need_subpart_) { - stat_param.subpart_infos_.reset(); - } - } - - if (OB_SUCC(ret)) { + decide_modified_part(stat_param, cascade_parts); if (stat_param.force_ && OB_FAIL(ObDbmsStatsLockUnlock::fill_stat_locked(ctx, stat_param))) { LOG_WARN("failed fill stat locked", K(ret)); @@ -933,9 +875,9 @@ int ObDbmsStats::delete_schema_stats(ObExecContext &ctx, ParamStore ¶ms, ObO } else if (!params.at(5).is_null() && OB_FAIL(params.at(5).get_bool(stat_param.force_))) { LOG_WARN("failed to get no invalidate", K(ret)); } else { - stat_param.need_global_ = true; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; + stat_param.global_stat_param_.need_modify_ = true; + stat_param.part_stat_param_.need_modify_ = true; + stat_param.subpart_stat_param_.need_modify_ = true; if (stat_param.force_ && OB_FAIL(ObDbmsStatsLockUnlock::fill_stat_locked(ctx, stat_param))) { LOG_WARN("failed to fill stat locked", K(ret)); @@ -1016,25 +958,7 @@ int ObDbmsStats::delete_index_stats(ObExecContext &ctx, ParamStore ¶ms, ObOb } else if (!params.at(9).is_null() && OB_FAIL(params.at(9).get_bool(index_stat_param.force_))) { LOG_WARN("failed to get force", K(ret)); } else { - if (index_stat_param.part_name_.empty()) { - index_stat_param.need_global_ = true; - index_stat_param.need_part_ = cascade_parts; - index_stat_param.need_subpart_ = cascade_parts; - } else if (!index_stat_param.is_subpart_name_) { - index_stat_param.need_global_ = false; - index_stat_param.need_part_ = true; - index_stat_param.need_subpart_ = cascade_parts; - } else { - index_stat_param.need_global_ = false; - index_stat_param.need_part_ = false; - index_stat_param.need_subpart_ = true; - } - if (!index_stat_param.need_part_) { - index_stat_param.part_infos_.reset(); - } - if (!index_stat_param.need_subpart_) { - index_stat_param.subpart_infos_.reset(); - } + decide_modified_part(index_stat_param, cascade_parts); } if (OB_SUCC(ret)) { @@ -1602,26 +1526,9 @@ int ObDbmsStats::import_table_stats(ObExecContext &ctx, ParamStore ¶ms, ObOb cascade_index = stat_param.cascade_; stat_param.stat_own_ = stat_table_param.db_name_; stat_param.stat_tab_ = stat_table_param.tab_name_; - if (stat_param.part_name_.empty()) { - stat_param.need_global_ = true; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; - } else if (!stat_param.is_subpart_name_) { - stat_param.need_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; + decide_modified_part(stat_param, true /* cascade_part */); + if (!stat_param.part_name_.empty()) { cascade_index = false; - } else { - stat_param.need_global_ = false; - stat_param.need_part_ = false; - stat_param.need_subpart_ = true; - cascade_index = false; - } - if (!stat_param.need_part_) { - stat_param.part_infos_.reset(); - } - if (!stat_param.need_subpart_) { - stat_param.subpart_infos_.reset(); } } if (OB_FAIL(ret)) { @@ -1705,25 +1612,7 @@ int ObDbmsStats::import_column_stats(sql::ObExecContext &ctx, } else { stat_param.stat_own_ = stat_table_param.db_name_; stat_param.stat_tab_ = stat_table_param.tab_name_; - if (stat_param.part_name_.empty()) { - stat_param.need_global_ = true; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; - } else if (!stat_param.is_subpart_name_) { - stat_param.need_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; - } else { - stat_param.need_global_ = false; - stat_param.need_part_ = false; - stat_param.need_subpart_ = true; - } - if (!stat_param.need_part_) { - stat_param.part_infos_.reset(); - } - if (!stat_param.need_subpart_) { - stat_param.subpart_infos_.reset(); - } + decide_modified_part(stat_param, true /* cascade_part */); } if (OB_FAIL(ret)) { } else if (!stat_param.force_ && @@ -1793,9 +1682,9 @@ int ObDbmsStats::import_schema_stats(ObExecContext &ctx, ParamStore ¶ms, ObO stat_param.stat_tab_ = stat_table_param.tab_name_; stat_param.stat_id_ = stat_table_param.stat_id_; stat_param.cascade_ = true; - stat_param.need_global_ = true; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; + stat_param.global_stat_param_.need_modify_ = true; + stat_param.part_stat_param_.need_modify_ = true; + stat_param.subpart_stat_param_.need_modify_ = true; stat_param.allocator_ = &tmp_alloc;//use the temp allocator to free memory after stat import if (OB_FAIL(parse_table_part_info(ctx, stat_table, stat_param))) { LOG_WARN("failed to parse table part info", K(ret)); @@ -1897,25 +1786,7 @@ int ObDbmsStats::import_index_stats(ObExecContext &ctx, ParamStore ¶ms, ObOb } else { index_stat_param.stat_own_ = stat_table_param.db_name_; index_stat_param.stat_tab_ = stat_table_param.tab_name_; - if (index_stat_param.part_name_.empty()) { - index_stat_param.need_global_ = true; - index_stat_param.need_part_ = true; - index_stat_param.need_subpart_ = true; - } else if (!index_stat_param.is_subpart_name_) { - index_stat_param.need_global_ = false; - index_stat_param.need_part_ = true; - index_stat_param.need_subpart_ = true; - } else { - index_stat_param.need_global_ = false; - index_stat_param.need_part_ = false; - index_stat_param.need_subpart_ = true; - } - if (!index_stat_param.need_part_) { - index_stat_param.part_infos_.reset(); - } - if (!index_stat_param.need_subpart_) { - index_stat_param.subpart_infos_.reset(); - } + decide_modified_part(index_stat_param, true /* cascade_part */); } if (OB_FAIL(ret)) { } else if (index_stat_param.force_ && @@ -2012,10 +1883,9 @@ int ObDbmsStats::lock_table_stats(sql::ObExecContext &ctx, } else if (OB_FAIL(parse_stat_type(stat_type_str, stat_param.stattype_))) { LOG_WARN("failed to parse stat type", K(ret), K(stat_type_str)); } else { - stat_param.need_global_ = true; - stat_param.need_approx_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; + stat_param.global_stat_param_.need_modify_ = true; + stat_param.part_stat_param_.need_modify_ = true; + stat_param.subpart_stat_param_.need_modify_ = true; if (OB_FAIL(ObDbmsStatsLockUnlock::set_table_stats_lock(ctx, stat_param, true))) { LOG_WARN("failed to lock table stats", K(ret)); } else if (OB_FAIL(lock_or_unlock_index_stats(ctx, stat_param, true))) { @@ -2060,10 +1930,9 @@ int ObDbmsStats::lock_partition_stats(sql::ObExecContext &ctx, } else if (!stat_param.part_name_.empty() && stat_param.is_subpart_name_) { /*do nothing*/ } else { - stat_param.need_global_ = false; - stat_param.need_approx_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = false; + stat_param.global_stat_param_.need_modify_ = false; + stat_param.part_stat_param_.need_modify_ = true; + stat_param.subpart_stat_param_.need_modify_ = false; if (OB_FAIL(ObDbmsStatsLockUnlock::set_table_stats_lock(ctx, stat_param, true))) { LOG_WARN("failed to lock table stats", K(ret)); } else {/*do nothing */} @@ -2112,10 +1981,9 @@ int ObDbmsStats::lock_schema_stats(sql::ObExecContext &ctx, if (OB_FAIL(parse_table_part_info(ctx, stat_table, stat_param))) { LOG_WARN("failed to parse table part info", K(ret)); } else { - stat_param.need_global_ = true; - stat_param.need_approx_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; + stat_param.global_stat_param_.need_modify_ = true; + stat_param.part_stat_param_.need_modify_ = true; + stat_param.subpart_stat_param_.need_modify_ = true; stat_param.allocator_ = &tmp_alloc;//use the temp allocator free memory after stat lock if (OB_FAIL(ObDbmsStatsLockUnlock::set_table_stats_lock(ctx, stat_param, true))) { LOG_WARN("failed to lock table stats", K(ret)); @@ -2151,10 +2019,9 @@ int ObDbmsStats::lock_or_unlock_index_stats(sql::ObExecContext &ctx, } else if (OB_FAIL(parse_table_part_info(ctx, stat_table, index_param))) { LOG_WARN("failed to parse table part info", K(ret)); } else { - index_param.need_global_ = true; - index_param.need_approx_global_ = false; - index_param.need_part_ = true; - index_param.need_subpart_ = true; + index_param.global_stat_param_.need_modify_ = true; + index_param.part_stat_param_.need_modify_ = true; + index_param.subpart_stat_param_.need_modify_ = true; index_param.is_index_stat_ = true; if (OB_FAIL(ObDbmsStatsLockUnlock::set_table_stats_lock(ctx, index_param, is_lock_stats))) { LOG_WARN("failed to lock table stats", K(ret)); @@ -2205,10 +2072,9 @@ int ObDbmsStats::unlock_table_stats(sql::ObExecContext &ctx, } else if (OB_FAIL(parse_stat_type(stat_type_str, stat_param.stattype_))) { LOG_WARN("failed to parse stat type", K(ret), K(stat_type_str)); } else { - stat_param.need_global_ = true; - stat_param.need_approx_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; + stat_param.global_stat_param_.need_modify_ = true; + stat_param.part_stat_param_.need_modify_ = true; + stat_param.subpart_stat_param_.need_modify_ = true; if (OB_FAIL(ObDbmsStatsLockUnlock::set_table_stats_lock(ctx, stat_param, false))) { LOG_WARN("failed to lock table stats", K(ret)); } else if (OB_FAIL(lock_or_unlock_index_stats(ctx, stat_param, false))) { @@ -2253,10 +2119,9 @@ int ObDbmsStats::unlock_partition_stats(sql::ObExecContext &ctx, } else if (!stat_param.part_name_.empty() && stat_param.is_subpart_name_) { /*do nothing*/ } else { - stat_param.need_global_ = false; - stat_param.need_approx_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = false; + stat_param.global_stat_param_.need_modify_ = false; + stat_param.part_stat_param_.need_modify_ = true; + stat_param.subpart_stat_param_.need_modify_ = false; if (OB_FAIL(ObDbmsStatsLockUnlock::set_table_stats_lock(ctx, stat_param, false))) { LOG_WARN("failed to lock table stats", K(ret)); } else {/*do nothing */} @@ -2305,10 +2170,9 @@ int ObDbmsStats::unlock_schema_stats(sql::ObExecContext &ctx, if (OB_FAIL(parse_table_part_info(ctx, stat_table, stat_param))) { LOG_WARN("failed to parse table part info", K(ret)); } else { - stat_param.need_global_ = true; - stat_param.need_approx_global_ = false; - stat_param.need_part_ = true; - stat_param.need_subpart_ = true; + stat_param.global_stat_param_.need_modify_ = true; + stat_param.part_stat_param_.need_modify_ = true; + stat_param.subpart_stat_param_.need_modify_ = true; stat_param.allocator_ = &tmp_alloc;//use the temp allocator to free memory after stat unlock if (OB_FAIL(ObDbmsStatsLockUnlock::set_table_stats_lock(ctx, stat_param, false))) { LOG_WARN("failed to lock table stats", K(ret)); @@ -3057,7 +2921,7 @@ int ObDbmsStats::update_stat_cache(const uint64_t rpc_tenant_id, LOG_WARN("failed to push back partition id", K(ret)); } } - if (OB_SUCC(ret) && param.need_global_) { + if (OB_SUCC(ret) && param.global_stat_param_.need_modify_) { int64_t part_id = param.global_part_id_; if (OB_FAIL(stat_arg.partition_ids_.push_back(part_id))) { LOG_WARN("failed to push back partition ids", K(ret)); @@ -3131,17 +2995,20 @@ int ObDbmsStats::parse_table_part_info(ObExecContext &ctx, } else if (OB_FAIL(param.all_part_infos_.assign(param.part_infos_)) || OB_FAIL(param.all_subpart_infos_.assign(param.subpart_infos_))) { LOG_WARN("failed to assign", K(ret)); - } else if (!part_name.is_null()) { - param.table_id_ = table_schema->get_table_id(); - param.part_level_ = table_schema->get_part_level(); - param.total_part_cnt_ = table_schema->get_all_part_num(); - if (OB_FAIL(parse_partition_name(ctx, table_schema, part_name, param))) { - LOG_WARN("failed to parse partition name", K(ret)); - } + } else if (!part_name.is_null() && OB_FAIL(parse_partition_name(ctx, table_schema, part_name, param))) { + LOG_WARN("failed to parse partition name", K(ret)); } else { param.table_id_ = table_schema->get_table_id(); param.part_level_ = table_schema->get_part_level(); param.total_part_cnt_ = table_schema->get_all_part_num(); + // we can't get part/subpart type anyway, because default value of part_func_type is + // PARTITION_FUNC_TYPE_HASH even table is not partitioned. + if (share::schema::ObPartitionLevel::PARTITION_LEVEL_ONE == param.part_level_) { + param.part_stat_param_.part_type_ = table_schema->get_part_option().get_part_func_type(); + } else if (share::schema::ObPartitionLevel::PARTITION_LEVEL_TWO == param.part_level_) { + param.part_stat_param_.part_type_ = table_schema->get_part_option().get_part_func_type(); + param.subpart_stat_param_.part_type_ = table_schema->get_sub_part_option().get_part_func_type(); + } } if (OB_SUCC(ret)) { if (OB_FAIL(init_column_stat_params(*param.allocator_, @@ -3149,12 +3016,6 @@ int ObDbmsStats::parse_table_part_info(ObExecContext &ctx, *table_schema, param.column_params_))) { LOG_WARN("failed to init column stat params", K(ret)); - } else { - //set default granularity: gather subpartition、partition and global stats - param.need_global_ = true; - param.need_approx_global_ = false; - param.need_part_ = true; - param.need_subpart_ = true; } } return ret; @@ -3192,11 +3053,6 @@ int ObDbmsStats::parse_table_part_info(ObExecContext &ctx, param.table_id_ = table_schema->get_table_id(); param.part_level_ = table_schema->get_part_level(); param.total_part_cnt_ = table_schema->get_all_part_num(); - //set default granularity: gather subpartition、partition and global stats - param.need_global_ = true; - param.need_approx_global_ = false; - param.need_part_ = true; - param.need_subpart_ = true; } return ret; } @@ -3269,11 +3125,6 @@ int ObDbmsStats::parse_index_part_info(ObExecContext &ctx, param.column_params_))) { LOG_WARN("failed to init column stat params", K(ret)); } else { - //set default granularity: gather subpartition、partition and global stats - param.need_global_ = true; - param.need_approx_global_ = false; - param.need_part_ = true; - param.need_subpart_ = true; LOG_TRACE("Succed to parse index part info", K(param)); } } @@ -3451,25 +3302,7 @@ int ObDbmsStats::parse_set_table_info(ObExecContext &ctx, } else { param.table_id_ = table_schema->get_table_id(); param.part_level_ = table_schema->get_part_level(); - if (param.part_name_.empty()) { - param.need_global_ = true; - param.need_part_ = false; - param.need_subpart_ = false; - } else if (!param.is_subpart_name_) { - param.need_global_ = false; - param.need_part_ = true; - param.need_subpart_ = false; - } else { - param.need_global_ = false; - param.need_part_ = false; - param.need_subpart_ = true; - } - if (!param.need_part_) { - param.part_infos_.reset(); - } - if (!param.need_subpart_) { - param.subpart_infos_.reset(); - } + decide_modified_part(param, false /* cascade_part */); } return ret; } @@ -3550,25 +3383,7 @@ int ObDbmsStats::parse_set_column_stats(ObExecContext &ctx, } else { param.table_id_ = table_schema->get_table_id(); param.part_level_ = table_schema->get_part_level(); - if (param.part_name_.empty()) { - param.need_global_ = true; - param.need_part_ = false; - param.need_subpart_ = false; - } else if (!param.is_subpart_name_) { - param.need_global_ = false; - param.need_part_ = true; - param.need_subpart_ = false; - } else { - param.need_global_ = false; - param.need_part_ = false; - param.need_subpart_ = true; - } - if (!param.need_part_) { - param.part_infos_.reset(); - } - if (!param.need_subpart_) { - param.subpart_infos_.reset(); - } + decide_modified_part(param, false /* cascade_part */); } } } @@ -4092,12 +3907,11 @@ int ObDbmsStats::parse_granularity_and_method_opt(ObExecContext &ctx, int ret = OB_SUCCESS; //virtual table(not include real agent table) doesn't gather histogram. bool is_vt = is_virtual_table(param.table_id_); - if (OB_FAIL(ObDbmsStatsUtils::parse_granularity(param.granularity_, - param.need_global_, - param.need_approx_global_, - param.need_part_, - param.need_subpart_))) { - LOG_WARN("extract_valid_int64_with_trunc failed", K(ret)); + ObGranularityType granu_type = ObGranularityType::GRANULARITY_INVALID; + if (OB_FAIL(ObDbmsStatsUtils::parse_granularity(param.granularity_, granu_type))) { + LOG_WARN("failed to parse granularity"); + } else if (OB_FAIL(resovle_granularity(granu_type, param))) { + LOG_WARN("failed to resovle granularity", K(granu_type)); } else if (0 == param.method_opt_.case_compare("Z") && !is_vt) { if (OB_FAIL(set_default_column_params(param.column_params_))) { LOG_WARN("failed to set default column params", K(ret)); @@ -5775,7 +5589,7 @@ int ObDbmsStats::gather_table_stats_with_default_param(ObExecContext &ctx, } else if (OB_FAIL(use_default_gather_stat_options(ctx, stat_table, stat_param))) { LOG_WARN("failed to use default gather stat optitions", K(ret)); } else if (stat_table.need_gather_subpart_) { - stat_param.need_subpart_ = true; + stat_param.subpart_stat_param_.set_gather_stat(); } if (OB_SUCC(ret)) { if (OB_FAIL(ObDbmsStatsLockUnlock::adjust_table_stat_param(stat_table.no_regather_partition_ids_, @@ -6202,5 +6016,93 @@ bool ObDbmsStats::is_func_index(const ObTableStatParam &index_param) return is_true; } +/** + * @brief ObDbmsStats::parse_granularity + * @param ctx + * @param granularity + * possible values are: + * ALL: Gather all (subpartition, partition, and global) + * AUTO: Oracle recommends setting granularity to the default value of AUTO to gather subpartition, + * partition, or global statistics, depending on partition type. + * DEFAULT: Gathers global and partition-level + * GLOBAL: Gather global only + * GLOBAL AND PARTITION: Gather global and partition-level + * APPROX_GLOBAL AND PARTITION: similar to 'GLOBAL AND PARTITION' but in this case the global + statistics are aggregated from partition level statistics. + * PARTITION: Gather partition-level + * SUBPARTITION: Gather subpartition-level + * Oracle granularity actual behavior survey: + * + * @return + */ +int ObDbmsStats::resovle_granularity(ObGranularityType granu_type, ObTableStatParam ¶m) +{ + int ret = OB_SUCCESS; + if (ObGranularityType::GRANULARITY_AUTO == granu_type) { + param.global_stat_param_.set_gather_stat(false); + param.part_stat_param_.set_gather_stat(); + param.subpart_stat_param_.set_gather_stat(); + // refine auto granularity based on subpart type + if (ObPartitionLevel::PARTITION_LEVEL_TWO == param.part_level_ && + !(is_range_part(param.subpart_stat_param_.part_type_) || is_list_part(param.subpart_stat_param_.part_type_))) { + param.subpart_stat_param_.gather_histogram_ = false; + } + } else if (ObGranularityType::GRANULARITY_ALL == granu_type) { + param.global_stat_param_.set_gather_stat(false); + param.part_stat_param_.set_gather_stat(); + param.subpart_stat_param_.set_gather_stat(); + } else if (ObGranularityType::GRANULARITY_GLOBAL_AND_PARTITION == granu_type) { + param.global_stat_param_.set_gather_stat(false); + param.part_stat_param_.set_gather_stat(); + param.subpart_stat_param_.reset_gather_stat(); + } else if (ObGranularityType::GRANULARITY_APPROX_GLOBAL_AND_PARTITION == granu_type) { + bool gather_approx = param.part_level_ != ObPartitionLevel::PARTITION_LEVEL_ZERO; + param.global_stat_param_.set_gather_stat(gather_approx); + param.part_stat_param_.set_gather_stat(); + param.subpart_stat_param_.reset_gather_stat(); + } else if (ObGranularityType::GRANULARITY_GLOBAL == granu_type) { + param.global_stat_param_.set_gather_stat(false); + param.part_stat_param_.reset_gather_stat(); + param.subpart_stat_param_.reset_gather_stat(); + } else if (ObGranularityType::GRANULARITY_PARTITION == granu_type) { + param.global_stat_param_.reset_gather_stat(); + param.part_stat_param_.set_gather_stat(); + param.subpart_stat_param_.reset_gather_stat(); + } else if (ObGranularityType::GRANULARITY_SUBPARTITION == granu_type) { + param.global_stat_param_.reset_gather_stat(); + param.part_stat_param_.reset_gather_stat(); + param.subpart_stat_param_.set_gather_stat(); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected granularity type", K(granu_type)); + } + LOG_TRACE("succeed to parse granularity", K(param.global_stat_param_), + K(param.part_stat_param_), K(param.subpart_stat_param_)); + return ret; +} + +void ObDbmsStats::decide_modified_part(ObTableStatParam ¶m, const bool cascade_parts) +{ + if (param.part_name_.empty()) { + param.global_stat_param_.need_modify_ = true; + param.part_stat_param_.need_modify_ = cascade_parts; + param.subpart_stat_param_.need_modify_ = cascade_parts; + } else if (!param.is_subpart_name_) { + param.global_stat_param_.need_modify_ = false; + param.part_stat_param_.need_modify_ = true; + param.subpart_stat_param_.need_modify_ = cascade_parts; + } else { + param.global_stat_param_.need_modify_ = false; + param.part_stat_param_.need_modify_ = false; + param.subpart_stat_param_.need_modify_ = true; + } + if (!param.part_stat_param_.need_modify_) { + param.part_infos_.reset(); + } + if (!param.subpart_stat_param_.need_modify_) { + param.subpart_infos_.reset(); + } +} + } } diff --git a/src/pl/sys_package/ob_dbms_stats.h b/src/pl/sys_package/ob_dbms_stats.h index bd9f32c259..4ad1f32c89 100644 --- a/src/pl/sys_package/ob_dbms_stats.h +++ b/src/pl/sys_package/ob_dbms_stats.h @@ -558,6 +558,9 @@ private: static bool is_func_index(const ObTableStatParam &index_param); + static int resovle_granularity(ObGranularityType granu_type, ObTableStatParam ¶m); + static void decide_modified_part(ObTableStatParam ¶m, const bool cascade_parts); + }; } diff --git a/src/share/stat/ob_basic_stats_estimator.cpp b/src/share/stat/ob_basic_stats_estimator.cpp index 53a1331eb2..94231d8b5e 100644 --- a/src/share/stat/ob_basic_stats_estimator.cpp +++ b/src/share/stat/ob_basic_stats_estimator.cpp @@ -108,7 +108,8 @@ int ObBasicStatsEstimator::estimate(const ObTableStatParam ¶m, OB_FAIL(add_stat_item(ObStatNumDistinct(col_param, src_col_stats.at(i), param.need_approx_ndv_))) || OB_FAIL(add_stat_item(ObStatAvgLen(col_param, src_col_stats.at(i)))) || OB_FAIL(add_stat_item(ObStatLlcBitmap(col_param, src_col_stats.at(i)))) || - OB_FAIL(add_stat_item(ObStatTopKHist(col_param, src_tab_stat, src_col_stats.at(i))))) { + (extra.need_histogram_ && + OB_FAIL(add_stat_item(ObStatTopKHist(col_param, src_tab_stat, src_col_stats.at(i)))))) { LOG_WARN("failed to add statistic item", K(ret)); } else {/*do nothing*/} } @@ -707,7 +708,7 @@ int ObBasicStatsEstimator::gen_tablet_list(const ObTableStatParam ¶m, { int ret = OB_SUCCESS; ObSEArray tablet_ids; - if (param.need_global_ || param.need_approx_global_) { + if (param.global_stat_param_.need_modify_) { if (param.part_level_ == share::schema::ObPartitionLevel::PARTITION_LEVEL_ZERO) { if (OB_UNLIKELY(param.global_tablet_id_ == 0)) { ret = OB_ERR_UNEXPECTED; @@ -717,7 +718,7 @@ int ObBasicStatsEstimator::gen_tablet_list(const ObTableStatParam ¶m, } } } - if (OB_SUCC(ret) && param.need_part_ && + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_ && param.part_level_ != share::schema::ObPartitionLevel::PARTITION_LEVEL_TWO) { for (int64_t i = 0; OB_SUCC(ret) && i < param.part_infos_.count(); ++i) { if (OB_FAIL(tablet_ids.push_back(param.part_infos_.at(i).tablet_id_.id()))) { @@ -725,7 +726,7 @@ int ObBasicStatsEstimator::gen_tablet_list(const ObTableStatParam ¶m, } } } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.subpart_infos_.count(); ++i) { if (OB_FAIL(tablet_ids.push_back(param.subpart_infos_.at(i).tablet_id_.id()))) { LOG_WARN("failed to push back", K(ret)); diff --git a/src/share/stat/ob_dbms_stats_executor.cpp b/src/share/stat/ob_dbms_stats_executor.cpp index 37f0d9e12c..e26655b3bf 100644 --- a/src/share/stat/ob_dbms_stats_executor.cpp +++ b/src/share/stat/ob_dbms_stats_executor.cpp @@ -51,9 +51,10 @@ int ObDbmsStatsExecutor::gather_table_stats(ObExecContext &ctx, extra.partition_id_block_map_))) { LOG_WARN("failed to estimate block count", K(ret)); } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { extra.type_ = SUBPARTITION_LEVEL; extra.nth_part_ = 0; + extra.need_histogram_ = param.subpart_stat_param_.gather_histogram_; ObSEArray opt_stats; if (param.part_level_ != share::schema::PARTITION_LEVEL_TWO) { /*do nothing*/ @@ -65,9 +66,10 @@ int ObDbmsStatsExecutor::gather_table_stats(ObExecContext &ctx, LOG_WARN("failed to calssify opt stat", K(ret)); } } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { extra.type_ = PARTITION_LEVEL; extra.nth_part_ = 0; + extra.need_histogram_ = param.part_stat_param_.gather_histogram_; ObSEArray opt_stats; if (param.part_level_ == share::schema::PARTITION_LEVEL_ZERO) { /*do nothing*/ @@ -79,10 +81,12 @@ int ObDbmsStatsExecutor::gather_table_stats(ObExecContext &ctx, LOG_WARN("failed to calssify opt stat", K(ret)); } } - if (OB_SUCC(ret) && (param.need_global_ || - (param.need_approx_global_ && param.part_level_ == share::schema::PARTITION_LEVEL_ZERO))) { + if (OB_SUCC(ret) && + param.global_stat_param_.need_modify_ && + !param.global_stat_param_.gather_approx_) { extra.type_ = TABLE_LEVEL; extra.nth_part_ = 0; + extra.need_histogram_ = param.global_stat_param_.gather_histogram_; ObSEArray opt_stats; if (OB_FAIL(do_gather_stats(ctx, param, extra, approx_opt_part_stats, opt_stats))) { LOG_WARN("failed to gather table stats", K(ret)); @@ -142,7 +146,7 @@ int ObDbmsStatsExecutor::do_gather_stats(ObExecContext &ctx, ObHybridHistEstimator hybrid_est(ctx, *param.allocator_); if (OB_FAIL(basic_est.estimate(param, extra, opt_stats))) { LOG_WARN("failed to estimate basic statistics", K(ret)); - } else if (OB_FAIL(hybrid_est.estimate(param, extra, opt_stats))) { + } else if (extra.need_histogram_ && OB_FAIL(hybrid_est.estimate(param, extra, opt_stats))) { LOG_WARN("failed to estimate hybrid histogram", K(ret)); } else {/*do nothing*/} } @@ -436,7 +440,7 @@ int ObDbmsStatsExecutor::delete_table_stats(ObExecContext &ctx, ObSEArray no_stats_partition_ids; ObSEArray part_stattypes; uint64_t table_id = param.table_id_; - if (param.need_global_) { + if (param.global_stat_param_.need_modify_) { PartInfo part_info; ObExtraParam extra; extra.type_ = TABLE_LEVEL; @@ -453,7 +457,7 @@ int ObDbmsStatsExecutor::delete_table_stats(ObExecContext &ctx, LOG_WARN("failed to push back", K(ret)); } else {/*do nothing*/} } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.part_infos_.count(); ++i) { if (OB_FAIL(part_ids.push_back(param.part_infos_.at(i).part_id_))) { LOG_WARN("failed to push back partition id", K(ret)); @@ -466,7 +470,7 @@ int ObDbmsStatsExecutor::delete_table_stats(ObExecContext &ctx, } else {/*do nothing*/} } } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.subpart_infos_.count(); ++i) { if (OB_FAIL(part_ids.push_back(param.subpart_infos_.at(i).part_id_))) { LOG_WARN("failed to push back partition id", K(ret)); @@ -525,7 +529,7 @@ int ObDbmsStatsExecutor::delete_column_stats(ObExecContext &ctx, LOG_WARN("failed to push back", K(ret)); } else {/*do nothing*/} } - if (OB_SUCC(ret) && param.need_global_) { + if (OB_SUCC(ret) && param.global_stat_param_.need_modify_) { PartInfo part_info; ObExtraParam extra; extra.type_ = TABLE_LEVEL; @@ -536,14 +540,14 @@ int ObDbmsStatsExecutor::delete_column_stats(ObExecContext &ctx, LOG_WARN("failed to push back partition id", K(ret)); } else {/*do nothing*/} } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.part_infos_.count(); ++i) { if (OB_FAIL(part_ids.push_back(param.part_infos_.at(i).part_id_))) { LOG_WARN("failed to push back partition id", K(ret)); } else {/*do nothing*/} } } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.subpart_infos_.count(); ++i) { if (OB_FAIL(part_ids.push_back(param.subpart_infos_.at(i).part_id_))) { LOG_WARN("failed to push back partition id", K(ret)); @@ -714,7 +718,7 @@ int ObDbmsStatsExecutor::gather_index_stats(ObExecContext &ctx, extra.partition_id_block_map_))) { LOG_WARN("failed to estimate block count", K(ret)); } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { extra.type_ = SUBPARTITION_LEVEL; extra.nth_part_ = 0; if (param.part_level_ != share::schema::PARTITION_LEVEL_TWO) { @@ -723,7 +727,7 @@ int ObDbmsStatsExecutor::gather_index_stats(ObExecContext &ctx, LOG_WARN("failed to gather subpartition stats", K(ret)); } else {/*do nothing*/} } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { extra.type_ = PARTITION_LEVEL; extra.nth_part_ = 0; if (param.part_level_ == share::schema::PARTITION_LEVEL_ZERO) { @@ -732,7 +736,7 @@ int ObDbmsStatsExecutor::gather_index_stats(ObExecContext &ctx, LOG_WARN("failed to gather partition stats", K(ret)); } else {/*do nothing*/} } - if (OB_SUCC(ret) && (param.need_global_ || param.need_approx_global_)) { + if (OB_SUCC(ret) && (param.global_stat_param_.need_modify_)) { extra.type_ = TABLE_LEVEL; extra.nth_part_ = 0; if (OB_FAIL(do_gather_index_stats(ctx, param, extra, all_index_stats))) { @@ -802,21 +806,16 @@ int ObDbmsStatsExecutor::update_stat_online(ObExecContext &ctx, ObSEArray history_col_handles; ObSEArray table_stats; ObSEArray column_stats; - ObSEArray part_ids; if (OB_FAIL(ObDbmsStatsLockUnlock::check_stat_locked(ctx, param))) { if (ret == OB_ERR_DBMS_STATS_PL) { - param.need_global_ = false; - param.need_approx_global_ = false; - param.need_part_ = false; - param.need_subpart_ = false; + param.global_stat_param_.reset_gather_stat(); + param.part_stat_param_.reset_gather_stat(); + param.subpart_stat_param_.reset_gather_stat(); ret = OB_SUCCESS; // ignore lock check error } LOG_WARN("fail to check lock stat", K(ret)); } if (OB_FAIL(ret)) { - } else if (OB_FAIL(ObDbmsStatsUtils::get_part_ids_from_param(param, part_ids))) { - //part id should generated after check stat locked, since check_stat_locked will change part_info - LOG_WARN("fail to get part_ids"); } else if (OB_FAIL(ObDbmsStatsHistoryManager::get_history_stat_handles(ctx, param, history_tab_handles, diff --git a/src/share/stat/ob_dbms_stats_executor.h b/src/share/stat/ob_dbms_stats_executor.h index b0f1473185..f0274c0c44 100644 --- a/src/share/stat/ob_dbms_stats_executor.h +++ b/src/share/stat/ob_dbms_stats_executor.h @@ -77,11 +77,6 @@ private: static int prepare_opt_stat(ObIArray &all_stats, ObOptStat *&opt_stat); - static int try_drive_global_stat(ObExecContext &ctx, - const ObTableStatParam ¶m, - ObExtraParam &extra, - ObIArray &opt_stats); - static int check_all_cols_range_skew(const ObTableStatParam ¶m, ObIArray &opt_stats); diff --git a/src/share/stat/ob_dbms_stats_export_import.cpp b/src/share/stat/ob_dbms_stats_export_import.cpp index 5a5172baa1..f9683c4422 100644 --- a/src/share/stat/ob_dbms_stats_export_import.cpp +++ b/src/share/stat/ob_dbms_stats_export_import.cpp @@ -1500,7 +1500,7 @@ int ObDbmsStatsExportImport::gen_import_partition_list(const ObTableStatParam &p { int ret = OB_SUCCESS; bool need_or = false; - if (param.need_global_) { + if (param.global_stat_param_.need_modify_) { if (OB_FAIL(partition_list.append("c2 is NULL"))) { LOG_WARN("failed to append", K(ret), K(partition_list)); } else { @@ -1508,7 +1508,7 @@ int ObDbmsStatsExportImport::gen_import_partition_list(const ObTableStatParam &p } } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { if (need_or && !param.part_infos_.empty() && OB_FAIL(partition_list.append(" or "))) { LOG_WARN("failed to append sql", K(ret)); } @@ -1527,7 +1527,7 @@ int ObDbmsStatsExportImport::gen_import_partition_list(const ObTableStatParam &p } } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { if (need_or && !param.subpart_infos_.empty() && OB_FAIL(partition_list.append(" or "))) { LOG_WARN("failed to append sql", K(ret)); } diff --git a/src/share/stat/ob_dbms_stats_history_manager.cpp b/src/share/stat/ob_dbms_stats_history_manager.cpp index e1b100ed64..e4909abc11 100644 --- a/src/share/stat/ob_dbms_stats_history_manager.cpp +++ b/src/share/stat/ob_dbms_stats_history_manager.cpp @@ -674,14 +674,14 @@ int ObDbmsStatsHistoryManager::get_part_ids_and_column_ids(const ObTableStatPara { int ret = OB_SUCCESS; //get part ids - if (param.need_global_ || param.need_approx_global_) { + if (param.global_stat_param_.need_modify_) { int64_t part_id = param.global_part_id_; if (OB_FAIL(part_ids.push_back(part_id))) { LOG_WARN("failed to push back", K(ret)); } else {/*do nothing*/} } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.part_infos_.count(); ++i) { if (OB_FAIL(part_ids.push_back(param.part_infos_.at(i).part_id_))) { LOG_WARN("failed to push back", K(ret)); @@ -689,7 +689,7 @@ int ObDbmsStatsHistoryManager::get_part_ids_and_column_ids(const ObTableStatPara } } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.subpart_infos_.count(); ++i) { if (OB_FAIL(part_ids.push_back(param.subpart_infos_.at(i).part_id_))) { LOG_WARN("failed to push back", K(ret)); @@ -788,19 +788,19 @@ int ObDbmsStatsHistoryManager::gen_partition_list(const ObTableStatParam ¶m, { int ret = OB_SUCCESS; ObSEArray partition_ids; - if (param.need_global_ || param.need_approx_global_) { + if (param.global_stat_param_.need_modify_) { if (OB_FAIL(partition_ids.push_back(param.global_part_id_))) { LOG_WARN("failed to push back", K(ret)); } } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.part_infos_.count(); ++i) { if (OB_FAIL(partition_ids.push_back(param.part_infos_.at(i).part_id_))) { LOG_WARN("failed to push back", K(ret), K(param)); } } } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.subpart_infos_.count(); ++i) { if (OB_FAIL(partition_ids.push_back(param.subpart_infos_.at(i).part_id_))) { LOG_WARN("failed to push back", K(ret), K(param)); diff --git a/src/share/stat/ob_dbms_stats_lock_unlock.cpp b/src/share/stat/ob_dbms_stats_lock_unlock.cpp index 887a7b16a0..6d95c35a21 100644 --- a/src/share/stat/ob_dbms_stats_lock_unlock.cpp +++ b/src/share/stat/ob_dbms_stats_lock_unlock.cpp @@ -413,16 +413,15 @@ int ObDbmsStatsLockUnlock::adjust_table_stat_param(const ObIArray &lock if (locked_partition_ids.empty()) { /*do nothing*/ } else { - if (param.need_global_ || param.need_approx_global_) { + if (param.global_stat_param_.need_modify_) { int64_t part_id = param.global_part_id_; if (is_partition_id_locked(part_id, locked_partition_ids, idx)) { - param.need_global_ = false; - param.need_approx_global_ = false; + param.global_stat_param_.reset_gather_stat(); } else { has_valid_partition_id = true; } } - if (param.need_subpart_) { + if (param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.subpart_infos_.count(); ++i) { if (!is_partition_id_locked(param.subpart_infos_.at(i).part_id_, locked_partition_ids, idx)) { if (OB_FAIL(new_subpart_infos.push_back(param.subpart_infos_.at(i)))) { @@ -435,7 +434,7 @@ int ObDbmsStatsLockUnlock::adjust_table_stat_param(const ObIArray &lock } else {/*do nothing*/} } } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.part_infos_.count(); ++i) { if (!is_partition_id_locked(param.part_infos_.at(i).part_id_, locked_partition_ids, idx)) { if (ObIncrementalStatEstimator::is_part_can_incremental_gather( @@ -480,16 +479,17 @@ int ObDbmsStatsLockUnlock::adjust_table_stat_param(const ObIArray &lock } else if (OB_FAIL(param.part_infos_.assign(new_part_infos))) { LOG_WARN("failed to assign", K(ret)); } else { - param.need_subpart_ = !new_subpart_infos.empty(); - param.need_part_ = !new_part_infos.empty(); - if (param.need_approx_global_ && !param.need_part_) { + param.subpart_stat_param_.need_modify_ = !new_subpart_infos.empty(); + param.part_stat_param_.need_modify_ = !new_part_infos.empty(); + if (param.global_stat_param_.need_modify_ && + param.global_stat_param_.gather_approx_ && + !param.part_stat_param_.need_modify_) { //if take approx global and partition to gather, but all partition are locked, should adjust //approx global gather to global gather. - if (!param.need_global_ && !param.need_subpart_) { - param.need_approx_global_ = false; - param.need_global_ = true; - } else if (param.need_subpart_) {//incremental partition gather stats from subpart stats. - param.need_part_ = true; + if (!param.subpart_stat_param_.need_modify_) { + param.global_stat_param_.gather_approx_ = false; + } else { //incremental partition gather stats from subpart stats. + param.part_stat_param_.need_modify_ = true; } } LOG_TRACE("Succeed to adjust table stat param", K(param), K(locked_partition_ids)); @@ -505,7 +505,7 @@ int ObDbmsStatsLockUnlock::adjust_table_stat_locked(const ObIArray &loc { int ret = OB_SUCCESS; int64_t idx = -1; - if (param.need_global_ || param.need_approx_global_) { + if (param.global_stat_param_.need_modify_) { int64_t part_id = param.global_part_id_; if (is_partition_id_locked(part_id, locked_partition_ids, idx)) { if (OB_UNLIKELY(idx < 0 || idx >= stattype_locked_array.count() || @@ -517,7 +517,7 @@ int ObDbmsStatsLockUnlock::adjust_table_stat_locked(const ObIArray &loc } } } - if (OB_SUCC(ret) && param.need_subpart_) { + if (OB_SUCC(ret) && param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.subpart_infos_.count(); ++i) { if (is_partition_id_locked(param.subpart_infos_.at(i).part_id_, locked_partition_ids, idx)) { if (OB_UNLIKELY(idx < 0 || idx >= stattype_locked_array.count() || @@ -530,7 +530,7 @@ int ObDbmsStatsLockUnlock::adjust_table_stat_locked(const ObIArray &loc } } } - if (OB_SUCC(ret) && param.need_part_) { + if (OB_SUCC(ret) && param.part_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < param.part_infos_.count(); ++i) { if (is_partition_id_locked(param.part_infos_.at(i).part_id_, locked_partition_ids, idx)) { if (OB_UNLIKELY(idx < 0 || idx >= stattype_locked_array.count() || diff --git a/src/share/stat/ob_dbms_stats_preferences.cpp b/src/share/stat/ob_dbms_stats_preferences.cpp index 37a3b3bd66..bc25bb9d08 100644 --- a/src/share/stat/ob_dbms_stats_preferences.cpp +++ b/src/share/stat/ob_dbms_stats_preferences.cpp @@ -864,16 +864,9 @@ int ObGranularityPrefs::check_pref_value_validity(ObTableStatParam *param/*defau param->granularity_.assign_ptr(buf, buf_len); } } else { - bool dummy_need_global = false; - bool need_approx_global = false; - bool need_part = false; - bool need_subpart = false; - if (OB_FAIL(ObDbmsStatsUtils::parse_granularity(pvalue_, - dummy_need_global, - need_approx_global, - need_part, - need_subpart))) { - LOG_WARN("extract_valid_int64_with_trunc failed", K(ret), K(pvalue_)); + ObGranularityType dummy_type = ObGranularityType::GRANULARITY_INVALID; + if (OB_FAIL(ObDbmsStatsUtils::parse_granularity(pvalue_, dummy_type))) { + LOG_WARN("failed to parse granularity", K(ret), K(pvalue_)); } else {/*do nothing*/} } return ret; diff --git a/src/share/stat/ob_dbms_stats_utils.cpp b/src/share/stat/ob_dbms_stats_utils.cpp index edcb855048..f6ade5ca79 100644 --- a/src/share/stat/ob_dbms_stats_utils.cpp +++ b/src/share/stat/ob_dbms_stats_utils.cpp @@ -302,68 +302,25 @@ bool ObDbmsStatsUtils::is_virtual_index_table(const int64_t table_id) table_id == share::OB_ALL_VIRTUAL_SQL_PLAN_MONITOR_ORA_ALL_VIRTUAL_SQL_PLAN_MONITOR_I1_TID; } -/** - * @brief ObDbmsStats::parse_granularity - * @param ctx - * @param granularity - * possible values are: - * ALL: Gather all (subpartition, partition, and global) - * AUTO: Oracle recommends setting granularity to the default value of AUTO to gather subpartition, - * partition, or global statistics, depending on partition type. oracle 12c auto is same as - * ALL, compatible it. - * DEFAULT: Gathers global and partition-level - * GLOBAL: Gather global only - * GLOBAL AND PARTITION: Gather global and partition-level - * APPROX_GLOBAL AND PARTITION: similar to 'GLOBAL AND PARTITION' but in this case the global - statistics are aggregated from partition level statistics. - * PARTITION: Gather partition-level - * SUBPARTITION: Gather subpartition-level - * Oracle granularity actual behavior survey: - * - * @return - */ -int ObDbmsStatsUtils::parse_granularity(const ObString &granularity, - bool &need_global, - bool &need_approx_global, - bool &need_part, - bool &need_subpart) +int ObDbmsStatsUtils::parse_granularity(const ObString &granularity, ObGranularityType &granu_type) { int ret = OB_SUCCESS; - // first check the table is partitioned; if (0 == granularity.case_compare("all")) { - need_global = true; - need_part = true; - need_subpart = true; - need_approx_global = false; + granu_type = ObGranularityType::GRANULARITY_ALL; } else if (0 == granularity.case_compare("auto") || 0 == granularity.case_compare("Z")) { - /*do nothing, use default value*/ + granu_type = ObGranularityType::GRANULARITY_AUTO; } else if (0 == granularity.case_compare("default") || 0 == granularity.case_compare("global and partition")) { - need_global = true; - need_part = true; - need_subpart = false; - need_approx_global = false; + granu_type = ObGranularityType::GRANULARITY_GLOBAL_AND_PARTITION; } else if (0 == granularity.case_compare("approx_global and partition")) { - need_global = false; - need_approx_global = true; - need_part = true; - need_subpart = false; + granu_type = ObGranularityType::GRANULARITY_APPROX_GLOBAL_AND_PARTITION; } else if (0 == granularity.case_compare("global")) { - need_global = true; - need_part = false; - need_subpart = false; - need_approx_global = false; + granu_type = ObGranularityType::GRANULARITY_GLOBAL; } else if (0 == granularity.case_compare("partition")) { - need_global = false; - need_part = true; - need_subpart = false; - need_approx_global = false; + granu_type = ObGranularityType::GRANULARITY_PARTITION; } else if (0 == granularity.case_compare("subpartition")) { - need_global = false; - need_part = false; - need_subpart = true; - need_approx_global = false; + granu_type = ObGranularityType::GRANULARITY_SUBPARTITION; } else { ret = OB_ERR_DBMS_STATS_PL; LOG_WARN("Illegal granularity : must be AUTO | ALL | GLOBAL | PARTITION | SUBPARTITION" \ @@ -371,7 +328,6 @@ int ObDbmsStatsUtils::parse_granularity(const ObString &granularity, LOG_USER_ERROR(OB_ERR_DBMS_STATS_PL, "Illegal granularity : must be AUTO | ALL | GLOBAL |" \ " PARTITION | SUBPARTITION | GLOBAL AND PARTITION | APPROX_GLOBAL AND PARTITION"); } - LOG_TRACE("succeed to parse granularity", K(need_global), K(need_part), K(need_subpart)); return ret; } @@ -676,12 +632,12 @@ int ObDbmsStatsUtils::check_part_id_valid(const ObTableStatParam ¶m, bool found = false; LOG_DEBUG("check part_id valid", K(param), K(part_id)); is_valid = false; - if (param.need_global_) { + if (param.global_stat_param_.need_modify_) { if (part_id == param.global_part_id_) { is_valid = true; } } - if (!is_valid && param.need_part_) { + if (!is_valid && param.part_stat_param_.need_modify_) { for (int64_t i = 0; !found && i < param.part_infos_.count(); i++) { if (part_id == param.part_infos_.at(i).part_id_) { found = true; @@ -689,7 +645,7 @@ int ObDbmsStatsUtils::check_part_id_valid(const ObTableStatParam ¶m, } } } - if (!is_valid && param.need_subpart_) { + if (!is_valid && param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; !found && i < param.subpart_infos_.count(); i++) { if (part_id == param.subpart_infos_.at(i).part_id_) { found = true; @@ -700,31 +656,5 @@ int ObDbmsStatsUtils::check_part_id_valid(const ObTableStatParam ¶m, return ret; } -int ObDbmsStatsUtils::get_part_ids_from_param(const ObTableStatParam ¶m, - common::ObIArray &part_ids) -{ - int ret = OB_SUCCESS; - if (param.need_global_) { - if (OB_FAIL(part_ids.push_back(param.global_part_id_))) { - LOG_WARN("failed to push back partition id", K(ret)); - } - } - if (OB_SUCC(ret) && param.need_part_) { - for (int64_t i = 0; OB_SUCC(ret) && i < param.part_infos_.count(); ++i) { - if (OB_FAIL(part_ids.push_back(param.part_infos_.at(i).part_id_))) { - LOG_WARN("failed to push back partition id", K(ret)); - } - } - } - if (OB_SUCC(ret) && param.need_subpart_) { - for (int64_t i = 0; OB_SUCC(ret) && i < param.subpart_infos_.count(); ++i) { - if (OB_FAIL(part_ids.push_back(param.subpart_infos_.at(i).part_id_))) { - LOG_WARN("failed to push back partition id", K(ret)); - } - } - } - return ret; -} - } } diff --git a/src/share/stat/ob_dbms_stats_utils.h b/src/share/stat/ob_dbms_stats_utils.h index 1d3745dae5..fcfba0d937 100644 --- a/src/share/stat/ob_dbms_stats_utils.h +++ b/src/share/stat/ob_dbms_stats_utils.h @@ -76,11 +76,7 @@ public: static bool is_virtual_index_table(const int64_t table_id); - static int parse_granularity(const ObString &granularity, - bool &need_global, - bool &need_approx_global, - bool &need_part, - bool &need_subpart); + static int parse_granularity(const ObString &granularity, ObGranularityType &granu_type); static bool is_subpart_id(const ObIArray &partition_infos, const int64_t partition_id, @@ -111,7 +107,6 @@ public: common::ObIArray &dst_column_stat); static int check_part_id_valid(const ObTableStatParam ¶m, const ObObjectID part_id, bool &is_valid); - static int get_part_ids_from_param(const ObTableStatParam ¶m, common::ObIArray &part_ids); private: static int batch_write(share::schema::ObSchemaGetterGuard *schema_guard, const uint64_t tenant_id, diff --git a/src/share/stat/ob_incremental_stat_estimator.cpp b/src/share/stat/ob_incremental_stat_estimator.cpp index a9f01d137f..0ff2200c24 100644 --- a/src/share/stat/ob_incremental_stat_estimator.cpp +++ b/src/share/stat/ob_incremental_stat_estimator.cpp @@ -40,9 +40,11 @@ int ObIncrementalStatEstimator::try_drive_global_stat(ObExecContext &ctx, ObIArray &opt_stats) { int ret = OB_SUCCESS; - if (extra.type_ == INVALID_LEVEL || extra.type_ == TABLE_LEVEL || - !param.need_approx_global_ || param.part_level_ == share::schema::PARTITION_LEVEL_ZERO) { - LOG_TRACE("not fullfill drive global stat", K(extra.type_),K(param.need_approx_global_), + if (extra.type_ == INVALID_LEVEL || + extra.type_ == TABLE_LEVEL || + !(param.global_stat_param_.need_modify_ && param.global_stat_param_.gather_approx_) || + param.part_level_ == share::schema::PARTITION_LEVEL_ZERO) { + LOG_TRACE("not fullfill drive global stat", K(extra.type_),K(param.global_stat_param_), K(param.part_level_)); } else if (extra.type_ == SUBPARTITION_LEVEL) { if (OB_FAIL(drive_part_stats_from_subpart_stats(ctx, param, opt_stats, @@ -880,7 +882,9 @@ bool ObIncrementalStatEstimator::is_part_can_incremental_gather(const ObTableSta bool can_be = false; int64_t no_regather_subpart_cnt = 0; int64_t cur_part_id = OB_INVALID_ID; - if (param.need_approx_global_ && param.need_subpart_ && + if (param.global_stat_param_.need_modify_ && + param.global_stat_param_.gather_approx_ && + param.subpart_stat_param_.need_modify_ && param.part_level_ == share::schema::ObPartitionLevel::PARTITION_LEVEL_TWO) { for (int64_t i = 0; i < param.no_regather_partition_ids_.count(); ++i) { if (ObDbmsStatsUtils::is_subpart_id(param.all_subpart_infos_, @@ -978,9 +982,9 @@ int ObIncrementalStatEstimator::gen_opt_stat_param_by_direct_load(ObExecContext param.tenant_id_ = ctx.get_my_session()->get_effective_tenant_id(); param.part_level_ = table_schema->get_part_level(); param.total_part_cnt_ = table_schema->get_all_part_num(); - param.need_global_ = true; - param.need_part_ = true; - param.need_subpart_ = true; + param.global_stat_param_.need_modify_ = true; + param.part_stat_param_.need_modify_ = true; + param.subpart_stat_param_.need_modify_ = true; if (OB_FAIL(pl::ObDbmsStats::set_param_global_part_id(ctx, param))) { LOG_WARN("failed to set param globa part id", K(ret)); } diff --git a/src/share/stat/ob_index_stats_estimator.cpp b/src/share/stat/ob_index_stats_estimator.cpp index 082433bf64..acec7534e1 100644 --- a/src/share/stat/ob_index_stats_estimator.cpp +++ b/src/share/stat/ob_index_stats_estimator.cpp @@ -405,13 +405,13 @@ int ObIndexStatsEstimator::get_all_need_gather_partition_ids(const ObTableStatPa ObIArray &gather_part_ids) { int ret = OB_SUCCESS; - if (index_param.need_global_ || index_param.need_approx_global_) { + if (index_param.global_stat_param_.need_modify_) { if (OB_FAIL(gather_part_ids.push_back(data_param.global_part_id_))) { LOG_WARN("failed to push back", K(ret)); } } - if (OB_SUCC(ret) && index_param.need_part_) { + if (OB_SUCC(ret) && index_param.part_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < data_param.part_infos_.count(); ++i) { if (OB_FAIL(gather_part_ids.push_back(data_param.part_infos_.at(i).part_id_))) { LOG_WARN("failed to push back", K(ret)); @@ -419,7 +419,7 @@ int ObIndexStatsEstimator::get_all_need_gather_partition_ids(const ObTableStatPa } } - if (OB_SUCC(ret) && index_param.need_subpart_) { + if (OB_SUCC(ret) && index_param.subpart_stat_param_.need_modify_) { for (int64_t i = 0; OB_SUCC(ret) && i < data_param.subpart_infos_.count(); ++i) { if (OB_FAIL(gather_part_ids.push_back(data_param.subpart_infos_.at(i).part_id_))) { LOG_WARN("failed to push back", K(ret)); diff --git a/src/share/stat/ob_stat_define.cpp b/src/share/stat/ob_stat_define.cpp index 92c4399adf..207efec45a 100644 --- a/src/share/stat/ob_stat_define.cpp +++ b/src/share/stat/ob_stat_define.cpp @@ -91,10 +91,9 @@ int ObTableStatParam::assign(const ObTableStatParam &other) sample_info_.sample_value_ = other.sample_info_.sample_value_; method_opt_ = other.method_opt_; degree_ = other.degree_; - need_global_ = other.need_global_; - need_approx_global_ = other.need_approx_global_; - need_part_ = other.need_part_; - need_subpart_ = other.need_subpart_; + global_stat_param_ = other.global_stat_param_; + part_stat_param_ = other.part_stat_param_; + subpart_stat_param_ = other.subpart_stat_param_; granularity_ = other.granularity_; cascade_ = other.cascade_; stat_tab_ = other.stat_tab_; @@ -149,10 +148,9 @@ int ObTableStatParam::assign_common_property(const ObTableStatParam &other) sample_info_.sample_value_ = other.sample_info_.sample_value_; method_opt_ = other.method_opt_; degree_ = other.degree_; - need_global_ = other.need_global_; - need_approx_global_ = other.need_approx_global_; - need_part_ = other.need_part_; - need_subpart_ = other.need_subpart_; + global_stat_param_ = other.global_stat_param_; + part_stat_param_ = other.part_stat_param_; + subpart_stat_param_ = other.subpart_stat_param_; granularity_ = other.granularity_; cascade_ = other.cascade_; stat_tab_ = other.stat_tab_; diff --git a/src/share/stat/ob_stat_define.h b/src/share/stat/ob_stat_define.h index aadf64c9db..16a3faa723 100644 --- a/src/share/stat/ob_stat_define.h +++ b/src/share/stat/ob_stat_define.h @@ -105,12 +105,25 @@ enum ColumnAttrFlag IS_NOT_NULL_COL = 1 << 3 }; +enum ObGranularityType +{ + GRANULARITY_INVALID = 0, + GRANULARITY_GLOBAL, + GRANULARITY_PARTITION, + GRANULARITY_SUBPARTITION, + GRANULARITY_ALL, + GRANULARITY_AUTO, + GRANULARITY_GLOBAL_AND_PARTITION, + GRANULARITY_APPROX_GLOBAL_AND_PARTITION +}; + struct ObExtraParam { StatLevel type_; int64_t nth_part_; PartitionIdBlockMap partition_id_block_map_; int64_t start_time_; + bool need_histogram_; }; //TODO@jiangxiu.wt: improve the expression of PartInfo, use the map is better. @@ -174,6 +187,76 @@ struct PartInfo ObSEArray no_regather_partition_ids_; }; +struct ObGlobalStatParam +{ + ObGlobalStatParam() + : need_modify_(true), + gather_approx_(false), + gather_histogram_(true) + {} + ObGlobalStatParam& operator=(const ObGlobalStatParam& other) + { + need_modify_ = other.need_modify_; + gather_approx_ = other.gather_approx_; + gather_histogram_ = other.gather_histogram_; + return *this; + } + void set_gather_stat(const bool gather_approx) + { + need_modify_ = true; + gather_approx_ = gather_approx; + gather_histogram_ = true; + } + void reset_gather_stat() + { + need_modify_ = false; + gather_approx_ = false; + gather_histogram_ = false; + } + TO_STRING_KV(K_(need_modify), + K_(gather_approx), + K_(gather_histogram)); + bool need_modify_; + bool gather_approx_; + bool gather_histogram_; +}; +struct ObPartitionStatParam +{ + ObPartitionStatParam(share::schema::ObPartitionFuncType type) + : part_type_(type), + need_modify_(true), + gather_histogram_(true) + {} + ObPartitionStatParam& operator=(const ObPartitionStatParam& other) + { + part_type_ = other.part_type_; + need_modify_ = other.need_modify_; + gather_histogram_ = other.gather_histogram_; + return *this; + } + void assign_without_part_type(const ObPartitionStatParam& other) + { + need_modify_ = other.need_modify_; + gather_histogram_ = other.gather_histogram_; + } + void set_gather_stat() + { + need_modify_ = true; + gather_histogram_ = true; + } + void reset_gather_stat() + { + need_modify_ = false; + gather_histogram_ = false; + } + TO_STRING_KV(K_(part_type), + K_(need_modify), + K_(gather_histogram)); + share::schema::ObPartitionFuncType part_type_; + bool need_modify_; + bool gather_histogram_; +}; + enum SampleType { RowSample, @@ -262,6 +345,9 @@ struct ObTableStatParam { tab_name_(), table_id_(OB_INVALID_ID), part_level_(share::schema::ObPartitionLevel::PARTITION_LEVEL_ZERO), + global_stat_param_(), + part_stat_param_(share::schema::ObPartitionFuncType::PARTITION_FUNC_TYPE_MAX), + subpart_stat_param_(share::schema::ObPartitionFuncType::PARTITION_FUNC_TYPE_MAX), total_part_cnt_(0), part_name_(), part_infos_(), @@ -270,10 +356,6 @@ struct ObTableStatParam { sample_info_(), method_opt_(), degree_(1), - need_global_(true), - need_approx_global_(false), - need_part_(true), - need_subpart_(true), granularity_(), cascade_(false), stat_tab_(), @@ -326,6 +408,9 @@ struct ObTableStatParam { ObString tab_name_; uint64_t table_id_; share::schema::ObPartitionLevel part_level_; + ObGlobalStatParam global_stat_param_; + ObPartitionStatParam part_stat_param_; + ObPartitionStatParam subpart_stat_param_; int64_t total_part_cnt_; ObString part_name_; @@ -337,11 +422,6 @@ struct ObTableStatParam { ObString method_opt_; int64_t degree_; - bool need_global_; - bool need_approx_global_; - bool need_part_; - bool need_subpart_; - ObString granularity_; bool cascade_; @@ -389,10 +469,9 @@ struct ObTableStatParam { K(sample_info_), K(method_opt_), K(degree_), - K(need_global_), - K(need_approx_global_), - K(need_part_), - K(need_subpart_), + K(global_stat_param_), + K(part_stat_param_), + K(subpart_stat_param_), K(granularity_), K(cascade_), K(stat_tab_), diff --git a/src/sql/engine/opt_statistics/ob_optimizer_stats_gathering_op.cpp b/src/sql/engine/opt_statistics/ob_optimizer_stats_gathering_op.cpp index 0e7a215410..3dec538f74 100644 --- a/src/sql/engine/opt_statistics/ob_optimizer_stats_gathering_op.cpp +++ b/src/sql/engine/opt_statistics/ob_optimizer_stats_gathering_op.cpp @@ -662,14 +662,14 @@ int ObOptimizerStatsGatheringOp::generate_stat_param(ObTableStatParam ¶m) } else { param.tenant_id_ = tenant_id_; param.table_id_ = MY_SPEC.table_id_; - param.need_global_ = true; + param.global_stat_param_.need_modify_ = true; param.part_level_ = MY_SPEC.part_level_; param.allocator_ = &ctx_.get_allocator(); if (!MY_SPEC.is_part_table()) { param.global_part_id_ = MY_SPEC.table_id_; param.global_tablet_id_ = MY_SPEC.table_id_; - param.need_part_ = false; - param.need_subpart_ = false; + param.part_stat_param_.need_modify_ = false; + param.subpart_stat_param_.need_modify_ = false; } else { param.global_part_id_ = -1; param.global_tablet_id_ = -1; @@ -694,8 +694,8 @@ int ObOptimizerStatsGatheringOp::generate_stat_param(ObTableStatParam ¶m) if (OB_FAIL(ret)) { } else if (MY_SPEC.is_part_table() && !MY_SPEC.is_two_level_part()) { - param.need_part_ = true; - param.need_subpart_ = false; + param.part_stat_param_.need_modify_ = true; + param.subpart_stat_param_.need_modify_ = false; } else if (MY_SPEC.is_part_table() && MY_SPEC.is_two_level_part()){ //default is true } diff --git a/src/sql/resolver/ddl/ob_analyze_stmt.cpp b/src/sql/resolver/ddl/ob_analyze_stmt.cpp index 84e36a9cf0..6f4970a5a0 100644 --- a/src/sql/resolver/ddl/ob_analyze_stmt.cpp +++ b/src/sql/resolver/ddl/ob_analyze_stmt.cpp @@ -93,14 +93,9 @@ int ObAnalyzeStmt::fill_table_stat_param(ObExecContext &ctx, common::ObTableStat param.sample_info_ = sample_info_; param.degree_ = parallel_degree_; //analyze stmt default use granularity is based partition type(oracle 12c),maybe refine it later - param.need_global_ = partition_name_.empty(); - param.need_approx_global_ = false; - param.need_part_ = !partition_infos_.empty(); - param.need_subpart_ = !subpartition_infos_.empty(); - // param.need_approx_global_ = false; - // param.need_global_ = part_level_ == share::schema::PARTITION_LEVEL_ZERO; - // param.need_part_ = part_level_ == share::schema::PARTITION_LEVEL_ONE; - // param.need_subpart_ = part_level_ == share::schema::PARTITION_LEVEL_TWO; + param.global_stat_param_.need_modify_ = partition_name_.empty(); + param.part_stat_param_.need_modify_ = !partition_infos_.empty(); + param.subpart_stat_param_.need_modify_ = !subpartition_infos_.empty(); } LOG_TRACE("link bug", K(param));