Commit 236bb807 authored by unknown's avatar unknown
Browse files

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.


sql/log_event.cc:
  Using RPL_TABLE_LIST instead of TABLE_LIST for tables_to_lock.
sql/rpl_rli.cc:
  Moving st_relay_log_info::clear_tables_to_lock() into rpl_rli.cc.
  Adding code to release memory allocated for saved table definition.
sql/rpl_rli.h:
  Moving st_relay_log_info::clear_tables_to_lock() into rpl_rli.cc.
  Using RPL_TABLE_LIST instead of TABLE_LIST for tables_to_lock.
sql/rpl_utility.h:
  Adding forward declarations.
  Adding boolean to tell if tabledef is valid.
parent acc12007
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -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.
       */
      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,
                              &rli->tables_to_lock_count, 0)))
      if ((error= open_tables(thd, &tables, &rli->tables_to_lock_count, 0)))
      {
        if (thd->query_error || thd->is_fatal_error)
        {
@@ -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))
      {
        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)
    /*
      Use placement new to construct the table_def instance in the
      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=
      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
+20 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "rpl_rli.h"
#include <my_dir.h>    // For MY_STAT
#include "sql_repl.h"  // For check_binlog_magic
#include "rpl_utility.h"

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)
  unsafe_to_stop_at= 0;
  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
+4 −11
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@

#include "rpl_tblmap.h"

struct RPL_TABLE_LIST;


/****************************************************************************

@@ -279,7 +281,7 @@ typedef struct st_relay_log_info
	    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 */
  table_mapping m_table_map;      /* RBR: Mapping table-id to table */

@@ -295,16 +297,7 @@ typedef struct st_relay_log_info
  void transaction_end(THD*);

  void cleanup_context(THD *, bool);
  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);
  }
  void clear_tables_to_lock();

  time_t unsafe_to_stop_at;
} RELAY_LOG_INFO;
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@

#include "mysql_priv.h"

struct st_relay_log_info;
typedef st_relay_log_info RELAY_LOG_INFO;

uint32
field_length_from_packed(enum_field_types field_type, byte const *data);

@@ -128,6 +131,7 @@ class table_def
struct RPL_TABLE_LIST
  : public st_table_list
{
  bool m_tabledef_valid;
  table_def m_tabledef;
};