diff --git a/sql/slave.cc b/sql/slave.cc index c7a048e8452..b535c87024b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -907,6 +907,12 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) event_len); char llbuff[22]; + mi->event_len = event_len; /* Added by Heikki: InnoDB internally stores the + master log position it has processed so far; + position to store is really + mi->pos + mi->pending + mi->event_len + since we must store the pos of the END of the + current log event */ if (ev) { int type_code = ev->get_type_code(); @@ -1017,7 +1023,16 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) delete ev; mi->inc_pos(event_len); - flush_master_info(mi); + + if (!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) { + + /* We only flush the master info position to the master.info file if + the transaction is not open any more: an incomplete transaction will + be rolled back automatically in crash recovery in transactional + table handlers */ + + flush_master_info(mi); + } break; } @@ -1139,10 +1154,16 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) } mi->inc_pos(event_len); - flush_master_info(mi); + + if (!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) + flush_master_info(mi); + break; } + /* Question: in a START or STOP event, what happens if we have transaction + open? */ + case START_EVENT: mi->inc_pos(event_len); flush_master_info(mi); @@ -1168,7 +1189,9 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) mi->pos = 4; // skip magic number pthread_cond_broadcast(&mi->cond); pthread_mutex_unlock(&mi->lock); - flush_master_info(mi); + + if (!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) + flush_master_info(mi); #ifndef DBUG_OFF if(abort_slave_event_count) ++events_till_abort; diff --git a/sql/slave.h b/sql/slave.h index 2934e675d56..769689ebfa2 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -12,6 +12,12 @@ typedef struct st_master_info { char log_file_name[FN_REFLEN]; ulonglong pos,pending; + int event_len; /* Added by Heikki: InnoDB internally stores the + master log position it has processed so far; the + position to store is really the sum + pos + pending + event_len + here since we must store the pos of the END of the + current log event */ File fd; // we keep the file open, so we need to remember the file pointer IO_CACHE file; // the variables below are needed because we can change masters on the fly