WL#7266: Dump-thread additional concurrency tests

Affects: Server-5.1   —   Status: Complete   —   Priority: Medium

Create MTR tests to verify dump-thread behaviour when present to:
 * binlog file rotates while dump thread is waiting on a hot log;
 * temporary read errors from current binlog.
This worklog aims at testing the two following scenarios:

1) Whenever the mysql_binlog_send method (dump thread)
reaches the end of file when reading events from the binlog, before
checking if it should wait for more events, there was a test to
check if the file being read was still active, i.e, it was the last
known binlog. However, it was possible that something was written to
the binary log and then a rotation would happen, after EOF was
detected and before the check for active was performed. In this
case, the end of the binary log would not be read by the dump
thread, and this would cause the slave to lose updates.

This test verifies that the problem has been fixed. It waits during this
window while forcing a rotation in the binlog.


2) Verify dump thread can send events in active file, correctly after
encountering an IO error.
SCENARIO 1
----------

Instrumentation
---------------
--- a/sql/sql_repl.cc
revid:harin.vadodaria@oracle.com-20130215070554-mgj5bqum8jja83aq
+++ b/sql/sql_repl.cc	
@@ -624,6 +627,13 @@ impossible position";
       error=LOG_READ_EOF;
     }
 
+    DBUG_EXECUTE_IF("wait_after_binlog_EOF",
+                    {
+                      const char act[]= "now wait_for signal.rotate_finished";
+                      DBUG_ASSERT(!debug_sync_set_action(current_thd,
+                                                         STRING_WITH_LEN(act)));
+                    };);
+

Test case
---------
--source include/have_debug.inc
--source include/master-slave.inc

--connection master

SET @debug_saved= @@GLOBAL.DEBUG;

CREATE TABLE t (i INT);

# When reaching the EOF the dump thread will wait before deciding if
# it should move to a new binlong file.
--eval SET GLOBAL DEBUG= "d,wait_after_binlog_EOF"

INSERT INTO t VALUES (1);

--sleep 1

# A insert and a rotate happens before the decision
INSERT INTO t VALUES (2);
FLUSH LOGS;

SET DEBUG_SYNC= 'now SIGNAL signal.rotate_finished';

--sync_slave_with_master

# All the rows should be sent to the slave.
--let $diff_tables=master:t,slave:t
--source include/diff_tables.inc

##Clean up
--connection master

SET @@GLOBAL.DEBUG= @debug_saved;
SET DEBUG_SYNC= 'RESET';

DROP TABLE t;
--source include/rpl_end.inc


SCENARIO 1
----------

Instrumentation
---------------
--- a/sql/log_event.cc
revid:venkata.sidagam@oracle.com-20130909150250-zaeypntgb6tegv3o
+++ b/sql/log_event.cc	
@@ -1027,6 +1027,17 @@ int Log_event::read_log_event(IO_CACHE*
   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);
+                    }
+                  });
+

Test case
---------
--source include/have_debug.inc
--source include/master-slave.inc

CALL mtr.add_suppression("Failed to read an event from active binlog.*");
SET @debug_saved= @@GLOBAL.DEBUG;

CREATE TABLE t1(c1 INT);
INSERT INTO t1 VALUES(1);

--sync_slave_with_master

--source include/rpl_connection_master.inc
SET GLOBAL debug='+d,dump_fake_io_error';
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);

--sync_slave_with_master
--let $diff_tables= master:t1, slave:t1
--source include/diff_tables.inc

--source include/rpl_connection_master.inc
SET @@GLOBAL.DEBUG= @debug_saved;
DROP TABLE t1;
--source include/rpl_end.inc