From 514b8261b5404c0b4fecbd66fc6fa99ca1bd8c47 Mon Sep 17 00:00:00 2001
From: Libing Song <libing.song@oracle.com>
Date: Tue, 10 Sep 2013 09:35:49 +0800
Subject: Bug#17402313 DUMP THREAD SENDS SOME EVENTS MORE THAN ONCE

Dump thread may encounter an error when reading events from the active binlog
file. However the errors may be temporary, so dump thread will try to read
the event again. But dump thread seeked to an wrong position, it caused some
events was sent twice.

To fix the bug, prev_pos is defined out the while loop and is set the correct
position after reading every event correctly.

This patch also make binlog_can_be_corrupted more accurate, only the binlogs
not closed normally are marked binlog_can_be_corrupted.

Finally, two warnings are added when dump threads encounter the temporary
errors.
---
 sql/log_event.cc | 11 +++++++++++
 1 file changed, 11 insertions(+)

(limited to 'sql/log_event.cc')

diff --git a/sql/log_event.cc b/sql/log_event.cc
index 16388fbbef7..d7e912cfe1a 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1027,6 +1027,17 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
   if (log_file_name_arg)
     *is_binlog_active= mysql_bin_log.is_active(log_file_name_arg);
 
+  DBUG_EXECUTE_IF("dump_fake_io_error",
+                  {
+                    if (log_lock)
+                    {
+                      pthread_mutex_unlock(log_lock);
+
+                      DBUG_SET("-d,dump_fake_io_error");
+                      DBUG_RETURN(LOG_READ_IO);
+                    }
+                  });
+
   if (my_b_read(file, (uchar*) buf, sizeof(buf)))
   {
     /*
-- 
cgit v1.2.1


From 2b07397b2021ce598f0bde23a15b1e7983722463 Mon Sep 17 00:00:00 2001
From: Venkatesh Duggirala <venkatesh.duggirala@oracle.com>
Date: Wed, 16 Oct 2013 22:12:23 +0530
Subject: 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.
---
 sql/log_event.cc | 1 -
 1 file changed, 1 deletion(-)

(limited to 'sql/log_event.cc')

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:
-- 
cgit v1.2.1