forked from oceanbase/seekdb
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathob_analyze_executor.cpp
More file actions
158 lines (153 loc) · 7.94 KB
/
Copy pathob_analyze_executor.cpp
File metadata and controls
158 lines (153 loc) · 7.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* Copyright (c) 2025 OceanBase.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define USING_LOG_PREFIX SQL_ENG
#include "share/stat/ob_dbms_stats_executor.h"
#include "pl/sys_package/ob_dbms_stats.h"
#include "sql/engine/cmd/ob_analyze_executor.h"
#include "share/stat/ob_dbms_stats_lock_unlock.h"
#include "share/stat/ob_dbms_stats_utils.h"
#include "src/observer/virtual_table/ob_all_virtual_dml_stats.h"
//#define COMPUTE_FREQUENCY_HISTOGRAM
// "SELECT /*+NO_USE_PX*/ col, sum(val) over (order by col rows between unbounded preceding and current row) "
// "FROM (SELECT %.*s as col, count(*) as val FROM %s WHERE %.*s IS NOT NULL GROUP BY %.*s) temp;"
//
//#define COMPUTE_TOP_FREQUENCY_HISTOGRAM
// "SELECT /*+NO_USE_PX*/ col, sum(val) over (order by col rows between unbounded preceding and current row) "
// "FROM (SELECT * FROM (SELECT %.*s as col, count(*) as val FROM %s WHERE %.*s IS NOT NULL GROUP BY %.*s ORDER BY val LIMIT %ld) temp) temp2;"
//
//#define COMPUTE_HEIGHT_BASED_HISTOGRAM
// "SELECT /*+NO_USE_PX*/ endpoint_value, sum(endpoint_num) over (order by endpoint_value rows between unbounded preceding and current row) "
// "FROM (SELECT endpoint_value, count(*) as endpoint_num "
// "FROM (SELECT MAX(col) as endpoint_value "
// "FROM (SELECT %.*s as col, ntile(%ld) over (order by %.*s) as bucket FROM %s WHERE %.*s IS NOT NULL) temp GROUP BY bucket) temp2 group by endpoint_value) temp3;"
namespace oceanbase
{
using namespace common;
namespace sql
{
int ObAnalyzeExecutor::execute(ObExecContext &ctx, ObAnalyzeStmt &stmt)
{
int ret = OB_SUCCESS;
ObSEArray<ObTableStatParam,1> params;
ObSQLSessionInfo *session = ctx.get_my_session();
if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(session));
} else {
uint64_t tenant_id = session->get_effective_tenant_id();
bool is_primary = true;
if (OB_FAIL(ObShareUtil::mtl_check_if_tenant_role_is_primary(tenant_id, is_primary))) {
LOG_WARN("fail to execute mtl_check_if_tenant_role_is_primary", KR(ret), K(tenant_id));
} else if (OB_UNLIKELY(!is_primary)) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "analyze table during non-primary tenant");
}
}
if (FAILEDx(ObDbmsStatsUtils::implicit_commit_before_gather_stats(ctx))) {
LOG_WARN("failed to implicit commit before gather stats", K(ret));
} else if (OB_FAIL(ObDbmsStatsUtils::cancel_async_gather_stats(ctx))) {
LOG_WARN("failed to cancel async gather stats", K(ret));
} else if (OB_FAIL(stmt.fill_table_stat_params(ctx, params))) {
LOG_WARN("failed to fill table stat param", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < params.count(); ++i) {
if (OB_FAIL(pl::ObDbmsStats::process_not_size_manual_column(ctx, params.at(i)))) {
LOG_WARN("failed to process not size_manual column", K(ret));
}
}
if (OB_SUCC(ret)) {
if (stmt.is_delete_histogram()) {
bool cascade_columns = true;
bool cascade_indexes = true;
if (OB_UNLIKELY(params.count() != 1)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected error", K(ret), K(params));
} else {
ObArenaAllocator tmp_alloc("DeleteStats", OB_MALLOC_NORMAL_BLOCK_SIZE, params.at(0).tenant_id_);
params.at(0).allocator_ = &tmp_alloc;//use the temp allocator to free memory after delete stats.
if (OB_FAIL(ObDbmsStatsLockUnlock::check_stat_locked(ctx, params.at(0)))) {
LOG_WARN("failed to check stat locked", K(ret));
} else if (OB_FAIL(ObDbmsStatsExecutor::delete_table_stats(ctx, params.at(0), cascade_columns))) {
LOG_WARN("failed to delete table stats", K(ret));
} else if (OB_FAIL(pl::ObDbmsStats::update_stat_cache(session->get_rpc_tenant_id(), params.at(0)))) {
LOG_WARN("failed to update stat cache", K(ret));
} else if (cascade_indexes && params.at(0).part_name_.empty()) {
if (OB_FAIL(pl::ObDbmsStats::delete_table_index_stats(ctx, params.at(0)))) {
LOG_WARN("failed to delete index stats", K(ret));
} else {/*do nothing*/}
}
}
LOG_TRACE("succeed to drop table stats", K(params));
} else {
int64_t task_cnt = params.count();
int64_t start_time = ObTimeUtility::current_time();
ObOptStatTaskInfo task_info;
if (OB_FAIL(pl::ObDbmsStats::init_gather_task_info(ctx, ObOptStatGatherType::MANUAL_GATHER,
start_time, task_cnt, task_info))) {
LOG_WARN("failed to init gather task info", K(ret));
} else {
int64_t i = 0;
for (; OB_SUCC(ret) && i < params.count(); ++i) {
ObTableStatParam ¶m = params.at(i);
ObArenaAllocator tmp_alloc("OptStatGather", OB_MALLOC_NORMAL_BLOCK_SIZE, param.tenant_id_);
param.allocator_ = &tmp_alloc;//use the temp allocator to free memory after gather stats.
start_time = ObTimeUtility::current_time();
ObOptStatGatherStat gather_stat(task_info);
ObOptStatGatherStatList::instance().push(gather_stat);
ObOptStatGatherAudit audit(tmp_alloc);
ObOptStatRunningMonitor running_monitor(ctx.get_allocator(), start_time, param.allocator_->used(), gather_stat, audit);
if (OB_FAIL(running_monitor.add_monitor_info(ObOptStatRunningPhase::GATHER_PREPARE))) {
LOG_WARN("failed to add add monitor info", K(ret));
} else if (OB_FAIL(pl::ObDbmsStats::get_stats_consumer_group_id(param))) {
LOG_WARN("failed to get stats consumer gourp id");
} else if (OB_FAIL(running_monitor.add_table_info(param))) {
LOG_WARN("failed to add table info", K(ret));
} else if (OB_FAIL(ObDbmsStatsLockUnlock::check_stat_locked(ctx, param))) {
LOG_WARN("failed check stat locked", K(ret));
} else if (OB_FAIL(ObOptStatMonitorManager::flush_database_monitoring_info(ctx, false, true))) {
LOG_WARN("failed to do flush database monitoring info", K(ret));
} else if (OB_FAIL(ObDbmsStatsExecutor::gather_table_stats(ctx, param, running_monitor))) {
LOG_WARN("failed to gather table stats", K(ret));
} else if (OB_FAIL(pl::ObDbmsStats::update_stat_cache(session->get_rpc_tenant_id(), param))) {
LOG_WARN("failed to update stat cache", K(ret));
} else {
LOG_TRACE("succeed to gather table stats", K(param));
}
if (ret == OB_SUCCESS || ret == OB_TIMEOUT) {
int tmp_ret = ret;
if (OB_FAIL(running_monitor.flush_gather_audit())) {
LOG_WARN("failed to flush gather audit", K(ret));
} else {
ret = tmp_ret;
}
}
running_monitor.set_monitor_result(ret, ObTimeUtility::current_time(), param.allocator_->used());
pl::ObDbmsStats::update_optimizer_gather_stat_info(NULL, &gather_stat);
ObOptStatGatherStatList::instance().remove(gather_stat);
task_info.completed_table_count_ ++;
}
task_info.task_end_time_ = ObTimeUtility::current_time();
task_info.ret_code_ = ret;
task_info.failed_count_ = ret == OB_SUCCESS ? 0 : params.count() - i + 1;
pl::ObDbmsStats::update_optimizer_gather_stat_info(&task_info, NULL);
}
}
}
}
return ret;
}
} // end of SQL
} // end of OceanBase