Commit c78680b4 authored by unknown's avatar unknown

Fix for a rpl_relayrotate failure.

Changed Rotate_log_event::exec_event() to not increment positions when the
event is seen in the middle of a transaction.


mysql-test/r/rpl_relayrotate.result:
  remove timeout which was too short for Valgrind
mysql-test/r/rpl_until.result:
  updated error message
mysql-test/t/rpl_relayrotate.test:
  removed timeout which was too short for Valgrind
sql/log_event.cc:
  Fix for a rpl_relayrotate failure. The problem was that Rotate_log_event::exec_event()
  believed that the relay log was corrupted. Fixed it by moving the test for
  corruption to Start_log_event::exec_event(). 
  Changed Rotate_log_event::exec_event() to not increment positions when the
  event is seen in the middle of a transaction (that was an old bug found by
  chance :)
parent 187ca485
......@@ -10,9 +10,9 @@ reset slave;
start slave;
stop slave;
start slave;
select master_pos_wait('master-bin.001',3000,120)=-1;
master_pos_wait('master-bin.001',3000,120)=-1
0
select master_pos_wait('master-bin.001',3000)>=0;
master_pos_wait('master-bin.001',3000)>=0
1
select * from t1 where a=8000;
a
8000
......
......@@ -69,4 +69,4 @@ ERROR HY000: Wrong parameter or combination of parameters for START SLAVE UNTIL
start slave sql_thread;
start slave until master_log_file='master-bin.000001', master_log_pos=561;
Warnings:
Note 1253 The slave was already running
Note 1253 Slave is already running
......@@ -53,10 +53,7 @@ start slave;
# We must wait for the transaction to commit before
# reading, MASTER_POS_WAIT() will do it for sure
# (the only statement with position>=3000 is COMMIT).
# Older versions of MySQL would hang forever in MASTER_POS_WAIT
# because COMMIT was said to be position 0 in the master's log (bug).
# Detect this with timeout.
select master_pos_wait('master-bin.001',3000,120)=-1;
select master_pos_wait('master-bin.001',3000)>=0;
select * from t1 where a=8000;
# The following DROP is a very important cleaning task:
......
......@@ -1086,6 +1086,23 @@ int Start_log_event::exec_event(struct st_relay_log_info* rli)
*/
close_temporary_tables(thd);
cleanup_load_tmpdir();
/*
As a transaction NEVER spans on 2 or more binlogs:
if we have an active transaction at this point, the master died while
writing the transaction to the binary log, i.e. while flushing the binlog
cache to the binlog. As the write was started, the transaction had been
committed on the master, so we lack of information to replay this
transaction on the slave; all we can do is stop with error.
*/
if (thd->options & OPTION_BEGIN)
{
slave_print_error(rli, 0,
"there is an unfinished transaction in the relay log \
(could find neither COMMIT nor ROLLBACK in the relay log); it could be that \
the master died while writing the transaction to its binary log. Now the slave \
is rolling back the transaction.");
return(1);
}
break;
/*
......@@ -1871,35 +1888,19 @@ int Rotate_log_event::write_data(IO_CACHE* file)
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
{
char* log_name = rli->group_master_log_name;
DBUG_ENTER("Rotate_log_event::exec_event");
pthread_mutex_lock(&rli->data_lock);
if (thd->options & OPTION_BEGIN)
{
slave_print_error(rli, 0,
opt_using_transactions ?
"\
There is an unfinished transaction in the relay log (could find neither \
COMMIT nor ROLLBACK in the relay log); It could be that the master died while \
writing the transaction to its binary log. Now the slave is rolling back the \
transaction." :
"\
There is an unfinished transaction in the relay log (could find neither \
COMMIT nor ROLLBACK in the relay log); It could be that the master died while \
writing the transaction to its binary log.");
pthread_mutex_unlock(&rli->data_lock);
DBUG_RETURN(1);
}
memcpy(log_name, new_log_ident, ident_len+1);
rli->notify_group_master_log_name_update();
rli->group_master_log_pos = pos;
rli->event_relay_log_pos += get_event_len();
rli->group_relay_log_pos = rli->event_relay_log_pos;
DBUG_PRINT("info", ("group_master_log_pos: %lu",
(ulong) rli->group_master_log_pos));
if (!(thd->options & OPTION_BEGIN))
{
memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
rli->notify_group_master_log_name_update();
rli->group_master_log_pos = pos;
rli->group_relay_log_pos = rli->event_relay_log_pos;
DBUG_PRINT("info", ("group_master_log_pos: %lu",
(ulong) rli->group_master_log_pos));
}
pthread_mutex_unlock(&rli->data_lock);
pthread_cond_broadcast(&rli->data_cond);
flush_relay_log_info(rli);
......
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