From 0a31d4f4116a55df18a6bb52c93a499360f03ac2 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Tue, 26 Mar 2013 19:24:01 +0200 Subject: [PATCH] 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 | 11 +++++++++-- sql/log_event.h | 7 ++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 7d2a80fdaf9..f962f897984 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5721,7 +5721,7 @@ User_var_log_event(const char* buf, uint event_len, const Format_description_log_event* description_event) :Log_event(buf, description_event) #ifndef MYSQL_CLIENT - , deferred(false) + , deferred(false), query_id(0) #endif { bool error= false; @@ -5967,11 +5967,16 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) { Item *it= 0; CHARSET_INFO *charset; + query_id_t sav_query_id; /* memorize orig id when deferred applying */ if (rli->deferred_events_collecting) { - set_deferred(); + set_deferred(current_thd->query_id); 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)))) @@ -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); if (!is_deferred()) free_root(thd->mem_root,0); + else + current_thd->query_id= sav_query_id; /* restore current query's context */ return 0; } diff --git a/sql/log_event.h b/sql/log_event.h index 63b31454011..5b22a1a324b 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -2524,6 +2524,7 @@ public: bool is_null; #ifndef MYSQL_CLIENT bool deferred; + query_id_t query_id; 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, uint charset_number_arg) @@ -2548,7 +2549,11 @@ public: and which case the applier adjusts execution path. */ 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 bool is_valid() const { return name != 0; }