diff options
author | unknown <guilhem@mysql.com> | 2003-08-23 16:54:22 +0200 |
---|---|---|
committer | unknown <guilhem@mysql.com> | 2003-08-23 16:54:22 +0200 |
commit | 9438655af97bf6f06512c1bdb4cc97a451b8fbc1 (patch) | |
tree | 072f8116d5344f9f93372a7f827e3aa382e36368 | |
parent | 2d2f57654521df494afc41545322e0ebb0ec47a4 (diff) | |
parent | 6e10224d71cf876466cfa9f83d88fe2c4885f162 (diff) | |
download | mariadb-git-9438655af97bf6f06512c1bdb4cc97a451b8fbc1.tar.gz |
Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-4.0
into mysql.com:/home/mysql_src/mysql-4.0
-rw-r--r-- | sql/log_event.cc | 43 | ||||
-rw-r--r-- | sql/slave.cc | 8 |
2 files changed, 43 insertions, 8 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc index 54e4d34f77e..c3bf41af8e7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2068,9 +2068,6 @@ Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'", TODO - Remove all active user locks - - If we have an active transaction at this point, the master died - in the middle while writing the transaction to the binary log. - In this case we should stop the slave. */ int Start_log_event::exec_event(struct st_relay_log_info* rli) @@ -2098,8 +2095,10 @@ int Start_log_event::exec_event(struct st_relay_log_info* rli) break; case BINLOG_FORMAT_323_GEQ_57 : /* Can distinguish, based on the value of 'created' */ - if (created) /* this was generated at master startup*/ - close_temporary_tables(thd); + if (!created) + break; + /* otherwise this was generated at master startup*/ + close_temporary_tables(thd); break; default : /* this case is impossible */ @@ -2156,10 +2155,28 @@ int Stop_log_event::exec_event(struct st_relay_log_info* rli) We can't rotate the slave as this will cause infinitive rotations in a A -> B -> A setup. + NOTES + 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 we didn't detect it, then positions would start to become garbage (as we + are incrementing rli->relay_log_pos whereas we are in a transaction: the new + rli->relay_log_pos will be + relay_log_pos of the BEGIN + size of the Rotate event = garbage. + + Since MySQL 4.0.14, the master ALWAYS sends a Rotate event when it starts + sending the next binlog, so we are sure to receive a Rotate event just + after the end of the "dead master"'s binlog; so this exec_event() is the + right place to catch the problem. If we would wait until + Start_log_event::exec_event() it would be too late, rli->relay_log_pos would + already be garbage. + RETURN VALUES 0 ok - */ - +*/ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) { @@ -2167,6 +2184,18 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) DBUG_ENTER("Rotate_log_event::exec_event"); pthread_mutex_lock(&rli->data_lock); + + if (rli->inside_transaction) + { + 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."); + pthread_mutex_unlock(&rli->data_lock); + DBUG_RETURN(1); + } + memcpy(log_name, new_log_ident, ident_len+1); rli->master_log_pos = pos; rli->relay_log_pos += get_event_len(); diff --git a/sql/slave.cc b/sql/slave.cc index 32ed228e119..10ec0050d05 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2260,7 +2260,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) } else { - sql_print_error("\ + slave_print_error(rli, 0, "\ Could not parse relay log event entry. The possible reasons are: the master's \ binary log is corrupted (you can check this by running 'mysqlbinlog' on the \ binary log), the slave's relay log is corrupted (you can check this by running \ @@ -2695,6 +2695,12 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun /* When master_pos_wait() wakes up it will check this and terminate */ rli->slave_running= 0; + /* + Going out of the transaction. Necessary to mark it, in case the user + restarts replication from a non-transactional statement (with CHANGE + MASTER). + */ + rli->inside_transaction= 0; /* Wake up master_pos_wait() */ pthread_mutex_unlock(&rli->data_lock); DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions")); |