summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkatesh Duggirala <venkatesh.duggirala@oracle.com>2013-10-16 22:12:23 +0530
committerVenkatesh Duggirala <venkatesh.duggirala@oracle.com>2013-10-16 22:12:23 +0530
commit2b07397b2021ce598f0bde23a15b1e7983722463 (patch)
treeb40810a80db48979155fb203ca48ff577c304644
parentde0e8a02d18b4593e11b282b7c8641603b7cbfe9 (diff)
downloadmariadb-git-2b07397b2021ce598f0bde23a15b1e7983722463.tar.gz
Bug#17234370 LAST_INSERT_ID IS REPLICATED INCORRECTLY IF
REPLICATION FILTERS ARE USED. Problem: When Filtered-slave applies Int_var_log_event and when it tries to write the event to its own binlog, LAST_INSERT_ID value is written wrongly. Analysis: THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt is a variable which is set when LAST_INSERT_ID() is used by a statement. If it is set, first_successful_insert_id_in_ prev_stmt_for_binlog will be stored in the statement-based binlog. This variable is CUMULATIVE along the execution of a stored function or trigger: if one substatement sets it to 1 it will stay 1 until the function/trigger ends, thus making sure that first_successful_insert_id_in_ prev_stmt_for_binlog does not change anymore and is propagated to the caller for binlogging. This is achieved using the following code if(!stmt_depends_on_first_successful_insert_id_in_prev_stmt) { /* It's the first time we read it */ first_successful_insert_id_in_prev_stmt_for_binlog= first_successful_insert_id_in_prev_stmt; stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1; } Slave server, after receiving Int_var_log_event event from master, it is setting stmt_depends_on_first_successful_insert_id_in_prev_stmt to true(*which is wrong*) and not setting first_successful_insert_id_in_prev_stmt_for_binlog. Because of this problem, when the actual DML statement with LAST_INSERT_ID() is parsed by slave SQL thread, first_successful_insert_id_in_prev_stmt_for_binlog is not set. Hence the value zero (default value) is written to slave's binlog. Why only *Filtered slave* is effected when the code is in common place: ------------------------------------------------------- In Query_log_event::do_apply_event, THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt is reset to zero at the end of the function. In case of normal slave (No Filters), this variable will be reset. In Filtered slave, Slave SQL thread defers all IRU events's execution until IRU's Query_log event is received. Once it receives Query_log_event it executes all pending IRU events and then it executes Query_log_event. Hence the variable is not getting reset to 0, causing this bug. Fix: As described above, the root cause was setting THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt when Int_var_log_event was executed by a SQL thread. Hence removing the problematic line from the code.
-rw-r--r--sql/log_event.cc1
1 files changed, 0 insertions, 1 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index d7e912cfe1a..7a557c42154 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -5397,7 +5397,6 @@ int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
switch (type) {
case LAST_INSERT_ID_EVENT:
- thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
thd->first_successful_insert_id_in_prev_stmt= val;
break;
case INSERT_ID_EVENT: