diff --git a/sql/dd/impl/upgrade/server.cc b/sql/dd/impl/upgrade/server.cc index 93862cee886..9a60ff01376 100644 --- a/sql/dd/impl/upgrade/server.cc +++ b/sql/dd/impl/upgrade/server.cc @@ -600,6 +600,7 @@ static bool check_tables(THD *thd, std::unique_ptr &schema, dd::Table::DD_table::create_key_by_schema_id(schema->id())); auto process_table = [&](std::unique_ptr &table) { + thd->mem_root->ClearForReuse(); invalid_triggers(thd, schema->name().c_str(), *table); // Check for usage of prefix key index in PARTITION BY KEY() function. @@ -637,6 +638,7 @@ static bool check_events(THD *thd, std::unique_ptr &schema, dd::Event::DD_table::create_key_by_schema_id(schema->id())); auto process_event = [&](std::unique_ptr &event) { + thd->mem_root->ClearForReuse(); dd::String_type sql; if (build_event_sp(thd, event->name().c_str(), event->name().size(), event->definition().c_str(), event->definition().size(), @@ -657,6 +659,7 @@ static bool check_routines(THD *thd, std::unique_ptr &schema, dd::Routine::DD_table::create_key_by_schema_id(schema->id())); auto process_routine = [&](std::unique_ptr &routine) { + thd->mem_root->ClearForReuse(); if (invalid_routine(thd, *schema, *routine)) LogErr(ERROR_LEVEL, ER_UPGRADE_PARSE_ERROR, "Routine", schema->name().c_str(), routine->name().c_str(), @@ -674,6 +677,7 @@ static bool check_views(THD *thd, std::unique_ptr &schema, dd::View::DD_table::create_key_by_schema_id(schema->id())); auto process_view = [&](std::unique_ptr &view) { + thd->mem_root->ClearForReuse(); if (invalid_sql(thd, schema->name().c_str(), view->definition())) LogErr(ERROR_LEVEL, ER_UPGRADE_PARSE_ERROR, "View", schema->name().c_str(), view->name().c_str(), @@ -686,6 +690,28 @@ static bool check_views(THD *thd, std::unique_ptr &schema, } // namespace +/** + RAII class to temporarily replace the query_arena of THD. This ensures that + during specific operations(such as check_tables, check_events, check_routines, + and check_views), memory allocation does not lead to memory spikes or delayed + memory release issues. +*/ +class Query_arena_guard { + public: + Query_arena_guard(THD *thd) + : m_thd(thd), m_arena(&m_mem_root, Query_arena::STMT_REGULAR_EXECUTION) { + m_thd->swap_query_arena(m_arena, &m_backup_arena); + } + + ~Query_arena_guard() { m_thd->swap_query_arena(m_backup_arena, &m_arena); } + + private: + THD *m_thd; + MEM_ROOT m_mem_root; + Query_arena m_arena; + Query_arena m_backup_arena; +}; + /* This function runs checks on the database before running the upgrade to make sure that the database is ready to be upgraded to a newer version. New checks @@ -725,6 +751,7 @@ bool do_server_upgrade_checks(THD *thd) { Upgrade_error_counter error_count; Syntax_error_handler error_handler(&error_count); thd->push_internal_handler(&error_handler); + Query_arena_guard check_arena_guard(thd); auto process_schema = [&](std::unique_ptr &schema) { return check_tables(thd, schema, &shared_spaces, &error_count) ||