Commit b75eb1ee authored by bar@bar.myoffice.izhnet.ru's avatar bar@bar.myoffice.izhnet.ru

Merge abarkov@bk-internal.mysql.com:/home/bk/mysql-5.1-rpl

into  mysql.com:/home/bar/mysql-work/mysql-5.1.b27287
parents 015c00cc 8f7550ec
......@@ -126,7 +126,9 @@ drop table t1,t2;
#
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM;
CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb;
CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
#
......@@ -169,7 +171,7 @@ CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
select count(*) from t1 /* must be 2 */;
#
# UPDATE (multi-update see bug#27716)
# UPDATE inc multi-update
#
# prepare
......@@ -185,9 +187,48 @@ CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
source include/show_binlog_events.inc; # must be events of the query
select count(*) from t1 /* must be 2 */;
## multi_update::send_eof() branch
# prepare
delete from t3;
delete from t4;
insert into t3 values (1,1);
insert into t4 values (1,1),(2,2);
reset master;
# execute
--error ER_DUP_ENTRY
UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
# check
source include/show_binlog_events.inc; # the offset must denote there is the query
select count(*) from t1 /* must be 4 */;
## send_error() branch of multi_update
# prepare
delete from t1;
delete from t3;
delete from t4;
insert into t3 values (1,1),(2,2);
insert into t4 values (1,1),(2,2);
reset master;
# execute
--error ER_DUP_ENTRY
UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
# check
select count(*) from t1 /* must be 1 */;
# cleanup
drop table t4;
#
# DELETE (for multi-delete see Bug #29136)
# DELETE incl multi-delete
#
# prepare
......@@ -203,6 +244,27 @@ CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
# execute
--error ER_DUP_ENTRY
delete from t2;
# check
source include/show_binlog_events.inc; # the offset must denote there is the query
select count(*) from t1 /* must be 1 */;
# cleanup
drop trigger trg_del;
# prepare
delete from t1;
delete from t2;
delete from t5;
create trigger trg_del_t2 after delete on t2 for each row
insert into t1 values (1);
insert into t2 values (2),(3);
insert into t5 values (1),(2);
reset master;
# execute
--error ER_DUP_ENTRY
delete t2.* from t2,t5 where t2.a=t5.a + 1;
# check
source include/show_binlog_events.inc; # must be events of the query
select count(*) from t1 /* must be 1 */;
......@@ -229,6 +291,8 @@ CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
#
# bug#23333 cleanup
#
drop trigger trg_del;
drop table t1,t2,t3,t4;
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
drop function bug27417;
......@@ -466,7 +466,7 @@ binary data';
select * from t2 order by f1;
select * from t3 order by f1;
select * from t4 order by f1;
select * from t31 order by f1;
select * from t31 order by f3;
connection master;
......
###################################################
#Author: Sven
#Date: 2007-10-09
#Purpose: Wait until the slave has an error in the
# sql thread, as indicated by
# "SHOW SLAVE STATUS", or at most 30
# seconds.
#Details:
# 1) Fill in and setup variables
# 2) loop, looking for sql error on slave
# 3) If it loops too long, die.
####################################################
connection slave;
let $row_number= 1;
let $run= 1;
let $counter= 300;
while ($run)
{
let $sql_result= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, $row_number);
let $run= `SELECT '$sql_result' = '0'`;
if ($run) {
real_sleep 0.1;
if (!$counter){
--echo "Failed while waiting for slave to produce an error in its sql thread"
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 #
query_vertical SHOW SLAVE STATUS;
exit;
}
dec $counter;
}
}
......@@ -1086,6 +1086,19 @@ n d
1 30
2 20
drop table t1,t2;
drop table if exists t1, t2;
CREATE TABLE t1 (a int, PRIMARY KEY (a));
CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
create trigger trg_del_t2 after delete on t2 for each row
insert into t1 values (1);
insert into t1 values (1);
insert into t2 values (1),(2);
delete t2 from t2;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
select count(*) from t2 /* must be 2 as restored after rollback caused by the error */;
count(*)
2
drop table t1, t2;
create table t1 (a int, b int) engine=innodb;
insert into t1 values(20,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
......@@ -1751,10 +1764,10 @@ Variable_name Value
Innodb_page_size 16384
show status like "Innodb_rows_deleted";
Variable_name Value
Innodb_rows_deleted 70
Innodb_rows_deleted 71
show status like "Innodb_rows_inserted";
Variable_name Value
Innodb_rows_inserted 1083
Innodb_rows_inserted 1085
show status like "Innodb_rows_updated";
Variable_name Value
Innodb_rows_updated 886
......
......@@ -614,6 +614,7 @@ CREATE TABLE `t2` (
`b` int(11) default NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
set @sav_binlog_format= @@session.binlog_format;
set @@session.binlog_format= mixed;
insert into t1 values (1,1),(2,2);
insert into t2 values (1,1),(4,4);
......@@ -626,7 +627,7 @@ a b
4 4
show master status /* there must be the UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 197
master-bin.000001 268
delete from t1;
delete from t2;
insert into t1 values (1,2),(3,4),(4,4);
......@@ -636,6 +637,24 @@ UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
show master status /* there must be the UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 212
master-bin.000001 283
drop table t1, t2;
set @@session.binlog_format= @sav_binlog_format;
drop table if exists t1, t2, t3;
CREATE TABLE t1 (a int, PRIMARY KEY (a));
CREATE TABLE t2 (a int, PRIMARY KEY (a));
CREATE TABLE t3 (a int, PRIMARY KEY (a)) ENGINE=MyISAM;
create trigger trg_del_t3 before delete on t3 for each row insert into t1 values (1);
insert into t2 values (1),(2);
insert into t3 values (1),(2);
reset master;
delete t3.* from t2,t3 where t2.a=t3.a;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
select count(*) from t1 /* must be 1 */;
count(*)
1
select count(*) from t3 /* must be 1 */;
count(*)
1
drop table t1, t2, t3;
end of tests
......@@ -520,7 +520,9 @@ count(*)
drop table t1,t2;
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM;
CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb;
CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
insert into t2 values (1);
reset master;
insert into t2 values (bug27417(1));
......@@ -559,6 +561,33 @@ master-bin.000001 # Query # # use `test`; update t3 set b=b+bug27417(1)
select count(*) from t1 /* must be 2 */;
count(*)
2
delete from t3;
delete from t4;
insert into t3 values (1,1);
insert into t4 values (1,1),(2,2);
reset master;
UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=6
master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from t1 /* must be 4 */;
count(*)
4
delete from t1;
delete from t3;
delete from t4;
insert into t3 values (1,1),(2,2);
insert into t4 values (1,1),(2,2);
reset master;
UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
select count(*) from t1 /* must be 1 */;
count(*)
1
drop table t4;
delete from t1;
delete from t2;
delete from t3;
......@@ -571,12 +600,30 @@ delete from t2;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=6
master-bin.000001 # Intvar # # INSERT_ID=9
master-bin.000001 # Query # # use `test`; delete from t2
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from t1 /* must be 1 */;
count(*)
1
drop trigger trg_del;
delete from t1;
delete from t2;
delete from t5;
create trigger trg_del_t2 after delete on t2 for each row
insert into t1 values (1);
insert into t2 values (2),(3);
insert into t5 values (1),(2);
reset master;
delete t2.* from t2,t5 where t2.a=t5.a + 1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from t1 /* must be 1 */;
count(*)
1
delete from t1;
create table t4 (a int default 0, b int primary key) engine=innodb;
insert into t4 values (0, 17);
......@@ -591,11 +638,11 @@ count(*)
2
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=7
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=12
master-bin.000001 # Intvar # # INSERT_ID=7
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=1
master-bin.000001 # Query # # use `test`; ROLLBACK
drop trigger trg_del;
drop table t1,t2,t3,t4;
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
drop function bug27417;
......@@ -494,7 +494,9 @@ count(*)
drop table t1,t2;
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique);
CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM;
CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb;
CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
insert into t2 values (1);
reset master;
insert into t2 values (bug27417(1));
......@@ -533,6 +535,33 @@ master-bin.000001 # Query # # use `test`; update t3 set b=b+bug27417(1)
select count(*) from t1 /* must be 2 */;
count(*)
2
delete from t3;
delete from t4;
insert into t3 values (1,1);
insert into t4 values (1,1),(2,2);
reset master;
UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=6
master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from t1 /* must be 4 */;
count(*)
4
delete from t1;
delete from t3;
delete from t4;
insert into t3 values (1,1),(2,2);
insert into t4 values (1,1),(2,2);
reset master;
UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
select count(*) from t1 /* must be 1 */;
count(*)
1
drop table t4;
delete from t1;
delete from t2;
delete from t3;
......@@ -545,12 +574,30 @@ delete from t2;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=6
master-bin.000001 # Intvar # # INSERT_ID=9
master-bin.000001 # Query # # use `test`; delete from t2
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from t1 /* must be 1 */;
count(*)
1
drop trigger trg_del;
delete from t1;
delete from t2;
delete from t5;
create trigger trg_del_t2 after delete on t2 for each row
insert into t1 values (1);
insert into t2 values (2),(3);
insert into t5 values (1),(2);
reset master;
delete t2.* from t2,t5 where t2.a=t5.a + 1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from t1 /* must be 1 */;
count(*)
1
delete from t1;
create table t4 (a int default 0, b int primary key) engine=innodb;
insert into t4 values (0, 17);
......@@ -565,13 +612,13 @@ count(*)
2
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=7
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=12
master-bin.000001 # Intvar # # INSERT_ID=7
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=1
master-bin.000001 # Query # # use `test`; ROLLBACK
drop trigger trg_del;
drop table t1,t2,t3,t4;
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
drop function bug27417;
set @@session.binlog_format=@@global.binlog_format;
end of tests
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
show slave status /* Second_behind reports 0 */;;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port 9306
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos 106
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 106
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master 0
Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 0
Last_SQL_Error
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'
create table t1 (f1 int);
flush logs /* contaminate rli->last_master_timestamp */;
lock table t1 write;
insert into t1 values (1);
show slave status /* bug emulated: reports slave threads starting time about 3*3 not 3 secs */;;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port 9306
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos 367
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 279
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master 9
Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 0
Last_SQL_Error
unlock tables;
flush logs /* this time rli->last_master_timestamp is not affected */;
lock table t1 write;
insert into t1 values (2);
show slave status /* reports the correct diff with master query time about 3+3 secs */;;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port 9306
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos 455
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes
Slave_SQL_Running Yes
Replicate_Do_DB
Replicate_Ignore_DB
Replicate_Do_Table
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 367
Relay_Log_Space #
Until_Condition None
Until_Log_File
Until_Log_Pos 0
Master_SSL_Allowed No
Master_SSL_CA_File
Master_SSL_CA_Path
Master_SSL_Cert
Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master 7
Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 0
Last_SQL_Error
unlock tables;
drop table t1;
--loose-debug=d,let_first_flush_log_change_timestamp
#
# Testing replication delay reporting (bug#29309)
# there is an unavoidable non-determinism in the test
# please compare the results with the comments
#
source include/master-slave.inc;
connection master;
#connection slave;
sync_slave_with_master;
--replace_result $DEFAULT_MASTER_PORT DEFAULT_MASTER_PORT
--replace_column 1 # 8 # 9 # 23 #
--query_vertical show slave status /* Second_behind reports 0 */;
sleep 3;
### bug emulation
connection master;
drop table if exists t1;
create table t1 (f1 int);
sleep 3;
#connection slave;
sync_slave_with_master;
flush logs /* contaminate rli->last_master_timestamp */;
connection slave;
lock table t1 write;
connection master;
insert into t1 values (1);
sleep 3;
connection slave;
--replace_result $DEFAULT_MASTER_PORT DEFAULT_MASTER_PORT
--replace_column 1 # 8 # 9 # 23 #
--query_vertical show slave status /* bug emulated: reports slave threads starting time about 3*3 not 3 secs */;
unlock tables;
connection master;
sync_slave_with_master;
### bugfix
connection slave;
flush logs /* this time rli->last_master_timestamp is not affected */;
lock table t1 write;
connection master;
insert into t1 values (2);
sleep 3;
connection slave;
--replace_result $DEFAULT_MASTER_PORT DEFAULT_MASTER_PORT
--replace_column 1 # 8 # 9 # 23 #
--query_vertical show slave status /* reports the correct diff with master query time about 3+3 secs */;
unlock tables;
connection master;
drop table t1;
#connection slave;
sync_slave_with_master;
# End of tests
......@@ -13,4 +13,3 @@
rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master
rpl_auto_increment_11932 : Bug#29809 2007-07-16 ingo Slave SQL errors in warnings file
rpl_stm_extraColmaster_ndb : WL#3915 : Statement-based replication not supported in ndb. Enable test when supported.
rpl_row_extraColmaster_ndb : BUG#29549 : Replication of BLOBs fail for NDB
......@@ -344,5 +344,6 @@ FLUSH LOGS;
--exec rm $MYSQLTEST_VARDIR/tmp/local.sql
DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5;
sync_slave_with_master;
# End of 4.1 tests
......@@ -28,7 +28,7 @@ insert into t1 values(NULL,'new');
save_master_pos;
connection slave;
# wait until the slave tries to run the query, fails and aborts slave thread
wait_for_slave_to_stop;
source include/wait_for_slave_sql_error.inc;
select * from t1 order by n;
delete from t1 where n = 2;
--disable_warnings
......
......@@ -15,8 +15,6 @@ rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not r
rpl_ndb_2myisam : BUG#19227 Seems to pass currently
rpl_ndb_2other : BUG#21842 2007-08-30 tsmith test has never worked on bigendian (sol10-sparc-a, powermacg5
rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD
rpl_ndb_innodb2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue
rpl_ndb_myisam2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue
rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB
rpl_ndb_mix_innodb : BUG#28123 rpl_ndb_mix_innodb.test casue slave to core on sol10-sparc-a
rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset
......
......@@ -753,6 +753,38 @@ select * from t1;
select * from t2;
drop table t1,t2;
#
# Bug #29136 erred multi-delete on trans table does not rollback
#
# prepare
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
CREATE TABLE t1 (a int, PRIMARY KEY (a));
CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
create trigger trg_del_t2 after delete on t2 for each row
insert into t1 values (1);
insert into t1 values (1);
insert into t2 values (1),(2);
# exec cases A, B - see multi_update.test
# A. send_error() w/o send_eof() branch
--error ER_DUP_ENTRY
delete t2 from t2;
# check
select count(*) from t2 /* must be 2 as restored after rollback caused by the error */;
# cleanup bug#29136
drop table t1, t2;
#
# Testing of IFNULL
#
......
......@@ -588,6 +588,7 @@ CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
# as the test is about to see erroed queries in binlog
set @sav_binlog_format= @@session.binlog_format;
set @@session.binlog_format= mixed;
......@@ -614,5 +615,42 @@ show master status /* there must be the UPDATE query event */;
# cleanup bug#27716
drop table t1, t2;
set @@session.binlog_format= @sav_binlog_format;
#
# Bug #29136 erred multi-delete on trans table does not rollback
#
# prepare
--disable_warnings
drop table if exists t1, t2, t3;
--enable_warnings
CREATE TABLE t1 (a int, PRIMARY KEY (a));
CREATE TABLE t2 (a int, PRIMARY KEY (a));
CREATE TABLE t3 (a int, PRIMARY KEY (a)) ENGINE=MyISAM;
create trigger trg_del_t3 before delete on t3 for each row insert into t1 values (1);
insert into t2 values (1),(2);
insert into t3 values (1),(2);
reset master;
# exec cases B, A - see innodb.test
# B. send_eof() and send_error() afterward
--error ER_DUP_ENTRY
delete t3.* from t2,t3 where t2.a=t3.a;
# check
select count(*) from t1 /* must be 1 */;
select count(*) from t3 /* must be 1 */;
# cleanup bug#29136
drop table t1, t2, t3;
#
# Add further tests from here
#
--echo end of tests
......@@ -3,7 +3,8 @@
# Simple test for the partition storage engine
# Taken fromm the select test
#
-- source include/have_partition.inc
source include/have_partition.inc;
source include/have_archive.inc;
--disable_warnings
drop table if exists t1;
......
This diff is collapsed.
This diff is collapsed.
......@@ -3577,9 +3577,6 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
(!binlog_filter->db_ok(local_db)))
{
VOID(pthread_mutex_unlock(&LOCK_log));
DBUG_PRINT("info",("OPTION_BIN_LOG is %s, db_ok('%s') == %d",
(thd->options & OPTION_BIN_LOG) ? "set" : "clear",
local_db, binlog_filter->db_ok(local_db)));
DBUG_RETURN(0);
}
#endif /* HAVE_REPLICATION */
......
......@@ -114,6 +114,9 @@ private:
flag_set m_flags;
};
#ifndef DBUG_OFF
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
#endif
/*
pretty_print_str()
......@@ -555,8 +558,32 @@ int Log_event::do_update_pos(Relay_log_info *rli)
Matz: I don't think we will need this check with this refactoring.
*/
if (rli)
rli->stmt_done(log_pos, when);
{
/*
bug#29309 simulation: resetting the flag to force
wrong behaviour of artificial event to update
rli->last_master_timestamp for only one time -
the first FLUSH LOGS in the test.
*/
DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
if (debug_not_change_ts_if_art_event == 1
&& is_artificial_event())
{
debug_not_change_ts_if_art_event= 0;
});
#ifndef DBUG_OFF
rli->stmt_done(log_pos,
is_artificial_event() &&
debug_not_change_ts_if_art_event > 0 ? 0 : when);
#else
rli->stmt_done(log_pos, is_artificial_event()? 0 : when);
#endif
DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
if (debug_not_change_ts_if_art_event == 0)
{
debug_not_change_ts_if_art_event= 2;
});
}
return 0; // Cannot fail currently
}
......
......@@ -65,6 +65,8 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
my_ptrdiff_t const rec_offset= record - table->record[0];
my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
DBUG_ENTER("pack_row");
/*
We write the null bits and the packed records using one pass
through all the fields. The null bytes are written little-endian,
......@@ -96,26 +98,14 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
For big-endian machines, we have to make sure that the
length is stored in little-endian format, since this is the
format used for the binlog.
We do this by setting the db_low_byte_first, which is used
inside some store_length() to decide what order to write the
bytes in.
In reality, db_log_byte_first is only set for legacy table
type Isam, but in the event of a bug, we need to guarantee
the endianess when writing to the binlog.
This is currently broken for NDB due to BUG#29549, so we
will fix it when NDB has fixed their way of handling BLOBs.
*/
#if 0
bool save= table->s->db_low_byte_first;
table->s->db_low_byte_first= TRUE;
#endif
pack_ptr= field->pack(pack_ptr, field->ptr + offset);
#if 0
table->s->db_low_byte_first= save;
#endif
const uchar *old_pack_ptr= pack_ptr;
pack_ptr= field->pack(pack_ptr, field->ptr + offset,
field->max_data_length(), TRUE);
DBUG_PRINT("debug", ("field: %s; pack_ptr: 0x%lx;"
" pack_ptr':0x%lx; bytes: %d",
field->field_name, (ulong) old_pack_ptr,
(ulong) pack_ptr, pack_ptr - old_pack_ptr));
}
null_mask <<= 1;
......@@ -143,8 +133,8 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
packed data. If it doesn't, something is very wrong.
*/
DBUG_ASSERT(null_ptr == row_data + null_byte_count);
return static_cast<size_t>(pack_ptr - row_data);
DBUG_DUMP("row_data", row_data, pack_ptr - row_data);
DBUG_RETURN(static_cast<size_t>(pack_ptr - row_data));
}
#endif
......@@ -242,18 +232,14 @@ unpack_row(Relay_log_info const *rli,
Use the master's size information if available else call
normal unpack operation.
*/
#if 0
bool save= table->s->db_low_byte_first;
table->s->db_low_byte_first= TRUE;
#endif
uint16 const metadata= tabledef->field_metadata(i);
if (tabledef && metadata)
pack_ptr= f->unpack(f->ptr, pack_ptr, metadata);
else
pack_ptr= f->unpack(f->ptr, pack_ptr);
#if 0
table->s->db_low_byte_first= save;
#endif
uchar const *const old_pack_ptr= pack_ptr;
pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, TRUE);
DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;"
" pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d",
f->field_name, metadata,
(ulong) old_pack_ptr, (ulong) pack_ptr,
pack_ptr - old_pack_ptr));
}
null_mask <<= 1;
......@@ -289,6 +275,8 @@ unpack_row(Relay_log_info const *rli,
*/
DBUG_ASSERT(null_ptr == row_data + master_null_byte_count);
DBUG_DUMP("row_data", row_data, pack_ptr - row_data);
*row_end = pack_ptr;
if (master_reclength)
{
......
......@@ -1082,6 +1082,9 @@ bool Relay_log_info::cached_charset_compare(char *charset) const
void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
time_t event_creation_time)
{
#ifndef DBUG_OFF
extern uint debug_not_change_ts_if_art_event;
#endif
clear_flag(IN_STMT);
/*
......@@ -1121,7 +1124,12 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
is that value may take some time to display in
Seconds_Behind_Master - not critical).
*/
last_master_timestamp= event_creation_time;
#ifndef DBUG_OFF
if (!(event_creation_time == 0 && debug_not_change_ts_if_art_event > 0))
#else
if (event_creation_time != 0)
#endif
last_master_timestamp= event_creation_time;
}
}
......
......@@ -3581,7 +3581,16 @@ static Log_event* next_event(Relay_log_info* rli)
a new event and is queuing it; the false "0" will exist until SQL
finishes executing the new event; it will be look abnormal only if
the events have old timestamps (then you get "many", 0, "many").
Transient phases like this can't really be fixed.
Transient phases like this can be fixed with implemeting
Heartbeat event which provides the slave the status of the
master at time the master does not have any new update to send.
Seconds_Behind_Master would be zero only when master has no
more updates in binlog for slave. The heartbeat can be sent
in a (small) fraction of slave_net_timeout. Until it's done
rli->last_master_timestamp is temporarely (for time of
waiting for the following event) reset whenever EOF is
reached.
*/
time_t save_timestamp= rli->last_master_timestamp;
rli->last_master_timestamp= 0;
......
......@@ -2436,6 +2436,11 @@ class multi_delete :public select_result_interceptor
/* True if at least one table we delete from is not transactional */
bool normal_tables;
bool delete_while_scanning;
/*
error handling (rollback and binlogging) can happen in send_eof()
so that afterward send_error() needs to find out that.
*/
bool error_handled;
public:
multi_delete(TABLE_LIST *dt, uint num_of_tables);
......@@ -2471,6 +2476,11 @@ class multi_update :public select_result_interceptor
/* True if the update operation has made a change in a transactional table */
bool transactional_tables;
bool ignore;
/*
error handling (rollback and binlogging) can happen in send_eof()
so that afterward send_error() needs to find out that.
*/
bool error_handled;
public:
multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list,
......
......@@ -541,7 +541,7 @@ bool mysql_multi_delete_prepare(THD *thd)
multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
: delete_tables(dt), deleted(0), found(0),
num_of_tables(num_of_tables_arg), error(0),
do_delete(0), transactional_tables(0), normal_tables(0)
do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
{
tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
}
......@@ -720,12 +720,14 @@ void multi_delete::send_error(uint errcode,const char *err)
/* First send error what ever it is ... */
my_message(errcode, err, MYF(0));
/* If nothing deleted return */
if (!deleted)
/* the error was handled or nothing deleted and no side effects return */
if (error_handled ||
!thd->transaction.stmt.modified_non_trans_table && !deleted)
DBUG_VOID_RETURN;
/* Something already deleted so we have to invalidate cache */
query_cache_invalidate3(thd, delete_tables, 1);
if (deleted)
query_cache_invalidate3(thd, delete_tables, 1);
/*
If rows from the first table only has been deleted and it is
......@@ -745,12 +747,29 @@ void multi_delete::send_error(uint errcode,const char *err)
*/
error= 1;
send_eof();
DBUG_ASSERT(error_handled);
DBUG_VOID_RETURN;
}
if (thd->transaction.stmt.modified_non_trans_table)
{
/*
there is only side effects; to binlog with the error
*/
if (mysql_bin_log.is_open())
{
thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE);
}
thd->transaction.all.modified_non_trans_table= true;
}
DBUG_ASSERT(!normal_tables || !deleted || thd->transaction.stmt.modified_non_trans_table);
DBUG_VOID_RETURN;
}
/*
Do delete from other tables.
Returns values:
......@@ -880,6 +899,8 @@ bool multi_delete::send_eof()
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
}
if (local_error != 0)
error_handled= TRUE; // to force early leave from ::send_error()
/* Commit or rollback the current SQL statement */
if (transactional_tables)
......
......@@ -2919,6 +2919,13 @@ end_with_restore_list:
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE,
del_result, unit, select_lex);
res|= thd->net.report_error;
if (unlikely(res))
{
/* If we had a another error reported earlier then this will be ignored */
del_result->send_error(ER_UNKNOWN_ERROR, "Execution of the query failed");
del_result->abort();
}
delete del_result;
}
else
......
......@@ -29,6 +29,8 @@
#include "event_data_objects.h"
#include <my_dir.h>
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
#endif
......@@ -3115,8 +3117,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
schema_table_idx= get_schema_table_idx(schema_table);
get_lookup_field_values(thd, cond, tables, &lookup_field_vals);
DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
lookup_field_vals.db_value.str,
lookup_field_vals.table_value.str));
STR_OR_NIL(lookup_field_vals.db_value.str),
STR_OR_NIL(lookup_field_vals.table_value.str)));
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
{
......
......@@ -1215,8 +1215,8 @@ multi_update::multi_update(TABLE_LIST *table_list,
:all_tables(table_list), leaves(leaves_list), update_tables(0),
tmp_tables(0), updated(0), found(0), fields(field_list),
values(value_list), table_count(0), copy_field(0),
handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(0),
transactional_tables(1), ignore(ignore_arg)
handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
transactional_tables(1), ignore(ignore_arg), error_handled(0)
{}
......@@ -1418,7 +1418,6 @@ multi_update::initialize_tables(JOIN *join)
if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
DBUG_RETURN(1);
main_table=join->join_tab->table;
trans_safe= transactional_tables= main_table->file->has_transactions();
table_to_update= 0;
/* Any update has at least one pair (field, value) */
......@@ -1713,12 +1712,14 @@ void multi_update::send_error(uint errcode,const char *err)
/* First send error what ever it is ... */
my_error(errcode, MYF(0), err);
/* If nothing updated return */
if (updated == 0) /* the counter might be reset in send_eof */
return; /* and then the query has been binlogged */
/* the error was handled or nothing deleted and no side effects return */
if (error_handled ||
!thd->transaction.stmt.modified_non_trans_table && !updated)
return;
/* Something already updated so we have to invalidate cache */
query_cache_invalidate3(thd, update_tables, 1);
if (updated)
query_cache_invalidate3(thd, update_tables, 1);
/*
If all tables that has been updated are trans safe then just do rollback.
If not attempt to do remaining updates.
......@@ -1754,8 +1755,7 @@ void multi_update::send_error(uint errcode,const char *err)
thd->query, thd->query_length,
transactional_tables, FALSE);
}
if (!trans_safe)
thd->transaction.all.modified_non_trans_table= TRUE;
thd->transaction.all.modified_non_trans_table= TRUE;
}
DBUG_ASSERT(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
......@@ -1978,8 +1978,6 @@ bool multi_update::send_eof()
{
if (local_error == 0)
thd->clear_error();
else
updated= 0; /* if there's an error binlog it here not in ::send_error */
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE) &&
......@@ -1991,6 +1989,8 @@ bool multi_update::send_eof()
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
}
if (local_error != 0)
error_handled= TRUE; // to force early leave from ::send_error()
if (transactional_tables)
{
......
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