Commit 53ada890 authored by unknown's avatar unknown

fixed bugs in delayed insert replication and when slave loses connection after...

fixed bugs in delayed insert replication and when slave loses connection after Int_var but before Query
public test suite now tests replication code as well


mysql-test/mybin/mysql-test_install_db:
  fixes to test replication with two daemons on one machine
mysql-test/mysql-test-run:
  fixes for replication tests -- still need to test gcov, the rest works
mysql-test/t/include/master-slave.inc:
  include file for replication tests
sql/slave.cc:
  fixed bug for the case when the slave loses connection after it has read Int_var event but before Query
sql/sql_insert.cc:
  reset error in delayed thread
  slave converts delayed insert to regular
parent 5abcec92
...@@ -5,38 +5,21 @@ ...@@ -5,38 +5,21 @@
# This scripts creates the privilege tables db, host, user, tables_priv, # This scripts creates the privilege tables db, host, user, tables_priv,
# columns_priv in the mysql database, as well as the func table. # columns_priv in the mysql database, as well as the func table.
ldata=var/lib
logdir=var/log
mdata=$ldata/mysql
execdir=../sql
bindir=../client
# Get mysqld/safe_mysqld options from /etc/my.cnf or ~/.my.cnf
if test -w /
then
conf=@sysconfdir@/my.cnf
else
conf=$HOME/.my.cnf
fi
if test -f "$conf" if [ x$1 = x"-slave" ]
then then
if grep "^datadir" $conf >/dev/null shift $#
then ldata=var/slave-data
ldata=`grep "^datadir" $conf | sed '.*=[ \t]*//` logdir=var/log
fi mdata=$ldata/mysql
if grep "^execdir" $conf >/dev/null execdir=../sql
then bindir=../client
execdir=`grep "^execdir" $conf | sed '.*=[ \t]*//` else
fi ldata=var/lib
if grep "^bindir" $conf >/dev/null logdir=var/log
then mdata=$ldata/mysql
bindir=`grep "^bindir" $conf | sed '.*=[ \t]*//` execdir=../sql
fi bindir=../client
if grep "^user" $conf >/dev/null
then
user=`grep "^user" $conf | sed '.*=[ \t]*//`
fi
fi fi
if test ! -x $execdir/mysqld if test ! -x $execdir/mysqld
...@@ -51,6 +34,7 @@ hostname=`hostname` # Install this too in the user table ...@@ -51,6 +34,7 @@ hostname=`hostname` # Install this too in the user table
resolved=127.0.0.1 resolved=127.0.0.1
# Create database directories mysql & test # Create database directories mysql & test
if test ! -d $ldata; then (mkdir -p $ldata || exit 1) && \ if test ! -d $ldata; then (mkdir -p $ldata || exit 1) && \
(chmod 700 $ldata || exit 1) ; fi (chmod 700 $ldata || exit 1) ; fi
...@@ -207,8 +191,8 @@ then ...@@ -207,8 +191,8 @@ then
c_c="$c_c comment='Column privileges';" c_c="$c_c comment='Column privileges';"
fi fi
if $execdir/mysqld --bootstrap --skip-grant-tables \ if $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
--basedir=. --datadir=$ldata "$@" << END_OF_DATA --basedir=. --datadir=$ldata << END_OF_DATA
use mysql; use mysql;
$c_d $c_d
$i_d $i_d
......
...@@ -25,12 +25,18 @@ TOT_TEST=0 ...@@ -25,12 +25,18 @@ TOT_TEST=0
USERT=0 USERT=0
SYST=0 SYST=0
REALT=0 REALT=0
MY_TMP_DIR=$CWD/var/tmp
TIMEFILE="$CWD/var/tmp/mysqltest-time" TIMEFILE="$CWD/var/tmp/mysqltest-time"
DASHBLANK="---- ---- -------" DASHBLANK="---- ---- -------"
MYSQLD_SRC_DIRS="strings mysys include extra regex isam merge myisam \ MYSQLD_SRC_DIRS="strings mysys include extra regex isam merge myisam \
myisammrg heap sql" myisammrg heap sql"
GCOV_MSG=/tmp/mysqld-gcov.out #gcov output GCOV_MASTER_MSG=/tmp/mysqld-master-gcov.out #gcov output
GCOV_ERR=/tmp/mysqld-gcov.err GCOV_MASTER_ERR=/tmp/mysqld-master-gcov.err
GCOV_SLAVE_MSG=/tmp/mysqld-slave-gcov.out #gcov output
GCOV_SLAVE_ERR=/tmp/mysqld-slave-gcov.err
GCOV_SLAVE_SRC=/tmp/mysqld-slave-src/
[ -d $MY_TMP_DIR ] || mkdir -p $MY_TMP_DIR
[ -z $COLUMNS ] && COLUMNS=80 [ -z $COLUMNS ] && COLUMNS=80
E=`expr $COLUMNS - 8` E=`expr $COLUMNS - 8`
...@@ -45,12 +51,20 @@ done ...@@ -45,12 +51,20 @@ done
#++ #++
# mysqld Environment Parameters # mysqld Environment Parameters
#-- #--
MYPORT=9306 MYRUN_DIR=var/run
MYDDIR="$CWD/var/lib" MASTER_MYPORT=9306
MYSOCK="$CWD/var/tmp/mysql.sock" MASTER_MYDDIR="$CWD/var/lib"
MYPID="$CWD/var/run/mysqld.pid" MASTER_MYSOCK="$CWD/var/tmp/mysql.sock"
MYLOG="$CWD/var/log/mysqld.log" MASTER_MYPID="$CWD/var/run/mysqld.pid"
MYERR="$CWD/var/log/mysqld.err" MASTER_MYLOG="$CWD/var/log/mysqld.log"
MASTER_MYERR="$CWD/var/log/mysqld.err"
SLAVE_MYPORT=9307
SLAVE_MYDDIR="$CWD/var/slave-data"
SLAVE_MYSOCK="$CWD/var/tmp/mysql-slave.sock"
SLAVE_MYPID="$CWD/var/run/mysqld-slave.pid"
SLAVE_MYLOG="$CWD/var/log/mysqld-slave.log"
SLAVE_MYERR="$CWD/var/log/mysqld-slave.err"
#++ #++
# Program Definitions # Program Definitions
...@@ -70,7 +84,7 @@ XARGS=`which xargs` ...@@ -70,7 +84,7 @@ XARGS=`which xargs`
MYSQLD="$BASEDIR/sql/mysqld" MYSQLD="$BASEDIR/sql/mysqld"
MYSQL_TEST="$BASEDIR/client/mysqltest" MYSQL_TEST="$BASEDIR/client/mysqltest"
MYSQLADMIN="$BASEDIR/client/mysqladmin" MYSQLADMIN="$BASEDIR/client/mysqladmin"
MYSQL_TEST="$MYSQL_TEST --socket=$MYSOCK --database=$DB --user=$DBUSER --password=$DBPASSWD --silent" MYSQL_TEST="$MYSQL_TEST --socket=$MASTER_MYSOCK --database=$DB --user=$DBUSER --password=$DBPASSWD --silent"
INSTALL_DB="$MYBIN/mysql-test_install_db" INSTALL_DB="$MYBIN/mysql-test_install_db"
[ "$1" = "-gcov" ] && DO_GCOV=1 [ "$1" = "-gcov" ] && DO_GCOV=1
...@@ -165,52 +179,97 @@ report_stats () { ...@@ -165,52 +179,97 @@ report_stats () {
} }
mysql_install_db () { mysql_install_db () {
`$INSTALL_DB` $RM -rf $MASTER_MYDDIR $SLAVE_MYDDIR $SLAVE_MYLOG $MASTER_MYLOG \
$SLAVE_MYERR $MASTER_MYERR
[ -d $MYRUN_DIR ] || mkdir -p $MYRUN_DIR
$INSTALL_DB
if [ $? != 0 ]; then
error "Could not install master test DBs"
exit 1
fi
$INSTALL_DB -slave
if [ $? != 0 ]; then if [ $? != 0 ]; then
error "Could not install test DBs" error "Could not install slave test DBs"
exit 1 exit 1
fi fi
return 0 return 0
} }
gcov_clean () { gcov_prepare () {
$FIND $BASEDIR -name \*.gcov \ $FIND $BASEDIR -name \*.gcov \
-or -name \*.da | $XARGS $RM -or -name \*.da | $XARGS $RM
$RM -rf $GCOV_SLAVE_SRC
for d in $MYSQLD_SRC_DIRS; do
cd $BASEDIR/$d
mkdir -p $GCOV_SLAVE_SRC/$d
for f in *.h *.cc *.c; do
cp $f $GCOV_SLAVE_SRC/$d
done
cd $CWD
done
} }
gcov_collect () { gcov_collect () {
$ECHO "Collecting source coverage info..." $ECHO "Collecting source coverage info..."
[ -f $GCOV_MSG ] && $RM $GCOV_MSG [ -f $GCOV_MASTER_MSG ] && $RM $GCOV_MASTER_MSG
[ -f $GCOV_ERR ] && $RM $GCOV_ERR [ -f $GCOV_MASTER_ERR ] && $RM $GCOV_MASTER_ERR
[ -f $GCOV_SLAVE_MSG ] && $RM $GCOV_SLAVE_MSG
[ -f $GCOV_SLAVE_ERR ] && $RM $GCOV_SLAVE_ERR
for d in $MYSQLD_SRC_DIRS; do for d in $MYSQLD_SRC_DIRS; do
cd $BASEDIR/$d cd $BASEDIR/$d
for f in *.h *.cc *.c; do for f in *.h *.cc *.c; do
$GCOV $f 2>>$GCOV_ERR >>$GCOV_MSG $GCOV $f 2>>$GCOV_MASTER_ERR >>$GCOV_MASTER_MSG
done
cd $CWD
cd $GCOV_SLAVE_SRC/$d
for f in *.h *.cc *.c; do
$GCOV $f 2>>$GCOV_SLAVE_ERR >>$GCOV_SLAVE_MSG
done done
cd $CWD cd $CWD
done done
$ECHO "gcov info in $GCOV_MSG, errors in $GCOV_ERR" $ECHO "gcov master info in $GCOV_MASTER_MSG, errors in $GCOV_MASTER_ERR"
$ECHO "gcov slave info in $GCOV_SLAVE_MSG, errors in $GCOV_SLAVE_ERR"
} }
mysql_start () { mysql_start () {
cd $BASEDIR # for gcov cd $BASEDIR # for gcov
$MYSQLD --no-defaults \ #start master
--skip-networking \ $MYSQLD --no-defaults --log-bin \
--server-id=1 \
--basedir=$CWD \ --basedir=$CWD \
--datadir=$MYDDIR \ --port=$MASTER_MYPORT \
--pid-file=$MYPID \ --core-file \
--socket=$MYSOCK \ --datadir=$MASTER_MYDDIR \
--log=$MYLOG \ --pid-file=$MASTER_MYPID \
--language=english >> $MYERR 2>&1 & --socket=$MASTER_MYSOCK \
--log=$MASTER_MYLOG \
--language=english >> $MASTER_MYERR 2>&1 &
#allow master to get setteled so slave can connect right away without error
sleep 1
#start slave
$MYSQLD --no-defaults --server-id=2 \
--master-user=root \
--master-connect-retry=5 \
--master-host=127.0.0.1 \
--master-port=$MASTER_MYPORT \
--core-file \
--basedir=$CWD \
--datadir=$SLAVE_MYDDIR \
--pid-file=$SLAVE_MYPID \
--port=$SLAVE_MYPORT \
--socket=$SLAVE_MYSOCK \
--log=$SLAVE_MYLOG \
--language=english >> $SLAVE_MYERR 2>&1 &
cd $CWD cd $CWD
return 1 return 1
} }
mysql_stop () { mysql_stop () {
`$MYSQLADMIN --socket=$MYSOCK -u root shutdown` $MYSQLADMIN --socket=$MASTER_MYSOCK -u root shutdown
$MYSQLADMIN --socket=$SLAVE_MYSOCK -u root shutdown
return 1 return 1
} }
...@@ -230,13 +289,14 @@ mysql_restart () { ...@@ -230,13 +289,14 @@ mysql_restart () {
mysql_loadstd () { mysql_loadstd () {
sleep 2 #sleep 2
return 1 return 1
} }
[ "$DO_GCOV" -a ! -x "$GCOV" ] && error "No gcov found" [ "$DO_GCOV" -a ! -x "$GCOV" ] && error "No gcov found"
[ "$DO_GCOV" ] && gcov_clean # clean up stale gcov files if running with gcov [ "$DO_GCOV" ] && gcov_prepare
mysql_install_db mysql_install_db
...@@ -289,6 +349,9 @@ do ...@@ -289,6 +349,9 @@ do
total_inc total_inc
if [ $res != 0 ]; then if [ $res != 0 ]; then
$ECHO "failed output"
$CAT $TIMEFILE
$ECHO
$ECHO $ECHO
$SETCOLOR_NORMAL && $ECHO -n "Restarting mysqld $DASHBLANK" $SETCOLOR_NORMAL && $ECHO -n "Restarting mysqld $DASHBLANK"
mysql_restart mysql_restart
......
Table Op Msg_type Msg_text
test.words check status OK
name age id
Andy 31 00000001
Jacob 2 00000002
Caleb 1 00000003
unix_timestamp(t)
200006
This diff is collapsed.
source t/include/master-slave.inc;
connection master;
use test;
drop table if exists words;
create table words (word char(20) not null);
load data infile '../../std_data/words' into table words;
drop table if exists foo;
create table foo(n int);
insert into foo values(1),(2);
connection slave;
sleep 3;
use test;
@r/3.23/rpl000001.a.result select * from foo;
@r/3.23/rpl000001.b.result select sum(length(word)) from words;
source t/include/master-slave.inc;
connection master;
use test;
drop table if exists x;
create table x(n int auto_increment primary key);
set insert_id = 2000;
insert into x values (NULL),(NULL),(NULL);
connection slave;
use test;
sleep 1;
@r/3.23/rpl000002.result select * from x;
source t/include/master-slave.inc;
connection master;
drop table if exists x;
create table x(n int primary key);
!insert into x values (1),(2),(2);
insert into x values (3);
connection slave;
sleep 1;
@r/3.23/rpl000003.result select * from x;
source t/include/master-slave.inc;
connection master;
use test;
set SQL_LOG_BIN=0;
drop table if exists words;
create table words (word char(20) not null, index(word));
load data infile '../../std_data/words' into table words;
drop table if exists words1;
create table words1 (word char(20) not null);
load data infile '../../std_data/words' into table words1;
connection slave;
use test;
drop table if exists words;
load table words from master;
drop table if exists words1;
load table words1 from master;
@r/3.23/rpl000004.a.result check table words;
@r/3.23/rpl000004.b.result select count(*) from words1;
source t/include/master-slave.inc;
connection master;
drop table if exists test;
CREATE TABLE test (name varchar(64), age smallint(3));
INSERT INTO test SET name='Andy', age=31;
INSERT test SET name='Jacob', age=2;
INSERT into test SET name='Caleb', age=1;
ALTER TABLE test ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY;
@r/3.23/rpl000005.result select * from test;
connection slave;
sleep 1;
@r/3.23/rpl000005.result select * from test;
source t/include/master-slave.inc;
connection master;
set SQL_LOG_BIN=0;
set timestamp=200006;
drop table if exists foo;
create table foo(t timestamp not null,a char(1));
insert into foo ( a) values ('F');
@r/3.23/rpl000006.result select unix_timestamp(t) from foo;
connection slave;
drop table if exists foo;
load table foo from master;
@r/3.23/rpl000006.result select unix_timestamp(t) from foo;
connect (master,localhost,root,,test,0,var/tmp/mysql.sock);
connect (slave,localhost,root,,test,0,var/tmp/mysql-slave.sock);
connection slave;
!slave stop;
connection master;
reset master;
connection slave;
reset slave;
!slave start;
...@@ -1053,6 +1053,8 @@ static void safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) ...@@ -1053,6 +1053,8 @@ static void safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
static void safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) static void safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
{ {
mi->pending = 0; // if we lost connection after reading a state set event
// we will be re-reading it, so pending needs to be cleared
while(!slave_killed(thd) && mc_mysql_reconnect(mysql)) while(!slave_killed(thd) && mc_mysql_reconnect(mysql))
{ {
sql_print_error( sql_print_error(
......
...@@ -113,8 +113,15 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields, ...@@ -113,8 +113,15 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
char *query=thd->query; char *query=thd->query;
DBUG_ENTER("mysql_insert"); DBUG_ENTER("mysql_insert");
/*
in safe mode or with skip-new change delayed insert to be regular
if we are told to replace duplicates, the insert cannot be concurrent
delayed insert changed to regular in slave thread
*/
if (lock_type == TL_WRITE_DELAYED && if (lock_type == TL_WRITE_DELAYED &&
(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) || ((specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) ||
thd->slave_thread
) ||
lock_type == TL_WRITE_CONCURRENT_INSERT && duplic == DUP_REPLACE) lock_type == TL_WRITE_CONCURRENT_INSERT && duplic == DUP_REPLACE)
lock_type=TL_WRITE; lock_type=TL_WRITE;
...@@ -1083,6 +1090,7 @@ bool delayed_insert::handle_inserts(void) ...@@ -1083,6 +1090,7 @@ bool delayed_insert::handle_inserts(void)
table->time_stamp=row->time_stamp; table->time_stamp=row->time_stamp;
info.handle_duplicates= row->dup; info.handle_duplicates= row->dup;
thd.net.last_errno = 0; // reset error for binlog
if (write_record(table,&info)) if (write_record(table,&info))
{ {
info.error++; // Ignore errors info.error++; // Ignore errors
......
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