Commit 9eb64ec5 authored by Andrei Elkin's avatar Andrei Elkin

Bug#16541422 LOG-SLAVE-UPDATES + REPLICATE-WILD-IGNORE-TABLE FAILS FOR USER VARIABLES

At logging a first Query referring a user var, the slave missed to log the user var.
It appears that at execution of a Uservar event the slaver applier
thought of the variable as already logged.
The reason of misjudgement is in coincidence of query id:s: of one that the thread
holds at Uservar execution and another one that the thread sees at the Query applying.
While the two are naturally different in the regular execution branch (as two computational
events are separated as individual events), in the deferred applying case the User var execution
effectively belongs to its Query processing.

Fixed with storing the Uservar parsing time (where desicion to defer is taken) query id 
to temporarily substitute with it the actual query id at the Uservar execution time
(along with its query).
Such manipulation mimics behaviour of the regular applying branch.

sql/log_event.cc:
  Storing the Uservar parsing time query id into a new member of the event
  to to temporarily substitute
  with it the actual thread id at the Uservar execution time.
sql/log_event.h:
  Storage for keeping query-id in User-var intance is added.
parent 7a4c3615
...@@ -5721,7 +5721,7 @@ User_var_log_event(const char* buf, uint event_len, ...@@ -5721,7 +5721,7 @@ User_var_log_event(const char* buf, uint event_len,
const Format_description_log_event* description_event) const Format_description_log_event* description_event)
:Log_event(buf, description_event) :Log_event(buf, description_event)
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
, deferred(false) , deferred(false), query_id(0)
#endif #endif
{ {
bool error= false; bool error= false;
...@@ -5967,11 +5967,16 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -5967,11 +5967,16 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
{ {
Item *it= 0; Item *it= 0;
CHARSET_INFO *charset; CHARSET_INFO *charset;
query_id_t sav_query_id; /* memorize orig id when deferred applying */
if (rli->deferred_events_collecting) if (rli->deferred_events_collecting)
{ {
set_deferred(); set_deferred(current_thd->query_id);
return rli->deferred_events->add(this); return rli->deferred_events->add(this);
} else if (is_deferred())
{
sav_query_id= current_thd->query_id;
current_thd->query_id= query_id; /* recreating original time context */
} }
if (!(charset= get_charset(charset_number, MYF(MY_WME)))) if (!(charset= get_charset(charset_number, MYF(MY_WME))))
...@@ -6045,6 +6050,8 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -6045,6 +6050,8 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0); e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
if (!is_deferred()) if (!is_deferred())
free_root(thd->mem_root,0); free_root(thd->mem_root,0);
else
current_thd->query_id= sav_query_id; /* restore current query's context */
return 0; return 0;
} }
......
...@@ -2524,6 +2524,7 @@ public: ...@@ -2524,6 +2524,7 @@ public:
bool is_null; bool is_null;
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
bool deferred; bool deferred;
query_id_t query_id;
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg, User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
char *val_arg, ulong val_len_arg, Item_result type_arg, char *val_arg, ulong val_len_arg, Item_result type_arg,
uint charset_number_arg) uint charset_number_arg)
...@@ -2548,7 +2549,11 @@ public: ...@@ -2548,7 +2549,11 @@ public:
and which case the applier adjusts execution path. and which case the applier adjusts execution path.
*/ */
bool is_deferred() { return deferred; } bool is_deferred() { return deferred; }
void set_deferred() { deferred= true; } /*
In case of the deffered applying the variable instance is flagged
and the parsing time query id is stored to be used at applying time.
*/
void set_deferred(query_id_t qid) { deferred= true; query_id= qid; }
#endif #endif
bool is_valid() const { return name != 0; } bool is_valid() const { return name != 0; }
......
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