Commit 221890f8 authored by unknown's avatar unknown

Plugging memory leak in row-based replication triggered by

test rpl_err_ignoredtables.


sql/log_event.cc:
  Clearing tables to lock list in the event of errors.
  Adding asserts to catch failing to clear the list of tables to lock.
  Releasing allocated memory if the table will not be replicated.
sql/rpl_rli.h:
  Adding assert to ensure post-condition of clear_tables_to_lock().
  Minor rewrites.
parent 94c6f6dc
...@@ -5350,6 +5350,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) ...@@ -5350,6 +5350,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
slave_print_msg(ERROR_LEVEL, rli, error, slave_print_msg(ERROR_LEVEL, rli, error,
"Error in %s event: when locking tables", "Error in %s event: when locking tables",
get_type_str()); get_type_str());
rli->clear_tables_to_lock();
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -5385,6 +5386,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) ...@@ -5385,6 +5386,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
"unexpected success or fatal error")); "unexpected success or fatal error"));
thd->query_error= 1; thd->query_error= 1;
} }
rli->clear_tables_to_lock();
DBUG_RETURN(error); DBUG_RETURN(error);
} }
} }
...@@ -5393,19 +5395,17 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) ...@@ -5393,19 +5395,17 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
the table map and remove them from tables to lock. the table map and remove them from tables to lock.
*/ */
TABLE_LIST *ptr= rli->tables_to_lock; TABLE_LIST *ptr;
while (ptr) for (ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
{ {
rli->m_table_map.set_table(ptr->table_id, ptr->table); rli->m_table_map.set_table(ptr->table_id, ptr->table);
rli->touching_table(ptr->db, ptr->table_name, ptr->table_id); rli->touching_table(ptr->db, ptr->table_name, ptr->table_id);
char *to_free= reinterpret_cast<char*>(ptr);
ptr= ptr->next_global;
my_free(to_free, MYF(MY_WME));
} }
rli->tables_to_lock= 0; rli->clear_tables_to_lock();
rli->tables_to_lock_count= 0;
} }
DBUG_ASSERT(rli->tables_to_lock == NULL && rli->tables_to_lock_count == 0);
TABLE* table= rli->m_table_map.get_table(m_table_id); TABLE* table= rli->m_table_map.get_table(m_table_id);
if (table) if (table)
...@@ -5816,12 +5816,8 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli) ...@@ -5816,12 +5816,8 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
&tname_mem, NAME_LEN + 1, &tname_mem, NAME_LEN + 1,
NULL); NULL);
/* if (memory == NULL)
If memory is allocated, it the pointer to it should be stored in DBUG_RETURN(HA_ERR_OUT_OF_MEM);
table_list. If this is not true, the memory will not be correctly
free:ed later.
*/
DBUG_ASSERT(memory == NULL || memory == table_list);
uint32 dummy_len; uint32 dummy_len;
bzero(table_list, sizeof(*table_list)); bzero(table_list, sizeof(*table_list));
...@@ -5836,8 +5832,12 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli) ...@@ -5836,8 +5832,12 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
int error= 0; int error= 0;
if (rpl_filter->db_ok(table_list->db) && if (!rpl_filter->db_ok(table_list->db) ||
(!rpl_filter->is_on() || rpl_filter->tables_ok("", table_list))) (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
{
my_free((gptr) memory, MYF(MY_WME));
}
else
{ {
/* /*
Check if the slave is set to use SBR. If so, it should switch Check if the slave is set to use SBR. If so, it should switch
......
...@@ -309,15 +309,14 @@ typedef struct st_relay_log_info ...@@ -309,15 +309,14 @@ typedef struct st_relay_log_info
void cleanup_context(THD *, bool); void cleanup_context(THD *, bool);
void clear_tables_to_lock() { void clear_tables_to_lock() {
TABLE_LIST *ptr= tables_to_lock; while (tables_to_lock)
while (ptr)
{ {
char *to_free= reinterpret_cast<char*>(ptr); char *to_free= reinterpret_cast<gptr>(tables_to_lock);
ptr= ptr->next_global; tables_to_lock= tables_to_lock->next_global;
tables_to_lock_count--;
my_free(to_free, MYF(MY_WME)); my_free(to_free, MYF(MY_WME));
} }
tables_to_lock= 0; DBUG_ASSERT(tables_to_lock == NULL && tables_to_lock_count == 0);
tables_to_lock_count= 0;
} }
time_t unsafe_to_stop_at; time_t unsafe_to_stop_at;
......
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