From d0f6fde3deb4752cd13fe2e8ac907477331da1f5 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Mon, 23 May 2011 23:46:51 +0100 Subject: [PATCH] BUG#12558519: RPL_TYPECONV PRODUCES VALGRIND STACK In RBR and in case of converting blob fields, the space allocated while unpacking into the conversion field was not freed after copying from it into the real field. We fix this by freeing the conversion field when the conversion table is not needed anymore (on close_tables_to_lock). --- sql/log_event.cc | 1 + sql/rpl_rli.cc | 10 ++++++++++ sql/table.cc | 10 +++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 39b4791ff3d..763bbf81a81 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8441,6 +8441,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) m_field_metadata, m_field_metadata_size, m_null_bits, m_flags); table_list->m_tabledef_valid= TRUE; + table_list->m_conv_table= NULL; table_list->open_type= OT_BASE_ONLY; /* diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index f2653894ea7..11c4924737d 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1254,6 +1254,16 @@ void Relay_log_info::clear_tables_to_lock() tables_to_lock->m_tabledef.table_def::~table_def(); tables_to_lock->m_tabledef_valid= FALSE; } + + /* + If blob fields were used during conversion of field values + from the master table into the slave table, then we need to + free the memory used temporarily to store their values before + copying into the slave's table. + */ + if (tables_to_lock->m_conv_table) + free_blobs(tables_to_lock->m_conv_table); + tables_to_lock= static_cast(tables_to_lock->next_global); tables_to_lock_count--; diff --git a/sql/table.cc b/sql/table.cc index 68e2566ffc1..8073120e530 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2188,7 +2188,15 @@ void free_blobs(register TABLE *table) for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ; ptr != end ; ptr++) - ((Field_blob*) table->field[*ptr])->free(); + { + /* + Reduced TABLE objects which are used by row-based replication for + type conversion might have some fields missing. Skip freeing BLOB + buffers for such missing fields. + */ + if (table->field[*ptr]) + ((Field_blob*) table->field[*ptr])->free(); + } }