[CP] fix some optimizer stats bug
This commit is contained in:
parent
648c9b98b5
commit
73cc1ad061
@ -421,21 +421,26 @@ int ObDbmsStats::fast_gather_index_stats(ObExecContext &ctx,
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_all_fast_gather = true;
|
||||
ObSEArray<ObAuxTableMetaInfo, 4> simple_index_infos;
|
||||
uint64_t index_tids[OB_MAX_INDEX_PER_TABLE + 1];
|
||||
int64_t index_count = OB_MAX_INDEX_PER_TABLE + 1;
|
||||
share::schema::ObSchemaGetterGuard *schema_guard = ctx.get_virtual_table_ctx().schema_guard_;
|
||||
if (OB_FAIL(get_table_index_infos(ctx, data_param.table_id_, simple_index_infos))) {
|
||||
if (OB_FAIL(get_table_index_infos(schema_guard,
|
||||
ctx.get_my_session()->get_effective_tenant_id(),
|
||||
data_param.table_id_,
|
||||
index_tids,
|
||||
index_count))) {
|
||||
LOG_WARN("failed to get table index infos", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < index_count; ++i) {
|
||||
StatTable stat_table;
|
||||
stat_table.database_id_ = data_param.db_id_;
|
||||
stat_table.table_id_ = simple_index_infos.at(i).table_id_;
|
||||
stat_table.table_id_ = index_tids[i];
|
||||
ObTableStatParam index_param;
|
||||
index_param.is_index_stat_ = true;
|
||||
index_param.assign_common_property(data_param);
|
||||
bool is_fast_gather = true;
|
||||
const share::schema::ObTableSchema *index_schema = NULL;
|
||||
if (simple_index_infos.at(i).table_id_ == data_param.table_id_) {
|
||||
if (index_tids[i] == data_param.table_id_) {
|
||||
//do nothing, remove primary table
|
||||
} else if (OB_FAIL(parse_table_part_info(ctx, stat_table, index_param))) {
|
||||
LOG_WARN("failed to parse table part info", K(ret));
|
||||
@ -1072,17 +1077,22 @@ int ObDbmsStats::delete_table_index_stats(sql::ObExecContext &ctx,
|
||||
const ObTableStatParam data_param)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObAuxTableMetaInfo, 4> simple_index_infos;
|
||||
if (OB_FAIL(get_table_index_infos(ctx, data_param.table_id_, simple_index_infos))) {
|
||||
uint64_t index_tids[OB_MAX_INDEX_PER_TABLE + 1];
|
||||
int64_t index_count = OB_MAX_INDEX_PER_TABLE + 1;
|
||||
if (OB_FAIL(get_table_index_infos(ctx.get_virtual_table_ctx().schema_guard_,
|
||||
ctx.get_my_session()->get_effective_tenant_id(),
|
||||
data_param.table_id_,
|
||||
index_tids,
|
||||
index_count))) {
|
||||
LOG_WARN("failed to get table index infos", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < index_count; ++i) {
|
||||
StatTable stat_table;
|
||||
stat_table.database_id_ = data_param.db_id_;
|
||||
stat_table.table_id_ = simple_index_infos.at(i).table_id_;
|
||||
stat_table.table_id_ = index_tids[i];
|
||||
ObTableStatParam index_param;
|
||||
index_param.assign_common_property(data_param);
|
||||
if (simple_index_infos.at(i).table_id_ == data_param.table_id_) {
|
||||
if (index_tids[i] == data_param.table_id_) {
|
||||
//do nothing, remove primary table
|
||||
} else if (OB_FAIL(parse_table_part_info(ctx, stat_table, index_param))) {
|
||||
LOG_WARN("failed to parse table part info", K(ret));
|
||||
@ -1544,17 +1554,22 @@ int ObDbmsStats::export_table_index_stats(sql::ObExecContext &ctx,
|
||||
const ObTableStatParam data_param)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObAuxTableMetaInfo, 4> simple_index_infos;
|
||||
if (OB_FAIL(get_table_index_infos(ctx, data_param.table_id_, simple_index_infos))) {
|
||||
uint64_t index_tids[OB_MAX_INDEX_PER_TABLE + 1];
|
||||
int64_t index_count = OB_MAX_INDEX_PER_TABLE + 1;
|
||||
if (OB_FAIL(get_table_index_infos(ctx.get_virtual_table_ctx().schema_guard_,
|
||||
ctx.get_my_session()->get_effective_tenant_id(),
|
||||
data_param.table_id_,
|
||||
index_tids,
|
||||
index_count))) {
|
||||
LOG_WARN("failed to get table index infos", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < index_count; ++i) {
|
||||
StatTable stat_table;
|
||||
stat_table.database_id_ = data_param.db_id_;
|
||||
stat_table.table_id_ = simple_index_infos.at(i).table_id_;
|
||||
stat_table.table_id_ = index_tids[i];
|
||||
ObTableStatParam index_param;
|
||||
index_param.assign_common_property(data_param);
|
||||
if (simple_index_infos.at(i).table_id_ == data_param.table_id_) {
|
||||
if (index_tids[i] == data_param.table_id_) {
|
||||
//do nothing, remove primary table
|
||||
} else if (OB_FAIL(parse_table_part_info(ctx, stat_table, index_param))) {
|
||||
LOG_WARN("failed to parse table part info", K(ret));
|
||||
@ -1930,17 +1945,22 @@ int ObDbmsStats::import_table_index_stats(sql::ObExecContext &ctx,
|
||||
const ObTableStatParam data_param)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObAuxTableMetaInfo, 4> simple_index_infos;
|
||||
if (OB_FAIL(get_table_index_infos(ctx, data_param.table_id_, simple_index_infos))) {
|
||||
uint64_t index_tids[OB_MAX_INDEX_PER_TABLE + 1];
|
||||
int64_t index_count = OB_MAX_INDEX_PER_TABLE + 1;
|
||||
if (OB_FAIL(get_table_index_infos(ctx.get_virtual_table_ctx().schema_guard_,
|
||||
ctx.get_my_session()->get_effective_tenant_id(),
|
||||
data_param.table_id_,
|
||||
index_tids,
|
||||
index_count))) {
|
||||
LOG_WARN("failed to get table index infos", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < index_count; ++i) {
|
||||
StatTable stat_table;
|
||||
stat_table.database_id_ = data_param.db_id_;
|
||||
stat_table.table_id_ = simple_index_infos.at(i).table_id_;
|
||||
stat_table.table_id_ = index_tids[i];
|
||||
ObTableStatParam index_param;
|
||||
index_param.assign_common_property(data_param);
|
||||
if (simple_index_infos.at(i).table_id_ == data_param.table_id_) {
|
||||
if (index_tids[i] == data_param.table_id_) {
|
||||
//do nothing, remove primary table
|
||||
} else if (OB_FAIL(parse_table_part_info(ctx, stat_table, index_param))) {
|
||||
LOG_WARN("failed to parse table part info", K(ret));
|
||||
@ -2141,17 +2161,22 @@ int ObDbmsStats::lock_or_unlock_index_stats(sql::ObExecContext &ctx,
|
||||
bool is_lock_stats)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObAuxTableMetaInfo, 4> simple_index_infos;
|
||||
if (OB_FAIL(get_table_index_infos(ctx, data_param.table_id_, simple_index_infos))) {
|
||||
uint64_t index_tids[OB_MAX_INDEX_PER_TABLE + 1];
|
||||
int64_t index_count = OB_MAX_INDEX_PER_TABLE + 1;
|
||||
if (OB_FAIL(get_table_index_infos(ctx.get_virtual_table_ctx().schema_guard_,
|
||||
ctx.get_my_session()->get_effective_tenant_id(),
|
||||
data_param.table_id_,
|
||||
index_tids,
|
||||
index_count))) {
|
||||
LOG_WARN("failed to get table index infos", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < index_count; ++i) {
|
||||
StatTable stat_table;
|
||||
stat_table.database_id_ = data_param.db_id_;
|
||||
stat_table.table_id_ = simple_index_infos.at(i).table_id_;
|
||||
stat_table.table_id_ = index_tids[i];
|
||||
ObTableStatParam index_param;
|
||||
index_param.assign_common_property(data_param);
|
||||
if (simple_index_infos.at(i).table_id_ == data_param.table_id_) {
|
||||
if (index_tids[i] == data_param.table_id_) {
|
||||
//do nothing, remove primary table
|
||||
} else if (OB_FAIL(parse_table_part_info(ctx, stat_table, index_param))) {
|
||||
LOG_WARN("failed to parse table part info", K(ret));
|
||||
@ -5340,6 +5365,7 @@ int ObDbmsStats::gather_database_stats_job_proc(sql::ObExecContext &ctx,
|
||||
int64_t duration_time = -1;
|
||||
int64_t succeed_cnt = 0;
|
||||
bool no_auto_gather = (OB_E(EventTable::EN_LEADER_STORAGE_ESTIMATION) OB_SUCCESS) != OB_SUCCESS;
|
||||
ObSQLSessionInfo::LockGuard query_lock_guard(ctx.get_my_session()->get_query_lock());
|
||||
if (OB_FAIL(check_statistic_table_writeable(ctx))) {
|
||||
ret = OB_SUCCESS;
|
||||
LOG_INFO("auto gather database statistics abort because of statistic table is unwriteable");
|
||||
@ -5925,30 +5951,26 @@ bool ObDbmsStats::is_table_gather_global_stats(const int64_t global_id,
|
||||
return is_gather;
|
||||
}
|
||||
|
||||
int ObDbmsStats::get_table_index_infos(sql::ObExecContext &ctx,
|
||||
const int64_t table_id,
|
||||
ObIArray<ObAuxTableMetaInfo> &index_infos)
|
||||
int ObDbmsStats::get_table_index_infos(share::schema::ObSchemaGetterGuard *schema_guard,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t table_id,
|
||||
uint64_t *index_tid_arr,
|
||||
int64_t &index_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const share::schema::ObTableSchema *table_schema = NULL;
|
||||
share::schema::ObSchemaGetterGuard *schema_guard = ctx.get_virtual_table_ctx().schema_guard_;
|
||||
if (OB_ISNULL(schema_guard)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret), K(schema_guard));
|
||||
} else if (OB_FAIL(schema_guard->get_table_schema(
|
||||
ctx.get_my_session()->get_effective_tenant_id(),
|
||||
table_id,
|
||||
table_schema))) {
|
||||
LOG_WARN("failed to get table schema", K(ret));
|
||||
} else if (OB_ISNULL(table_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret), K(table_schema));
|
||||
} else if (share::is_oracle_mapping_real_virtual_table(table_schema->get_table_id())) {
|
||||
} else if (share::is_oracle_mapping_real_virtual_table(table_id)) {
|
||||
// do not gather stat for oracle inner table index
|
||||
} else if (OB_FAIL(table_schema->get_simple_index_infos(index_infos))) {
|
||||
LOG_WARN("failed to get simple index infos", K(ret));
|
||||
} else {
|
||||
LOG_TRACE("Succeed to get table index infos", K(table_id), K(index_infos));
|
||||
} else if (OB_FAIL(schema_guard->get_can_read_index_array(tenant_id,
|
||||
table_id,
|
||||
index_tid_arr,
|
||||
index_count,
|
||||
false, /*with_mv*/
|
||||
true, /*with_global_index*/
|
||||
false /*domain index*/))) {
|
||||
LOG_WARN("failed to get can read index", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -5963,22 +5985,27 @@ int ObDbmsStats::get_index_schema(sql::ObExecContext &ctx,
|
||||
int ret = OB_SUCCESS;
|
||||
share::schema::ObSchemaGetterGuard *schema_guard = ctx.get_virtual_table_ctx().schema_guard_;
|
||||
index_schema = NULL;
|
||||
ObSEArray<ObAuxTableMetaInfo, 4> simple_index_infos;
|
||||
uint64_t index_tids[OB_MAX_INDEX_PER_TABLE + 1];
|
||||
int64_t index_count = OB_MAX_INDEX_PER_TABLE + 1;
|
||||
if (OB_ISNULL(schema_guard)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (OB_FAIL(get_table_index_infos(ctx, data_table_id, simple_index_infos))) {
|
||||
} else if (OB_FAIL(get_table_index_infos(ctx.get_virtual_table_ctx().schema_guard_,
|
||||
ctx.get_my_session()->get_effective_tenant_id(),
|
||||
data_table_id,
|
||||
index_tids,
|
||||
index_count))) {
|
||||
LOG_WARN("failed to get table index infos", K(ret));
|
||||
} else {
|
||||
bool found_it = false;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !found_it && i < simple_index_infos.count(); ++i) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !found_it && i < index_count; ++i) {
|
||||
const share::schema::ObTableSchema *cur_index_schema = NULL;
|
||||
ObString cur_index_name;
|
||||
if (simple_index_infos.at(i).table_id_ == data_table_id) {
|
||||
if (index_tids[i] == data_table_id) {
|
||||
//do nothing, remove primary table
|
||||
} else if (OB_FAIL(schema_guard->get_table_schema(
|
||||
ctx.get_my_session()->get_effective_tenant_id(),
|
||||
simple_index_infos.at(i).table_id_, cur_index_schema))) {
|
||||
index_tids[i], cur_index_schema))) {
|
||||
LOG_WARN("failed to get table schema", K(ret));
|
||||
} else if (OB_ISNULL(cur_index_schema) || OB_UNLIKELY(!cur_index_schema->is_index_table())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
|
@ -579,9 +579,11 @@ private:
|
||||
const ObObjParam &table_name,
|
||||
ObTableStatParam ¶m);
|
||||
|
||||
static int get_table_index_infos(sql::ObExecContext &ctx,
|
||||
const int64_t table_id,
|
||||
ObIArray<ObAuxTableMetaInfo> &index_infos);
|
||||
static int get_table_index_infos(share::schema::ObSchemaGetterGuard *schema_guard,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t table_id,
|
||||
uint64_t *index_tid_arr,
|
||||
int64_t &index_count);
|
||||
|
||||
static int get_table_partition_infos(const ObTableSchema &table_schema,
|
||||
ObIAllocator &allocator,
|
||||
|
@ -315,14 +315,22 @@ int ObBasicStatsEstimator::do_estimate_block_count(ObExecContext &ctx,
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t retry_cnt = 0;
|
||||
const int64_t MAX_RETRY_CNT = 10;
|
||||
do {
|
||||
if (OB_FAIL(do_estimate_block_count_and_row_count(ctx, tenant_id, table_id, tablet_ids,
|
||||
partition_ids, column_group_ids, estimate_res))) {
|
||||
DAS_CTX(ctx).get_location_router().refresh_location_cache_by_errno(true, ret);
|
||||
++ retry_cnt;
|
||||
if (OB_FAIL(THIS_WORKER.check_status())) {
|
||||
LOG_WARN("failed to check status", K(ret));
|
||||
} else if (OB_FAIL(do_estimate_block_count_and_row_count(ctx, tenant_id, table_id, tablet_ids,
|
||||
partition_ids, column_group_ids, estimate_res))) {
|
||||
LOG_WARN("failed to do estimate block count and row count", K(ret));
|
||||
if (DAS_CTX(ctx).get_location_router().is_refresh_location_error(ret)) {
|
||||
DAS_CTX(ctx).get_location_router().refresh_location_cache_by_errno(true, ret);
|
||||
++ retry_cnt;
|
||||
ob_usleep(1000L * 1000L); // retry interval 1s
|
||||
} else {
|
||||
retry_cnt = MAX_RETRY_CNT;
|
||||
}
|
||||
}
|
||||
} while (OB_FAIL(ret) && retry_cnt < 2);//retry one time if failed to estimate.
|
||||
} while (OB_FAIL(ret) && retry_cnt < MAX_RETRY_CNT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1143,15 +1143,20 @@ OB_NOINLINE int ObDASLocationRouter::get_vt_ls_location(uint64_t table_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObDASLocationRouter::is_refresh_location_error(int err_no) const
|
||||
{
|
||||
return is_master_changed_error(err_no) ||
|
||||
is_partition_change_error(err_no) ||
|
||||
is_get_location_timeout_error(err_no) ||
|
||||
is_server_down_error(err_no) ||
|
||||
is_has_no_readable_replica_err(err_no) ||
|
||||
is_unit_migrate(err_no);
|
||||
}
|
||||
|
||||
void ObDASLocationRouter::refresh_location_cache_by_errno(bool is_nonblock, int err_no)
|
||||
{
|
||||
NG_TRACE_TIMES(1, get_location_cache_begin);
|
||||
if (is_master_changed_error(err_no)
|
||||
|| is_partition_change_error(err_no)
|
||||
|| is_get_location_timeout_error(err_no)
|
||||
|| is_server_down_error(err_no)
|
||||
|| is_has_no_readable_replica_err(err_no)
|
||||
|| is_unit_migrate(err_no)) {
|
||||
if (is_refresh_location_error(err_no)) {
|
||||
// Refresh tablet ls mapping and ls locations according to err_no.
|
||||
//
|
||||
// The timeout has been set inner the interface when renewing location synchronously.
|
||||
|
@ -331,6 +331,7 @@ public:
|
||||
}
|
||||
int save_success_task(const common::ObTabletID &succ_id)
|
||||
{ return succ_tablet_list_.push_back(succ_id); }
|
||||
bool is_refresh_location_error(int err_no) const;
|
||||
TO_STRING_KV(K(all_tablet_list_));
|
||||
private:
|
||||
int get_vt_svr_pair(uint64_t vt_id, const VirtualSvrPair *&vt_svr_pair);
|
||||
|
@ -65,13 +65,16 @@ int ObAccessPathEstimation::inner_estimate_rowcount(ObOptimizerContext &ctx,
|
||||
const bool is_inner_path,
|
||||
const ObIArray<ObRawExpr*> &filter_exprs,
|
||||
ObBaseTableEstMethod &method)
|
||||
{
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObBaseTableEstMethod valid_methods = 0;
|
||||
ObBaseTableEstMethod hint_specify_methods = 0;
|
||||
method = EST_INVALID;
|
||||
if (OB_FAIL(get_valid_est_methods(ctx, paths, filter_exprs, is_inner_path, valid_methods))) {
|
||||
if (OB_FAIL(get_valid_est_methods(ctx, paths, filter_exprs, is_inner_path, valid_methods, hint_specify_methods))) {
|
||||
LOG_WARN("failed to get valid est methods", K(ret));
|
||||
} else if (OB_FAIL(choose_best_est_method(ctx, paths, filter_exprs, valid_methods, method))) {
|
||||
} else if (OB_FAIL(choose_best_est_method(ctx, paths, filter_exprs,
|
||||
valid_methods & hint_specify_methods ? valid_methods & hint_specify_methods : valid_methods,
|
||||
method))) {
|
||||
LOG_WARN("failed to choose one est method", K(ret), K(valid_methods));
|
||||
} else if (OB_FAIL(do_estimate_rowcount(ctx, paths, is_inner_path, filter_exprs, valid_methods, method))) {
|
||||
LOG_WARN("failed to do estimate rowcount", K(ret), K(method), K(valid_methods));
|
||||
@ -146,12 +149,13 @@ int ObAccessPathEstimation::get_valid_est_methods(ObOptimizerContext &ctx,
|
||||
common::ObIArray<AccessPath*> &paths,
|
||||
const ObIArray<ObRawExpr*> &filter_exprs,
|
||||
bool is_inner_path,
|
||||
ObBaseTableEstMethod &valid_methods)
|
||||
ObBaseTableEstMethod &valid_methods,
|
||||
ObBaseTableEstMethod &hint_specify_methods)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
valid_methods = EST_DEFAULT | EST_STAT | EST_STORAGE | EST_DS_BASIC | EST_DS_FULL;
|
||||
hint_specify_methods = 0;
|
||||
const ObBaseTableEstMethod EST_DS_METHODS = EST_DS_BASIC | EST_DS_FULL;
|
||||
ObBaseTableEstMethod hint_specify_methods = 0;
|
||||
const ObLogPlan* log_plan = NULL;
|
||||
const OptTableMeta *table_meta = NULL;
|
||||
if (OB_UNLIKELY(paths.empty()) ||
|
||||
@ -218,13 +222,6 @@ int ObAccessPathEstimation::get_valid_est_methods(ObOptimizerContext &ctx,
|
||||
LOG_WARN("failed to check dynamic sampling", K(ret));
|
||||
}
|
||||
|
||||
// if there are any valid hint_specify_method, use it.
|
||||
if (OB_SUCC(ret)) {
|
||||
if (valid_methods & hint_specify_methods) {
|
||||
valid_methods &= hint_specify_methods;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,8 @@ private:
|
||||
common::ObIArray<AccessPath*> &paths,
|
||||
const ObIArray<ObRawExpr*> &filter_exprs,
|
||||
bool is_inner_path,
|
||||
ObBaseTableEstMethod &valid_methods);
|
||||
ObBaseTableEstMethod &valid_methods,
|
||||
ObBaseTableEstMethod &hint_specify_methods);
|
||||
|
||||
static int check_can_use_dynamic_sampling(ObOptimizerContext &ctx,
|
||||
const ObLogPlan &log_plan,
|
||||
|
Loading…
x
Reference in New Issue
Block a user