diff --git a/sql/rpl_info_table.cc b/sql/rpl_info_table.cc index 204dd69..78cafde 100644 --- a/sql/rpl_info_table.cc +++ b/sql/rpl_info_table.cc @@ -22,6 +22,50 @@ #include "sql_class.h" // THD +class Thd_local_mem_root +{ + THD *m_thd; + MEM_ROOT *m_old_mem_root; + MEM_ROOT m_local_mem_root; + bool m_restored; + + Thd_local_mem_root(const Thd_local_mem_root&); + Thd_local_mem_root& operator=(const Thd_local_mem_root&); + +public: + + Thd_local_mem_root(THD *thd) : m_thd(thd), m_restored(false) + { + if (m_thd == current_thd) + { + m_old_mem_root= thd->mem_root; + init_sql_alloc(PSI_NOT_INSTRUMENTED, + &m_local_mem_root, + global_system_variables.query_alloc_block_size, + global_system_variables.query_prealloc_size); + m_thd->mem_root= &m_local_mem_root; + } + } + + ~Thd_local_mem_root() + { + if (!m_restored) + restore(); + } + + void restore() + { + if (m_thd == current_thd) + { + DBUG_ASSERT(m_thd->mem_root == &m_local_mem_root); + m_thd->mem_root= m_old_mem_root; + free_root(&m_local_mem_root, MYF(0)); + m_restored= true; + } + } + +}; + Rpl_info_table::Rpl_info_table(uint nparam, const char* param_schema, const char *param_table, @@ -95,6 +139,7 @@ int Rpl_info_table::do_init_info(enum_find_method method, uint instance) DBUG_ENTER("Rlp_info_table::do_init_info"); THD *thd= access->create_thd(); + Thd_local_mem_root local_mem_root(thd); saved_mode= thd->variables.sql_mode; tmp_disable_binlog(thd); @@ -147,6 +192,7 @@ end: access->close_table(thd, table, &backup, error); reenable_binlog(thd); thd->variables.sql_mode= saved_mode; + local_mem_root.restore(); access->drop_thd(thd); DBUG_RETURN(error); } @@ -166,6 +212,7 @@ int Rpl_info_table::do_flush_info(const bool force) DBUG_RETURN(0); THD *thd= access->create_thd(); + Thd_local_mem_root local_mem_root(thd); sync_counter= 0; saved_mode= thd->variables.sql_mode; @@ -258,6 +305,7 @@ end: thd->is_operating_substatement_implicitly= false; reenable_binlog(thd); thd->variables.sql_mode= saved_mode; + local_mem_root.restore(); access->drop_thd(thd); DBUG_RETURN(error); } @@ -278,6 +326,7 @@ int Rpl_info_table::do_clean_info() DBUG_ENTER("Rpl_info_table::do_remove_info"); THD *thd= access->create_thd(); + Thd_local_mem_root local_mem_root(thd); saved_mode= thd->variables.sql_mode; tmp_disable_binlog(thd); @@ -313,6 +362,7 @@ end: access->close_table(thd, table, &backup, error); reenable_binlog(thd); thd->variables.sql_mode= saved_mode; + local_mem_root.restore(); access->drop_thd(thd); DBUG_RETURN(error); } @@ -350,6 +400,7 @@ int Rpl_info_table::do_reset_info(uint nparam, DBUG_RETURN(1); thd= info->access->create_thd(); + Thd_local_mem_root local_mem_root(thd); saved_mode= thd->variables.sql_mode; tmp_disable_binlog(thd); @@ -426,6 +477,7 @@ end: info->access->close_table(thd, table, &backup, error); reenable_binlog(thd); thd->variables.sql_mode= saved_mode; + local_mem_root.restore(); info->access->drop_thd(thd); delete info; DBUG_RETURN(error); @@ -441,6 +493,7 @@ enum_return_check Rpl_info_table::do_check_info() DBUG_ENTER("Rpl_info_table::do_check_info"); THD *thd= access->create_thd(); + Thd_local_mem_root local_mem_root(thd); saved_mode= thd->variables.sql_mode; /* @@ -482,6 +535,7 @@ end: access->close_table(thd, table, &backup, return_check == ERROR_CHECKING_REPOSITORY); thd->variables.sql_mode= saved_mode; + local_mem_root.restore(); access->drop_thd(thd); DBUG_RETURN(return_check); } @@ -496,6 +550,7 @@ enum_return_check Rpl_info_table::do_check_info(uint instance) DBUG_ENTER("Rpl_info_table::do_check_info"); THD *thd= access->create_thd(); + Thd_local_mem_root local_mem_root(thd); saved_mode= thd->variables.sql_mode; /* @@ -543,6 +598,7 @@ end: access->close_table(thd, table, &backup, return_check == ERROR_CHECKING_REPOSITORY); thd->variables.sql_mode= saved_mode; + local_mem_root.restore(); access->drop_thd(thd); DBUG_RETURN(return_check); } @@ -565,6 +621,7 @@ bool Rpl_info_table::do_count_info(uint nparam, DBUG_RETURN(true); thd= info->access->create_thd(); + Thd_local_mem_root local_mem_root(thd); saved_mode= thd->variables.sql_mode; /* @@ -600,6 +657,7 @@ end: */ info->access->close_table(thd, table, &backup, error); thd->variables.sql_mode= saved_mode; + local_mem_root.restore(); info->access->drop_thd(thd); delete info; DBUG_RETURN(error); @@ -777,6 +835,7 @@ bool Rpl_info_table::do_update_is_transactional() }); THD *thd= access->create_thd(); + Thd_local_mem_root local_mem_root(thd); saved_mode= thd->variables.sql_mode; tmp_disable_binlog(thd); @@ -795,6 +854,7 @@ end: access->close_table(thd, table, &backup, 0); reenable_binlog(thd); thd->variables.sql_mode= saved_mode; + local_mem_root.restore(); access->drop_thd(thd); DBUG_RETURN(error); }