mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-35326: Memory Leak in init_io_cache_ext upon SHUTDOWN
The problems were that: 1) resources was freed "asimetric" normal execution in send_eof, in case of error in destructor. 2) destructor was not called in case of SP for result objects. (so if the last SP execution ended with error resorces was not freeded on reinit before execution (cleanup() called before next execution) and destructor also was not called due to lack of delete call for the object) Result cleanup() renamed to reset_for_next_ps_execution() to better reflect function(). All result method revised and freeing resources made "symetric". Destructor of result object called for SP. Added skipped invalidation in case of error in insert. Removed misleading naming of reset(thd) (could be mixed with with reset()).
This commit is contained in:
@ -3066,7 +3066,7 @@ void Item_change_list::rollback_item_tree_changes()
|
||||
** Functions to provide a interface to select results
|
||||
*****************************************************************************/
|
||||
|
||||
void select_result::cleanup()
|
||||
void select_result::reset_for_next_ps_execution()
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
@ -3135,6 +3135,7 @@ void select_send::abort_result_set()
|
||||
*/
|
||||
thd->spcont->end_partial_result_set= TRUE;
|
||||
}
|
||||
reset_for_next_ps_execution();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -3145,7 +3146,7 @@ void select_send::abort_result_set()
|
||||
stored procedure statement.
|
||||
*/
|
||||
|
||||
void select_send::cleanup()
|
||||
void select_send::reset_for_next_ps_execution()
|
||||
{
|
||||
is_result_set_started= FALSE;
|
||||
}
|
||||
@ -3183,7 +3184,7 @@ bool select_send::send_eof()
|
||||
if (unlikely(thd->is_error()))
|
||||
return TRUE;
|
||||
::my_eof(thd);
|
||||
is_result_set_started= 0;
|
||||
reset_for_next_ps_execution();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -3192,10 +3193,22 @@ bool select_send::send_eof()
|
||||
Handling writing to file
|
||||
************************************************************************/
|
||||
|
||||
bool select_to_file::free_recources()
|
||||
{
|
||||
if (file >= 0)
|
||||
{
|
||||
(void) end_io_cache(&cache);
|
||||
bool error= mysql_file_close(file, MYF(MY_WME));
|
||||
file= -1;
|
||||
return error;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool select_to_file::send_eof()
|
||||
{
|
||||
int error= MY_TEST(end_io_cache(&cache));
|
||||
if (unlikely(mysql_file_close(file, MYF(MY_WME))) ||
|
||||
int error= false;
|
||||
if (unlikely(free_recources()) ||
|
||||
unlikely(thd->is_error()))
|
||||
error= true;
|
||||
|
||||
@ -3203,20 +3216,19 @@ bool select_to_file::send_eof()
|
||||
{
|
||||
::my_ok(thd,row_count);
|
||||
}
|
||||
file= -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
void select_to_file::abort_result_set()
|
||||
{
|
||||
select_result_interceptor::abort_result_set();
|
||||
free_recources();
|
||||
}
|
||||
|
||||
void select_to_file::cleanup()
|
||||
void select_to_file::reset_for_next_ps_execution()
|
||||
{
|
||||
/* In case of error send_eof() may be not called: close the file here. */
|
||||
if (file >= 0)
|
||||
{
|
||||
(void) end_io_cache(&cache);
|
||||
mysql_file_close(file, MYF(0));
|
||||
file= -1;
|
||||
}
|
||||
free_recources();
|
||||
path[0]= '\0';
|
||||
row_count= 0;
|
||||
}
|
||||
@ -3224,12 +3236,8 @@ void select_to_file::cleanup()
|
||||
|
||||
select_to_file::~select_to_file()
|
||||
{
|
||||
if (file >= 0)
|
||||
{ // This only happens in case of error
|
||||
(void) end_io_cache(&cache);
|
||||
mysql_file_close(file, MYF(0));
|
||||
file= -1;
|
||||
}
|
||||
DBUG_ASSERT(file < 0);
|
||||
free_recources(); // just in case
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@ -3716,9 +3724,9 @@ int select_singlerow_subselect::send_data(List<Item> &items)
|
||||
}
|
||||
|
||||
|
||||
void select_max_min_finder_subselect::cleanup()
|
||||
void select_max_min_finder_subselect::reset_for_next_ps_execution()
|
||||
{
|
||||
DBUG_ENTER("select_max_min_finder_subselect::cleanup");
|
||||
DBUG_ENTER("select_max_min_finder_subselect::reset_for_next_ps_execution");
|
||||
cache= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -3943,7 +3951,7 @@ bool select_dumpvar::check_simple_select() const
|
||||
}
|
||||
|
||||
|
||||
void select_dumpvar::cleanup()
|
||||
void select_dumpvar::reset_for_next_ps_execution()
|
||||
{
|
||||
row_count= 0;
|
||||
}
|
||||
@ -4372,10 +4380,10 @@ void select_materialize_with_stats::reset()
|
||||
}
|
||||
|
||||
|
||||
void select_materialize_with_stats::cleanup()
|
||||
void select_materialize_with_stats::reset_for_next_ps_execution()
|
||||
{
|
||||
reset();
|
||||
select_unit::cleanup();
|
||||
select_unit::reset_for_next_ps_execution();
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user