From c78680b43f3d2320218d9851d70e73df9409c22c Mon Sep 17 00:00:00 2001 From: unknown <guilhem@gbichot2> Date: Fri, 3 Oct 2003 20:07:08 +0200 Subject: [PATCH] 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 :) --- mysql-test/r/rpl_relayrotate.result | 6 ++-- mysql-test/r/rpl_until.result | 2 +- mysql-test/t/rpl_relayrotate.test | 5 +-- sql/log_event.cc | 51 +++++++++++++++-------------- 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/mysql-test/r/rpl_relayrotate.result b/mysql-test/r/rpl_relayrotate.result index 0ad61a7687e..802be911ad7 100644 --- a/mysql-test/r/rpl_relayrotate.result +++ b/mysql-test/r/rpl_relayrotate.result @@ -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 diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index 3dc3de8802d..ee5ceb28bd8 100644 --- a/mysql-test/r/rpl_until.result +++ b/mysql-test/r/rpl_until.result @@ -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 diff --git a/mysql-test/t/rpl_relayrotate.test b/mysql-test/t/rpl_relayrotate.test index 3f315ba9365..3aab8371ac0 100644 --- a/mysql-test/t/rpl_relayrotate.test +++ b/mysql-test/t/rpl_relayrotate.test @@ -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: diff --git a/sql/log_event.cc b/sql/log_event.cc index b6964c40422..23586201dcb 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -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); -- 2.30.9