Commit 62f82309 authored by mats@romeo.(none)'s avatar mats@romeo.(none)

BUG#26634 (Valgrind failure in tree: memory loss for memory allocated in rpl_utility.h):

Adding code to release allocated memory when tables_to_lock list is
cleared.
parent 959b8810
...@@ -5783,10 +5783,10 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) ...@@ -5783,10 +5783,10 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
need to add code to assert that is the case. need to add code to assert that is the case.
*/ */
thd->binlog_flush_pending_rows_event(false); thd->binlog_flush_pending_rows_event(false);
close_tables_for_reopen(thd, &rli->tables_to_lock); TABLE_LIST *tables= rli->tables_to_lock;
close_tables_for_reopen(thd, &tables);
if ((error= open_tables(thd, &rli->tables_to_lock, if ((error= open_tables(thd, &tables, &rli->tables_to_lock_count, 0)))
&rli->tables_to_lock_count, 0)))
{ {
if (thd->query_error || thd->is_fatal_error) if (thd->query_error || thd->is_fatal_error)
{ {
...@@ -5815,7 +5815,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) ...@@ -5815,7 +5815,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
*/ */
{ {
RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock); RPL_TABLE_LIST *ptr= rli->tables_to_lock;
for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global)) for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
{ {
if (ptr->m_tabledef.compatible_with(rli, ptr->table)) if (ptr->m_tabledef.compatible_with(rli, ptr->table))
...@@ -6396,9 +6396,15 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli) ...@@ -6396,9 +6396,15 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
/* /*
Use placement new to construct the table_def instance in the Use placement new to construct the table_def instance in the
memory allocated for it inside table_list. memory allocated for it inside table_list.
The memory allocated by the table_def structure (i.e., not the
memory allocated *for* the table_def structure) is released
inside st_relay_log_info::clear_tables_to_lock() by calling the
table_def destructor explicitly.
*/ */
const table_def *const def= const table_def *const def=
new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt); new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt);
table_list->m_tabledef_valid= TRUE;
/* /*
We record in the slave's information that the table should be We record in the slave's information that the table should be
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "rpl_rli.h" #include "rpl_rli.h"
#include <my_dir.h> // For MY_STAT #include <my_dir.h> // For MY_STAT
#include "sql_repl.h" // For check_binlog_magic #include "sql_repl.h" // For check_binlog_magic
#include "rpl_utility.h"
static int count_relay_log_space(RELAY_LOG_INFO* rli); static int count_relay_log_space(RELAY_LOG_INFO* rli);
...@@ -1108,4 +1109,23 @@ void st_relay_log_info::cleanup_context(THD *thd, bool error) ...@@ -1108,4 +1109,23 @@ void st_relay_log_info::cleanup_context(THD *thd, bool error)
unsafe_to_stop_at= 0; unsafe_to_stop_at= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void st_relay_log_info::clear_tables_to_lock()
{
while (tables_to_lock)
{
gptr to_free= reinterpret_cast<gptr>(tables_to_lock);
if (tables_to_lock->m_tabledef_valid)
{
tables_to_lock->m_tabledef.table_def::~table_def();
tables_to_lock->m_tabledef_valid= FALSE;
}
tables_to_lock=
static_cast<RPL_TABLE_LIST*>(tables_to_lock->next_global);
tables_to_lock_count--;
my_free(to_free, MYF(MY_WME));
}
DBUG_ASSERT(tables_to_lock == NULL && tables_to_lock_count == 0);
}
#endif #endif
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "rpl_tblmap.h" #include "rpl_tblmap.h"
struct RPL_TABLE_LIST;
/**************************************************************************** /****************************************************************************
...@@ -279,7 +281,7 @@ typedef struct st_relay_log_info ...@@ -279,7 +281,7 @@ typedef struct st_relay_log_info
group_relay_log_pos); group_relay_log_pos);
} }
TABLE_LIST *tables_to_lock; /* RBR: Tables to lock */ RPL_TABLE_LIST *tables_to_lock; /* RBR: Tables to lock */
uint tables_to_lock_count; /* RBR: Count of tables to lock */ uint tables_to_lock_count; /* RBR: Count of tables to lock */
table_mapping m_table_map; /* RBR: Mapping table-id to table */ table_mapping m_table_map; /* RBR: Mapping table-id to table */
...@@ -295,16 +297,7 @@ typedef struct st_relay_log_info ...@@ -295,16 +297,7 @@ typedef struct st_relay_log_info
void transaction_end(THD*); void transaction_end(THD*);
void cleanup_context(THD *, bool); void cleanup_context(THD *, bool);
void clear_tables_to_lock() { void clear_tables_to_lock();
while (tables_to_lock)
{
char *to_free= reinterpret_cast<gptr>(tables_to_lock);
tables_to_lock= tables_to_lock->next_global;
tables_to_lock_count--;
my_free(to_free, MYF(MY_WME));
}
DBUG_ASSERT(tables_to_lock == NULL && tables_to_lock_count == 0);
}
time_t unsafe_to_stop_at; time_t unsafe_to_stop_at;
} RELAY_LOG_INFO; } RELAY_LOG_INFO;
......
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
#include "mysql_priv.h" #include "mysql_priv.h"
struct st_relay_log_info;
typedef st_relay_log_info RELAY_LOG_INFO;
uint32 uint32
field_length_from_packed(enum_field_types field_type, byte const *data); field_length_from_packed(enum_field_types field_type, byte const *data);
...@@ -128,6 +131,7 @@ class table_def ...@@ -128,6 +131,7 @@ class table_def
struct RPL_TABLE_LIST struct RPL_TABLE_LIST
: public st_table_list : public st_table_list
{ {
bool m_tabledef_valid;
table_def m_tabledef; table_def m_tabledef;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment