fix information_schema.columns memory dynamic leak when resolving views
This commit is contained in:
@ -46,7 +46,8 @@ ObInfoSchemaColumnsTable::ObInfoSchemaColumnsTable() :
|
|||||||
last_filter_column_idx_(-1),
|
last_filter_column_idx_(-1),
|
||||||
database_schema_array_(),
|
database_schema_array_(),
|
||||||
filter_table_schema_array_(),
|
filter_table_schema_array_(),
|
||||||
view_resolve_alloc_()
|
mem_context_(nullptr),
|
||||||
|
iter_cnt_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +60,11 @@ void ObInfoSchemaColumnsTable::reset()
|
|||||||
{
|
{
|
||||||
ObVirtualTableScannerIterator::reset();
|
ObVirtualTableScannerIterator::reset();
|
||||||
tenant_id_ = OB_INVALID_ID;
|
tenant_id_ = OB_INVALID_ID;
|
||||||
view_resolve_alloc_.reset();
|
if (OB_LIKELY(NULL != mem_context_)) {
|
||||||
|
DESTROY_CONTEXT(mem_context_);
|
||||||
|
mem_context_ = NULL;
|
||||||
|
}
|
||||||
|
iter_cnt_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObInfoSchemaColumnsTable::inner_get_next_row(common::ObNewRow *&row)
|
int ObInfoSchemaColumnsTable::inner_get_next_row(common::ObNewRow *&row)
|
||||||
@ -72,6 +77,8 @@ int ObInfoSchemaColumnsTable::inner_get_next_row(common::ObNewRow *&row)
|
|||||||
} else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id_)) {
|
} else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id_)) {
|
||||||
ret = OB_NOT_INIT;
|
ret = OB_NOT_INIT;
|
||||||
SERVER_LOG(WARN, "tenant id is invalid_id", K(ret), K(tenant_id_));
|
SERVER_LOG(WARN, "tenant id is invalid_id", K(ret), K(tenant_id_));
|
||||||
|
} else if (OB_FAIL(init_mem_context())) {
|
||||||
|
SERVER_LOG(WARN, "failed to init mem context", K(ret));
|
||||||
} else {
|
} else {
|
||||||
if (!start_to_read_) {
|
if (!start_to_read_) {
|
||||||
void *tmp_ptr = NULL;
|
void *tmp_ptr = NULL;
|
||||||
@ -204,7 +211,10 @@ int ObInfoSchemaColumnsTable::iterate_table_schema_array(const bool is_filter_ta
|
|||||||
} else {
|
} else {
|
||||||
table_schema = table_schema_array.at(i);
|
table_schema = table_schema_array.at(i);
|
||||||
}
|
}
|
||||||
if (OB_ISNULL(table_schema)) {
|
++iter_cnt_;
|
||||||
|
if (0 == ++iter_cnt_ % 1024 && OB_FAIL(THIS_WORKER.check_status())) {
|
||||||
|
SERVER_LOG(WARN, "failed to check status", K(ret));
|
||||||
|
} else if (OB_ISNULL(table_schema)) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
SERVER_LOG(WARN, "table_schema should not be NULL", K(ret));
|
SERVER_LOG(WARN, "table_schema should not be NULL", K(ret));
|
||||||
} else {
|
} else {
|
||||||
@ -226,22 +236,23 @@ int ObInfoSchemaColumnsTable::iterate_table_schema_array(const bool is_filter_ta
|
|||||||
bool view_is_invalid = (0 == table_schema->get_object_status() || 0 == table_schema->get_column_count());
|
bool view_is_invalid = (0 == table_schema->get_object_status() || 0 == table_schema->get_column_count());
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
} else if (is_normal_view && view_is_invalid) {
|
} else if (is_normal_view && view_is_invalid) {
|
||||||
view_resolve_alloc_.reset_remain_one_page();
|
mem_context_->reset_remain_one_page();
|
||||||
|
WITH_CONTEXT(mem_context_) {
|
||||||
ObString view_definition;
|
ObString view_definition;
|
||||||
sql::ObSelectStmt *select_stmt = NULL;
|
sql::ObSelectStmt *select_stmt = NULL;
|
||||||
sql::ObSelectStmt *real_stmt = NULL;
|
sql::ObSelectStmt *real_stmt = NULL;
|
||||||
ObStmtFactory stmt_factory(view_resolve_alloc_);
|
ObStmtFactory stmt_factory(mem_context_->get_arena_allocator());
|
||||||
ObRawExprFactory expr_factory(view_resolve_alloc_);
|
ObRawExprFactory expr_factory(mem_context_->get_arena_allocator());
|
||||||
if (OB_FAIL(ObSQLUtils::generate_view_definition_for_resolve(
|
if (OB_FAIL(ObSQLUtils::generate_view_definition_for_resolve(
|
||||||
view_resolve_alloc_,
|
mem_context_->get_arena_allocator(),
|
||||||
session_->get_local_collation_connection(),
|
session_->get_local_collation_connection(),
|
||||||
table_schema->get_view_schema(),
|
table_schema->get_view_schema(),
|
||||||
view_definition))) {
|
view_definition))) {
|
||||||
SERVER_LOG(WARN, "fail to generate view definition for resolve", K(ret));
|
SERVER_LOG(WARN, "fail to generate view definition for resolve", K(ret));
|
||||||
} else if (OB_FAIL(ObTableColumns::resolve_view_definition(&view_resolve_alloc_, session_, schema_guard_,
|
} else if (OB_FAIL(ObTableColumns::resolve_view_definition(&mem_context_->get_arena_allocator(), session_, schema_guard_,
|
||||||
*table_schema, select_stmt, expr_factory, stmt_factory, false))) {
|
*table_schema, select_stmt, expr_factory, stmt_factory, false))) {
|
||||||
if (OB_ERR_UNKNOWN_TABLE != ret && OB_ERR_VIEW_INVALID != ret) {
|
if (OB_ERR_UNKNOWN_TABLE != ret && OB_ERR_VIEW_INVALID != ret) {
|
||||||
SERVER_LOG(WARN, "failed to resolve view definition", K(view_definition), K(ret), K(table_schema->get_table_id()));
|
SERVER_LOG(WARN, "failed to resolve view definition", K(view_definition), K(ret), K(table_schema->get_table_id()), K(mem_context_->used()));
|
||||||
} else {
|
} else {
|
||||||
ret = OB_SUCCESS;
|
ret = OB_SUCCESS;
|
||||||
continue;
|
continue;
|
||||||
@ -270,6 +281,7 @@ int ObInfoSchemaColumnsTable::iterate_table_schema_array(const bool is_filter_ta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (OB_FAIL(iterate_column_schema_array(database_schema->get_database_name_str(),
|
} else if (OB_FAIL(iterate_column_schema_array(database_schema->get_database_name_str(),
|
||||||
*table_schema,
|
*table_schema,
|
||||||
last_db_schema_idx,
|
last_db_schema_idx,
|
||||||
@ -1152,5 +1164,21 @@ int ObInfoSchemaColumnsTable::fill_row_cells(const common::ObString &database_na
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int ObInfoSchemaColumnsTable::init_mem_context()
|
||||||
|
{
|
||||||
|
int ret = common::OB_SUCCESS;
|
||||||
|
if (OB_LIKELY(NULL == mem_context_)) {
|
||||||
|
lib::ContextParam param;
|
||||||
|
param.set_properties(lib::USE_TL_PAGE_OPTIONAL)
|
||||||
|
.set_mem_attr(tenant_id_, ObModIds::OB_SQL_EXECUTOR, ObCtxIds::DEFAULT_CTX_ID);
|
||||||
|
if (OB_FAIL(CURRENT_CONTEXT->CREATE_CONTEXT(mem_context_, param))) {
|
||||||
|
SQL_ENG_LOG(WARN, "create entity failed", K(ret));
|
||||||
|
} else if (OB_ISNULL(mem_context_)) {
|
||||||
|
SQL_ENG_LOG(WARN, "mem entity is null", K(ret));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace observer
|
} // namespace observer
|
||||||
} // namespace oceanbase
|
} // namespace oceanbase
|
||||||
|
|||||||
@ -115,6 +115,7 @@ private:
|
|||||||
char* buf,
|
char* buf,
|
||||||
const int64_t buf_len,
|
const int64_t buf_len,
|
||||||
int64_t &pos);
|
int64_t &pos);
|
||||||
|
inline int init_mem_context();
|
||||||
private:
|
private:
|
||||||
uint64_t tenant_id_;
|
uint64_t tenant_id_;
|
||||||
int64_t last_schema_idx_;
|
int64_t last_schema_idx_;
|
||||||
@ -130,6 +131,8 @@ private:
|
|||||||
common::ObSEArray<const share::schema::ObDatabaseSchema *, 8> database_schema_array_;
|
common::ObSEArray<const share::schema::ObDatabaseSchema *, 8> database_schema_array_;
|
||||||
common::ObSEArray<const share::schema::ObTableSchema *, 16> filter_table_schema_array_;
|
common::ObSEArray<const share::schema::ObTableSchema *, 16> filter_table_schema_array_;
|
||||||
ObArenaAllocator view_resolve_alloc_;
|
ObArenaAllocator view_resolve_alloc_;
|
||||||
|
lib::MemoryContext mem_context_;
|
||||||
|
int64_t iter_cnt_;
|
||||||
};
|
};
|
||||||
} // namespace observer
|
} // namespace observer
|
||||||
} // namespace oceanbase
|
} // namespace oceanbase
|
||||||
|
|||||||
@ -927,7 +927,11 @@ int ObTableColumns::resolve_view_definition(
|
|||||||
K(select_stmt_node->type_));
|
K(select_stmt_node->type_));
|
||||||
} else if (OB_FAIL(select_resolver.resolve(*select_stmt_node))) {
|
} else if (OB_FAIL(select_resolver.resolve(*select_stmt_node))) {
|
||||||
LOG_WARN("resolve view definition failed", K(ret));
|
LOG_WARN("resolve view definition failed", K(ret));
|
||||||
|
if (OB_ALLOCATE_MEMORY_FAILED != ret) {
|
||||||
ret = OB_ERR_VIEW_INVALID;
|
ret = OB_ERR_VIEW_INVALID;
|
||||||
|
} else {
|
||||||
|
LOG_WARN("failed to resolve view", K(ret));
|
||||||
|
}
|
||||||
if (throw_error) {
|
if (throw_error) {
|
||||||
LOG_USER_ERROR(OB_ERR_VIEW_INVALID, db_name.length(), db_name.ptr(),
|
LOG_USER_ERROR(OB_ERR_VIEW_INVALID, db_name.length(), db_name.ptr(),
|
||||||
table_name.length(), table_name.ptr());
|
table_name.length(), table_name.ptr());
|
||||||
|
|||||||
@ -1129,10 +1129,12 @@ int ObReferenceObjTable::process_reference_obj_table(const uint64_t tenant_id,
|
|||||||
OZ (task_queue.erase_view_id_from_set(dep_obj_id));
|
OZ (task_queue.erase_view_id_from_set(dep_obj_id));
|
||||||
}
|
}
|
||||||
} else if (OB_FAIL(task_queue.push(task))) {
|
} else if (OB_FAIL(task_queue.push(task))) {
|
||||||
|
if (OB_UNLIKELY(OB_SIZE_OVERFLOW != ret)) {
|
||||||
LOG_WARN("push task failed", K(ret));
|
LOG_WARN("push task failed", K(ret));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OB_FAIL(ret) && OB_INVALID_ID != dep_obj_id) {
|
if (OB_FAIL(ret) && OB_INVALID_ID != dep_obj_id) {
|
||||||
int tmp_ret = OB_SUCCESS;
|
int tmp_ret = OB_SUCCESS;
|
||||||
if (OB_SUCCESS != (tmp_ret = task_queue.erase_view_id_from_set(dep_obj_id))) {
|
if (OB_SUCCESS != (tmp_ret = task_queue.erase_view_id_from_set(dep_obj_id))) {
|
||||||
|
|||||||
@ -266,7 +266,7 @@ void ObMaintainDepInfoTaskQueue::run2()
|
|||||||
task->set_retry_times(task->get_retry_times() - 1);
|
task->set_retry_times(task->get_retry_times() - 1);
|
||||||
task->set_last_execute_time(ObTimeUtility::current_time());
|
task->set_last_execute_time(ObTimeUtility::current_time());
|
||||||
if (OB_FAIL(queue_.push(task))) {
|
if (OB_FAIL(queue_.push(task))) {
|
||||||
LOG_ERROR("push task to queue failed", K(ret));
|
LOG_WARN("push task to queue failed", K(ret));
|
||||||
} else {
|
} else {
|
||||||
rescheduled = true;
|
rescheduled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user