1
0
mirror of https://github.com/MariaDB/server.git synced 2025-04-24 18:27:21 +03:00
mariadb/mysql-test/extra/rpl_tests/rpl_loaddata.test
Luis Soares a382917684 BUG#48297: Schema name is ignored when LOAD DATA is written into
binlog, replication aborts

In SBR or MBR, the schema name is not being written to the binlog
when executing a LOAD DATA statement. This becomes a problem when
the current database (lets call it db1) is different from the
table's schema (lets call it db2). For instance, take the
following statements:
  
  use db1;
  load data local infile 'infile.txt' into table db2.t

Should this statement be logged without t's schema (db2), when
replaying it, one can get db1.t populated instead of db2.t (if
db1.t exists). On the other hand, if there is no db1.t at all,
replication will stop.

We fix this by always logging the table (in load file) with fully
qualified name when its schema is different from the current
database or when no default database was selected.
2009-10-27 15:15:53 +00:00

223 lines
6.7 KiB
Plaintext

# Requires statement logging
-- source include/have_binlog_format_mixed_or_statement.inc
# See if replication of a "LOAD DATA in an autoincrement column"
# Honours autoincrement values
# i.e. if the master and slave have the same sequence
#
# check replication of load data for temporary tables with additional
# parameters
#
# check if duplicate entries trigger an error (they should unless IGNORE or
# REPLACE was used on the master) (bug 571).
#
# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986)
-- source include/master-slave.inc
source include/have_innodb.inc;
connection slave;
reset master;
connection master;
select last_insert_id();
create table t1(a int not null auto_increment, b int, primary key(a) );
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
# verify that LAST_INSERT_ID() is set by LOAD DATA INFILE
select last_insert_id();
create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60));
load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines;
create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60));
insert into t3 select * from t2;
save_master_pos;
connection slave;
sync_with_master;
select * from t1;
select * from t3;
connection master;
drop table t1;
drop table t2;
drop table t3;
create table t1(a int, b int, unique(b));
save_master_pos;
connection slave;
sync_with_master;
# See if slave stops when there's a duplicate entry for key error in LOAD DATA
insert into t1 values(1,10);
connection master;
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
save_master_pos;
connection slave;
# The SQL slave thread should be stopped now.
--source include/wait_for_slave_sql_to_stop.inc
# Skip the bad event and see if error is cleared in SHOW SLAVE STATUS by START
# SLAVE, even though we are not executing any event (as sql_slave_skip_counter
# takes us directly to the end of the relay log).
set global sql_slave_skip_counter=1;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# Trigger error again to test CHANGE MASTER
connection master;
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
save_master_pos;
connection slave;
# The SQL slave thread should be stopped now.
# Exec_Master_Log_Pos should point to the start of Execute event
# for last load data.
--source include/wait_for_slave_sql_to_stop.inc
# CHANGE MASTER and see if error is cleared in SHOW SLAVE STATUS.
stop slave;
change master to master_user='test';
change master to master_user='root';
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# Trigger error again to test RESET SLAVE
set global sql_slave_skip_counter=1;
start slave;
sync_with_master;
connection master;
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
load data infile '../../std_data/rpl_loaddata.dat' into table t1;
save_master_pos;
connection slave;
# The SQL slave thread should be stopped now.
--source include/wait_for_slave_sql_to_stop.inc
# RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS.
stop slave;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# Finally, see if logging is done ok on master for a failing LOAD DATA INFILE
connection master;
reset master;
eval create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
unique(day)) engine=$engine_type; # no transactions
--error ER_DUP_ENTRY
load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
'\n##\n' starting by '>' ignore 1 lines;
select * from t2;
save_master_pos;
connection slave;
start slave;
sync_with_master;
select * from t2;
# verify that if no error on slave, this is an error
alter table t2 drop key day;
connection master;
delete from t2;
--error ER_DUP_ENTRY
load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
'\n##\n' starting by '>' ignore 1 lines;
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
drop table t1, t2;
connection master;
drop table t1, t2;
# BUG#17233 LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed
CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
--error ER_DUP_ENTRY
LOAD DATA INFILE "../../std_data/words.dat" INTO TABLE t1;
DROP TABLE IF EXISTS t1;
# BUG#48297: Schema name is ignored when LOAD DATA is written into binlog,
# replication aborts
-- source include/master-slave-reset.inc
-- let $db1= b48297_db1
-- let $db2= b42897_db2
-- connection master
-- disable_warnings
-- eval drop database if exists $db1
-- eval drop database if exists $db2
-- enable_warnings
-- eval create database $db1
-- eval create database $db2
-- eval use $db1
-- eval CREATE TABLE t1 (c1 VARCHAR(256)) engine=$engine_type;
-- eval use $db2
-- echo ### assertion: works with cross-referenced database
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
-- eval use $db1
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- echo ### assertion: works with fully qualified name on current database
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
-- echo ### assertion: works without fully qualified name on current database
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1
-- echo ### create connection without default database
-- echo ### connect (conn2,localhost,root,,*NO-ONE*);
connect (conn2,localhost,root,,*NO-ONE*);
-- connection conn2
-- echo ### assertion: works without stating the default database
-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
-- echo ### disconnect and switch back to master connection
-- disconnect conn2
-- connection master
-- sync_slave_with_master
-- eval use $db1
let $diff_table_1=master:$db1.t1;
let $diff_table_2=slave:$db1.t1;
source include/diff_tables.inc;
-- connection master
-- eval DROP DATABASE $db1
-- eval DROP DATABASE $db2
-- sync_slave_with_master
# End of 4.1 tests