Commit 221890f8 authored by unknown's avatar unknown
Browse files

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
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -5350,6 +5350,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
        slave_print_msg(ERROR_LEVEL, rli, error,
                        "Error in %s event: when locking tables",
                        get_type_str());
        rli->clear_tables_to_lock();
        DBUG_RETURN(error);
      }

@@ -5385,6 +5386,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
                           "unexpected success or fatal error"));
          thd->query_error= 1;
        }
        rli->clear_tables_to_lock();
        DBUG_RETURN(error);
      }
    }
@@ -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.
     */
    
    TABLE_LIST *ptr= rli->tables_to_lock;
    while (ptr)
    TABLE_LIST *ptr;
    for (ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
    {
      rli->m_table_map.set_table(ptr->table_id, ptr->table);
      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->tables_to_lock_count= 0;
    rli->clear_tables_to_lock();
  }

  DBUG_ASSERT(rli->tables_to_lock == NULL && rli->tables_to_lock_count == 0);

  TABLE* table= rli->m_table_map.get_table(m_table_id);

  if (table)
@@ -5816,12 +5816,8 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
                    &tname_mem, NAME_LEN + 1,
                    NULL);

  /*
    If memory is allocated, it the pointer to it should be stored in
    table_list.  If this is not true, the memory will not be correctly
    free:ed later.
  */
  DBUG_ASSERT(memory == NULL || memory == table_list);
  if (memory == NULL)
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);

  uint32 dummy_len;
  bzero(table_list, sizeof(*table_list));
@@ -5836,8 +5832,12 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)

  int error= 0;

  if (rpl_filter->db_ok(table_list->db) &&
      (!rpl_filter->is_on() || rpl_filter->tables_ok("", table_list)))
  if (!rpl_filter->db_ok(table_list->db) ||
      (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
+5 −6
Original line number Diff line number Diff line
@@ -309,15 +309,14 @@ typedef struct st_relay_log_info

  void cleanup_context(THD *, bool);
  void clear_tables_to_lock() {
    TABLE_LIST *ptr= tables_to_lock;
    while (ptr)
    while (tables_to_lock)
    {
      char *to_free= reinterpret_cast<char*>(ptr);
      ptr= ptr->next_global;
      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));
    }
    tables_to_lock= 0;
    tables_to_lock_count= 0;
    DBUG_ASSERT(tables_to_lock == NULL && tables_to_lock_count == 0);
  }

  time_t unsafe_to_stop_at;