mysql-test/t/rpl_sporadic_master.test
fixed test case to produce same results on txn-enabled binary. temporary fix - permanent fix is it make mysqld behave the same with MyISAM on auto_increment insert after delete from tbl_name regardless of how the binary was compiled sql/slave.cc fixed concurrency bug with log_seq sql/slave.h last_log_seq needs to be updated atomically with pos sql/sql_repl.cc cleared up comment and fixed concurrency bug mysql-test/t/rpl_sporadic_master.test: fixed test case to produce same results on txn-enabled binary. temporary fix - permanent fix is it make mysqld behave the same with MyISAM on auto_increment insert after delete from tbl_name regardless of how the binary was compiled sql/slave.cc: fixed concurrency bug with log_seq sql/slave.h: last_log_seq needs to be updated atomically with pos sql/sql_repl.cc: cleared up comment and fixed concurrency bug
This commit is contained in:
parent
4ecea7d3a0
commit
586648ccc2
@ -6,12 +6,17 @@ drop table if exists t1;
|
|||||||
create table t1(n int not null auto_increment primary key);
|
create table t1(n int not null auto_increment primary key);
|
||||||
insert into t1 values (NULL),(NULL);
|
insert into t1 values (NULL),(NULL);
|
||||||
delete from t1;
|
delete from t1;
|
||||||
|
set insert_id=1;
|
||||||
insert into t1 values (NULL),(NULL);
|
insert into t1 values (NULL),(NULL);
|
||||||
|
set insert_id=3;
|
||||||
insert into t1 values (NULL),(NULL);
|
insert into t1 values (NULL),(NULL);
|
||||||
flush logs;
|
flush logs;
|
||||||
delete from t1;
|
delete from t1;
|
||||||
|
set insert_id=1;
|
||||||
insert into t1 values (NULL),(NULL);
|
insert into t1 values (NULL),(NULL);
|
||||||
|
set insert_id=3;
|
||||||
insert into t1 values (NULL),(NULL);
|
insert into t1 values (NULL),(NULL);
|
||||||
|
set insert_id=5;
|
||||||
insert into t1 values (NULL),(NULL);
|
insert into t1 values (NULL),(NULL);
|
||||||
save_master_pos;
|
save_master_pos;
|
||||||
connection slave;
|
connection slave;
|
||||||
|
30
sql/slave.cc
30
sql/slave.cc
@ -926,7 +926,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
|||||||
if(type_code == LOAD_EVENT)
|
if(type_code == LOAD_EVENT)
|
||||||
skip_load_data_infile(net);
|
skip_load_data_infile(net);
|
||||||
|
|
||||||
mi->inc_pos(event_len);
|
mi->inc_pos(event_len, ev->log_seq);
|
||||||
flush_master_info(mi);
|
flush_master_info(mi);
|
||||||
if(slave_skip_counter)
|
if(slave_skip_counter)
|
||||||
--slave_skip_counter;
|
--slave_skip_counter;
|
||||||
@ -1019,10 +1019,9 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
free_root(&thd->mem_root,0);
|
free_root(&thd->mem_root,0);
|
||||||
mi->last_log_seq = ev->log_seq;
|
|
||||||
delete ev;
|
|
||||||
thd->log_seq = 0;
|
thd->log_seq = 0;
|
||||||
mi->inc_pos(event_len);
|
mi->inc_pos(event_len, ev->log_seq);
|
||||||
|
delete ev;
|
||||||
flush_master_info(mi);
|
flush_master_info(mi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1035,11 +1034,10 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
|||||||
mysql_bin_log.write(sev);
|
mysql_bin_log.write(sev);
|
||||||
}
|
}
|
||||||
|
|
||||||
mi->last_log_seq = ev->log_seq;
|
|
||||||
delete ev;
|
|
||||||
thd->log_seq = 0;
|
thd->log_seq = 0;
|
||||||
mi->inc_pos(event_len);
|
mi->inc_pos(event_len, ev->log_seq);
|
||||||
flush_master_info(mi);
|
flush_master_info(mi);
|
||||||
|
delete ev;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1150,8 +1148,6 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mi->last_log_seq = ev->log_seq;
|
|
||||||
delete ev;
|
|
||||||
thd->log_seq = 0;
|
thd->log_seq = 0;
|
||||||
free_root(&thd->mem_root,0);
|
free_root(&thd->mem_root,0);
|
||||||
|
|
||||||
@ -1159,18 +1155,19 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
|||||||
{
|
{
|
||||||
sql_print_error("Slave: Fatal error running query '%s' ",
|
sql_print_error("Slave: Fatal error running query '%s' ",
|
||||||
thd->query);
|
thd->query);
|
||||||
|
delete ev;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mi->inc_pos(event_len);
|
mi->inc_pos(event_len, ev->log_seq);
|
||||||
|
delete ev;
|
||||||
flush_master_info(mi);
|
flush_master_info(mi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case START_EVENT:
|
case START_EVENT:
|
||||||
close_temporary_tables(thd);
|
close_temporary_tables(thd);
|
||||||
mi->inc_pos(event_len);
|
mi->inc_pos(event_len, ev->log_seq);
|
||||||
mi->last_log_seq = ev->log_seq;
|
|
||||||
flush_master_info(mi);
|
flush_master_info(mi);
|
||||||
delete ev;
|
delete ev;
|
||||||
thd->log_seq = 0;
|
thd->log_seq = 0;
|
||||||
@ -1180,10 +1177,9 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
|||||||
if(mi->pos > 4) // stop event should be ignored after rotate event
|
if(mi->pos > 4) // stop event should be ignored after rotate event
|
||||||
{
|
{
|
||||||
close_temporary_tables(thd);
|
close_temporary_tables(thd);
|
||||||
mi->inc_pos(event_len);
|
mi->inc_pos(event_len, ev->log_seq);
|
||||||
flush_master_info(mi);
|
flush_master_info(mi);
|
||||||
}
|
}
|
||||||
mi->last_log_seq = ev->log_seq;
|
|
||||||
delete ev;
|
delete ev;
|
||||||
thd->log_seq = 0;
|
thd->log_seq = 0;
|
||||||
break;
|
break;
|
||||||
@ -1207,17 +1203,17 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
|||||||
}
|
}
|
||||||
mi->pos = rev->pos;
|
mi->pos = rev->pos;
|
||||||
mi->last_log_seq = ev->log_seq;
|
mi->last_log_seq = ev->log_seq;
|
||||||
pthread_cond_broadcast(&mi->cond);
|
|
||||||
pthread_mutex_unlock(&mi->lock);
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if (abort_slave_event_count)
|
if (abort_slave_event_count)
|
||||||
++events_till_abort;
|
++events_till_abort;
|
||||||
#endif
|
#endif
|
||||||
if (rotate_binlog)
|
if (rotate_binlog)
|
||||||
{
|
{
|
||||||
mi->last_log_seq = 0;
|
|
||||||
mysql_bin_log.new_file();
|
mysql_bin_log.new_file();
|
||||||
|
mi->last_log_seq = 0;
|
||||||
}
|
}
|
||||||
|
pthread_cond_broadcast(&mi->cond);
|
||||||
|
pthread_mutex_unlock(&mi->lock);
|
||||||
flush_master_info(mi);
|
flush_master_info(mi);
|
||||||
|
|
||||||
if (write_slave_event)
|
if (write_slave_event)
|
||||||
|
@ -36,11 +36,12 @@ typedef struct st_master_info
|
|||||||
{
|
{
|
||||||
pending += val;
|
pending += val;
|
||||||
}
|
}
|
||||||
inline void inc_pos(ulonglong val)
|
inline void inc_pos(ulonglong val, uint32 log_seq)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
pos += val + pending;
|
pos += val + pending;
|
||||||
pending = 0;
|
pending = 0;
|
||||||
|
last_log_seq = log_seq;
|
||||||
pthread_cond_broadcast(&cond);
|
pthread_cond_broadcast(&cond);
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
// Sasha Pachev <sasha@mysql.com> is currently in charge of this file
|
// Sasha Pachev <sasha@mysql.com> is currently in charge of this file
|
||||||
// Do not mess with it without his permission!
|
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "sql_repl.h"
|
#include "sql_repl.h"
|
||||||
@ -259,9 +258,10 @@ void adjust_linfo_offsets(my_off_t purge_offset)
|
|||||||
if ((linfo = tmp->current_linfo))
|
if ((linfo = tmp->current_linfo))
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&linfo->lock);
|
pthread_mutex_lock(&linfo->lock);
|
||||||
// Why (monty): I don't understand this comment
|
/* index file offset can be less that purge offset
|
||||||
// no big deal if we just started reading the log
|
only if we just started reading the index file. In that case
|
||||||
// nothing to adjust
|
we have nothing to adjust
|
||||||
|
*/
|
||||||
if (linfo->index_file_offset < purge_offset)
|
if (linfo->index_file_offset < purge_offset)
|
||||||
linfo->fatal = (linfo->index_file_offset != 0);
|
linfo->fatal = (linfo->index_file_offset != 0);
|
||||||
else
|
else
|
||||||
@ -935,16 +935,7 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg)
|
|||||||
|
|
||||||
linfo.index_file_offset = 0;
|
linfo.index_file_offset = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
WARNING: POSSIBLE BUG:
|
|
||||||
Sasha, you are setting an uninitialized linfo into
|
|
||||||
thd->current_linfo.
|
|
||||||
What will happen if some other thread calls log_in_use() or
|
|
||||||
adjust_linfo_offsets() after the next instruction as linfo may
|
|
||||||
contain anything ?
|
|
||||||
*/
|
|
||||||
|
|
||||||
thd->current_linfo = &linfo;
|
|
||||||
search_file_name[0] = 0;
|
search_file_name[0] = 0;
|
||||||
|
|
||||||
if (mysql_bin_log.find_first_log(&linfo, search_file_name))
|
if (mysql_bin_log.find_first_log(&linfo, search_file_name))
|
||||||
@ -952,6 +943,7 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg)
|
|||||||
strmov(errmsg,"Could not find first log");
|
strmov(errmsg,"Could not find first log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
thd->current_linfo = &linfo;
|
||||||
|
|
||||||
bzero((char*) &log,sizeof(log));
|
bzero((char*) &log,sizeof(log));
|
||||||
log_lock = mysql_bin_log.get_log_lock();
|
log_lock = mysql_bin_log.get_log_lock();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user