Commit 8d154f7a authored by Andrei Elkin's avatar Andrei Elkin

Bug#13437900 - VALGRIND REPORTS A LEAK FOR REPL_IGNORE_SERVER_IDS

There was memory leak when running some tests on PB2.
The reason of the failure is an early return from change_master()
that was supposed to deallocate a dyn-array.

Fixed with relocating the dyn-array's destructor at ~LEX() that is
the end of the session, per Gleb's patch idea.
Two optimizations were done: the static buffer for the dyn-array to base on,
and the array initialization is called precisely when it's necessary rather than
per each CHANGE-MASTER as before.
 

mysql-test/suite/rpl/t/rpl_empty_master_host.test:
  the test is binlog-format insensitive so it will be run with MIXED mode only.
sql/sql_lex.cc:
  the new flag is initialized.
sql/sql_lex.h:
  A new bool flag new member to LEX.mi is added to stay UP since after
  LEX.mi.repl_ignore_server_ids dynarray initialization was called
  for the first time on the session. So it is set once and its life time 
  is session.
  
  The array is destroyed at the end of the session.
sql/sql_repl.cc:
  dyn-array destruction is relocated to ~LEX.
sql/sql_yacc.yy:
  Refining logics of Lex->mi.repl_ignore_server_ids initialization.
  The array is initialized once a corresponding option in CHANGE MASTER token sequence
  is found.
  The fact of initialization is memorized into the new flag.
parent 2d6753c8
......@@ -17,6 +17,7 @@
# working when expected.
--source include/master-slave.inc
--source include/have_binlog_format_mixed.inc
connection slave;
STOP SLAVE;
......
......@@ -2352,6 +2352,7 @@ LEX::LEX()
INITIAL_LEX_PLUGIN_LIST_SIZE,
INITIAL_LEX_PLUGIN_LIST_SIZE);
reset_query_tables_list(TRUE);
repl_ignore_server_ids_inited= false;
}
......
......@@ -291,7 +291,9 @@ typedef struct st_lex_master_info
char *ssl_key, *ssl_cert, *ssl_ca, *ssl_capath, *ssl_cipher;
char *relay_log_name;
ulong relay_log_pos;
bool repl_ignore_server_ids_inited;
DYNAMIC_ARRAY repl_ignore_server_ids;
typeof(::server_id) repl_ignore_server_ids_static_buffer[4];
} LEX_MASTER_INFO;
typedef struct st_lex_reset_slave
......@@ -2455,6 +2457,11 @@ struct LEX: public Query_tables_list
destroy_query_tables_list();
plugin_unlock_list(NULL, (plugin_ref *)plugins.buffer, plugins.elements);
delete_dynamic(&plugins);
if (mi.repl_ignore_server_ids_inited)
{
delete_dynamic(&mi.repl_ignore_server_ids);
mi.repl_ignore_server_ids_inited= false;
}
}
inline bool is_ps_or_view_context_analysis()
......
......@@ -1689,7 +1689,6 @@ bool change_master(THD* thd, Master_info* mi)
thd_proc_info(thd, 0);
if (ret == FALSE)
my_ok(thd);
delete_dynamic(&lex_mi->repl_ignore_server_ids); //freeing of parser-time alloc
DBUG_RETURN(ret);
}
......
......@@ -1863,12 +1863,7 @@ change:
LEX *lex = Lex;
lex->sql_command = SQLCOM_CHANGE_MASTER;
bzero((char*) &lex->mi, sizeof(lex->mi));
/*
resetting flags that can left from the previous CHANGE MASTER
*/
lex->mi.repl_ignore_server_ids_opt= LEX_MASTER_INFO::LEX_MI_UNCHANGED;
my_init_dynamic_array(&Lex->mi.repl_ignore_server_ids,
sizeof(::server_id), 16, 16);
}
master_defs
{}
......@@ -1979,6 +1974,15 @@ ignore_server_id_list:
ignore_server_id:
ulong_num
{
if (!Lex->mi.repl_ignore_server_ids_inited)
{
my_init_dynamic_array2(&Lex->mi.repl_ignore_server_ids,
sizeof(::server_id),
Lex->mi.repl_ignore_server_ids_static_buffer,
array_elements(Lex->mi.repl_ignore_server_ids_static_buffer),
16);
Lex->mi.repl_ignore_server_ids_inited= true;
}
insert_dynamic(&Lex->mi.repl_ignore_server_ids, (uchar*) &($1));
}
......
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