mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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
This commit is contained in:
@ -5,38 +5,21 @@
|
||||
# This scripts creates the privilege tables db, host, user, tables_priv,
|
||||
# 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 /
|
||||
if [ x$1 = x"-slave" ]
|
||||
then
|
||||
conf=@sysconfdir@/my.cnf
|
||||
shift $#
|
||||
ldata=var/slave-data
|
||||
logdir=var/log
|
||||
mdata=$ldata/mysql
|
||||
execdir=../sql
|
||||
bindir=../client
|
||||
else
|
||||
conf=$HOME/.my.cnf
|
||||
fi
|
||||
|
||||
if test -f "$conf"
|
||||
then
|
||||
if grep "^datadir" $conf >/dev/null
|
||||
then
|
||||
ldata=`grep "^datadir" $conf | sed '.*=[ \t]*//`
|
||||
fi
|
||||
if grep "^execdir" $conf >/dev/null
|
||||
then
|
||||
execdir=`grep "^execdir" $conf | sed '.*=[ \t]*//`
|
||||
fi
|
||||
if grep "^bindir" $conf >/dev/null
|
||||
then
|
||||
bindir=`grep "^bindir" $conf | sed '.*=[ \t]*//`
|
||||
fi
|
||||
if grep "^user" $conf >/dev/null
|
||||
then
|
||||
user=`grep "^user" $conf | sed '.*=[ \t]*//`
|
||||
fi
|
||||
ldata=var/lib
|
||||
logdir=var/log
|
||||
mdata=$ldata/mysql
|
||||
execdir=../sql
|
||||
bindir=../client
|
||||
fi
|
||||
|
||||
if test ! -x $execdir/mysqld
|
||||
@ -51,6 +34,7 @@ hostname=`hostname` # Install this too in the user table
|
||||
|
||||
resolved=127.0.0.1
|
||||
|
||||
|
||||
# Create database directories mysql & test
|
||||
if test ! -d $ldata; then (mkdir -p $ldata || exit 1) && \
|
||||
(chmod 700 $ldata || exit 1) ; fi
|
||||
@ -207,8 +191,8 @@ then
|
||||
c_c="$c_c comment='Column privileges';"
|
||||
fi
|
||||
|
||||
if $execdir/mysqld --bootstrap --skip-grant-tables \
|
||||
--basedir=. --datadir=$ldata "$@" << END_OF_DATA
|
||||
if $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
|
||||
--basedir=. --datadir=$ldata << END_OF_DATA
|
||||
use mysql;
|
||||
$c_d
|
||||
$i_d
|
||||
|
@ -25,12 +25,18 @@ TOT_TEST=0
|
||||
USERT=0
|
||||
SYST=0
|
||||
REALT=0
|
||||
MY_TMP_DIR=$CWD/var/tmp
|
||||
TIMEFILE="$CWD/var/tmp/mysqltest-time"
|
||||
DASHBLANK="---- ---- -------"
|
||||
MYSQLD_SRC_DIRS="strings mysys include extra regex isam merge myisam \
|
||||
myisammrg heap sql"
|
||||
GCOV_MSG=/tmp/mysqld-gcov.out #gcov output
|
||||
GCOV_ERR=/tmp/mysqld-gcov.err
|
||||
GCOV_MASTER_MSG=/tmp/mysqld-master-gcov.out #gcov output
|
||||
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
|
||||
E=`expr $COLUMNS - 8`
|
||||
@ -45,12 +51,20 @@ done
|
||||
#++
|
||||
# mysqld Environment Parameters
|
||||
#--
|
||||
MYPORT=9306
|
||||
MYDDIR="$CWD/var/lib"
|
||||
MYSOCK="$CWD/var/tmp/mysql.sock"
|
||||
MYPID="$CWD/var/run/mysqld.pid"
|
||||
MYLOG="$CWD/var/log/mysqld.log"
|
||||
MYERR="$CWD/var/log/mysqld.err"
|
||||
MYRUN_DIR=var/run
|
||||
MASTER_MYPORT=9306
|
||||
MASTER_MYDDIR="$CWD/var/lib"
|
||||
MASTER_MYSOCK="$CWD/var/tmp/mysql.sock"
|
||||
MASTER_MYPID="$CWD/var/run/mysqld.pid"
|
||||
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
|
||||
@ -70,7 +84,7 @@ XARGS=`which xargs`
|
||||
MYSQLD="$BASEDIR/sql/mysqld"
|
||||
MYSQL_TEST="$BASEDIR/client/mysqltest"
|
||||
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"
|
||||
|
||||
[ "$1" = "-gcov" ] && DO_GCOV=1
|
||||
@ -165,52 +179,97 @@ report_stats () {
|
||||
}
|
||||
|
||||
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 test DBs"
|
||||
error "Could not install master test DBs"
|
||||
exit 1
|
||||
fi
|
||||
$INSTALL_DB -slave
|
||||
if [ $? != 0 ]; then
|
||||
error "Could not install slave test DBs"
|
||||
exit 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
gcov_clean () {
|
||||
gcov_prepare () {
|
||||
$FIND $BASEDIR -name \*.gcov \
|
||||
-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 () {
|
||||
$ECHO "Collecting source coverage info..."
|
||||
[ -f $GCOV_MSG ] && $RM $GCOV_MSG
|
||||
[ -f $GCOV_ERR ] && $RM $GCOV_ERR
|
||||
[ -f $GCOV_MASTER_MSG ] && $RM $GCOV_MASTER_MSG
|
||||
[ -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
|
||||
cd $BASEDIR/$d
|
||||
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
|
||||
cd $CWD
|
||||
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 () {
|
||||
|
||||
cd $BASEDIR # for gcov
|
||||
$MYSQLD --no-defaults \
|
||||
--skip-networking \
|
||||
#start master
|
||||
$MYSQLD --no-defaults --log-bin \
|
||||
--server-id=1 \
|
||||
--basedir=$CWD \
|
||||
--datadir=$MYDDIR \
|
||||
--pid-file=$MYPID \
|
||||
--socket=$MYSOCK \
|
||||
--log=$MYLOG \
|
||||
--language=english >> $MYERR 2>&1 &
|
||||
--port=$MASTER_MYPORT \
|
||||
--core-file \
|
||||
--datadir=$MASTER_MYDDIR \
|
||||
--pid-file=$MASTER_MYPID \
|
||||
--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
|
||||
return 1
|
||||
}
|
||||
|
||||
mysql_stop () {
|
||||
|
||||
`$MYSQLADMIN --socket=$MYSOCK -u root shutdown`
|
||||
$MYSQLADMIN --socket=$MASTER_MYSOCK -u root shutdown
|
||||
$MYSQLADMIN --socket=$SLAVE_MYSOCK -u root shutdown
|
||||
|
||||
return 1
|
||||
}
|
||||
@ -230,13 +289,14 @@ mysql_restart () {
|
||||
|
||||
mysql_loadstd () {
|
||||
|
||||
sleep 2
|
||||
#sleep 2
|
||||
return 1
|
||||
}
|
||||
|
||||
[ "$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
|
||||
|
||||
@ -289,6 +349,9 @@ do
|
||||
total_inc
|
||||
|
||||
if [ $res != 0 ]; then
|
||||
$ECHO "failed output"
|
||||
$CAT $TIMEFILE
|
||||
$ECHO
|
||||
$ECHO
|
||||
$SETCOLOR_NORMAL && $ECHO -n "Restarting mysqld $DASHBLANK"
|
||||
mysql_restart
|
||||
|
3
mysql-test/r/3.23/rpl000001.a.result
Normal file
3
mysql-test/r/3.23/rpl000001.a.result
Normal file
@ -0,0 +1,3 @@
|
||||
n
|
||||
1
|
||||
2
|
2
mysql-test/r/3.23/rpl000001.b.result
Normal file
2
mysql-test/r/3.23/rpl000001.b.result
Normal file
@ -0,0 +1,2 @@
|
||||
sum(length(word))
|
||||
363634
|
4
mysql-test/r/3.23/rpl000002.result
Normal file
4
mysql-test/r/3.23/rpl000002.result
Normal file
@ -0,0 +1,4 @@
|
||||
n
|
||||
2000
|
||||
2001
|
||||
2002
|
4
mysql-test/r/3.23/rpl000003.result
Normal file
4
mysql-test/r/3.23/rpl000003.result
Normal file
@ -0,0 +1,4 @@
|
||||
n
|
||||
1
|
||||
2
|
||||
3
|
2
mysql-test/r/3.23/rpl000004.a.result
Normal file
2
mysql-test/r/3.23/rpl000004.a.result
Normal file
@ -0,0 +1,2 @@
|
||||
Table Op Msg_type Msg_text
|
||||
test.words check status OK
|
2
mysql-test/r/3.23/rpl000004.b.result
Normal file
2
mysql-test/r/3.23/rpl000004.b.result
Normal file
@ -0,0 +1,2 @@
|
||||
count(*)
|
||||
45402
|
4
mysql-test/r/3.23/rpl000005.result
Normal file
4
mysql-test/r/3.23/rpl000005.result
Normal file
@ -0,0 +1,4 @@
|
||||
name age id
|
||||
Andy 31 00000001
|
||||
Jacob 2 00000002
|
||||
Caleb 1 00000003
|
2
mysql-test/r/3.23/rpl000006.result
Normal file
2
mysql-test/r/3.23/rpl000006.result
Normal file
@ -0,0 +1,2 @@
|
||||
unix_timestamp(t)
|
||||
200006
|
45402
mysql-test/std_data/words
Normal file
45402
mysql-test/std_data/words
Normal file
File diff suppressed because it is too large
Load Diff
15
mysql-test/t/3.23/rpl000001.test
Normal file
15
mysql-test/t/3.23/rpl000001.test
Normal file
@ -0,0 +1,15 @@
|
||||
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;
|
||||
|
11
mysql-test/t/3.23/rpl000002.test
Normal file
11
mysql-test/t/3.23/rpl000002.test
Normal file
@ -0,0 +1,11 @@
|
||||
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;
|
9
mysql-test/t/3.23/rpl000003.test
Normal file
9
mysql-test/t/3.23/rpl000003.test
Normal file
@ -0,0 +1,9 @@
|
||||
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;
|
18
mysql-test/t/3.23/rpl000004.test
Normal file
18
mysql-test/t/3.23/rpl000004.test
Normal file
@ -0,0 +1,18 @@
|
||||
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;
|
12
mysql-test/t/3.23/rpl000005.test
Normal file
12
mysql-test/t/3.23/rpl000005.test
Normal file
@ -0,0 +1,12 @@
|
||||
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;
|
12
mysql-test/t/3.23/rpl000006.test
Normal file
12
mysql-test/t/3.23/rpl000006.test
Normal file
@ -0,0 +1,12 @@
|
||||
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;
|
9
mysql-test/t/include/master-slave.inc
Normal file
9
mysql-test/t/include/master-slave.inc
Normal file
@ -0,0 +1,9 @@
|
||||
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)
|
||||
|
||||
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))
|
||||
{
|
||||
sql_print_error(
|
||||
|
@ -113,8 +113,15 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
|
||||
char *query=thd->query;
|
||||
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 &&
|
||||
(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;
|
||||
|
||||
@ -1083,6 +1090,7 @@ bool delayed_insert::handle_inserts(void)
|
||||
table->time_stamp=row->time_stamp;
|
||||
|
||||
info.handle_duplicates= row->dup;
|
||||
thd.net.last_errno = 0; // reset error for binlog
|
||||
if (write_record(table,&info))
|
||||
{
|
||||
info.error++; // Ignore errors
|
||||
|
Reference in New Issue
Block a user