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)
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
......
......@@ -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
......@@ -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;
......
......@@ -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;
};
......
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