diff options
author | unknown <mats@mats-laptop.(none)> | 2008-05-15 21:04:13 +0200 |
---|---|---|
committer | unknown <mats@mats-laptop.(none)> | 2008-05-15 21:04:13 +0200 |
commit | 439cbe54cbbceaea54eb1227523cb885a16362d0 (patch) | |
tree | 46bb81f5803cf997aa92066b445669062669922b | |
parent | 4f706f3336f7e967216220e7b3e4ee785feec23c (diff) | |
parent | d2a75dc900fb45de27a749d030865e9f95f9e57b (diff) | |
download | mariadb-git-439cbe54cbbceaea54eb1227523cb885a16362d0.tar.gz |
Merge mats-laptop.(none):/home/bkroot/mysql-5.1-bugteam
into mats-laptop.(none):/home/bk/b36197-mysql-5.1-bugteam
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_found_rows.result | 233 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result | 59 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_found_rows.test | 256 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_slave_status.test | 59 | ||||
-rw-r--r-- | sql/log_event.cc | 173 | ||||
-rw-r--r-- | sql/log_event_old.cc | 99 | ||||
-rw-r--r-- | sql/sql_base.cc | 7 |
7 files changed, 74 insertions, 812 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_found_rows.result b/mysql-test/suite/rpl/r/rpl_found_rows.result deleted file mode 100644 index 7e757a1d141..00000000000 --- a/mysql-test/suite/rpl/r/rpl_found_rows.result +++ /dev/null @@ -1,233 +0,0 @@ -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; -==== 0. Setting it all up ==== -SET BINLOG_FORMAT=STATEMENT; -**** On Master **** -CREATE TABLE t1 (a INT); -CREATE TABLE logtbl (sect INT, test INT, count INT); -INSERT INTO t1 VALUES (1),(2),(3); -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -#### 1. Using statement mode #### -==== 1.1. Simple test ==== -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -a -7 -SELECT FOUND_ROWS() INTO @a; -INSERT INTO logtbl VALUES(1,1,@a); -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -a -1 -SELECT FOUND_ROWS() INTO @a; -INSERT INTO logtbl VALUES(1,2,@a); -SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; -sect test count -1 1 183 -1 2 3 -**** On Slave **** -SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; -sect test count -1 1 183 -1 2 3 -==== 1.2. Stored procedure ==== -**** On Master **** -CREATE PROCEDURE calc_and_log(sect INT, test INT) BEGIN -DECLARE cnt INT; -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -SELECT FOUND_ROWS() INTO cnt; -INSERT INTO logtbl VALUES(sect,test,cnt); -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -SELECT FOUND_ROWS() INTO cnt; -INSERT INTO logtbl VALUES(sect,test+1,cnt); -END $$ -CALL calc_and_log(2,1); -a -1 -a -7 -CREATE PROCEDURE just_log(sect INT, test INT, found_rows INT) BEGIN -INSERT INTO logtbl VALUES (sect,test,found_rows); -END $$ -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -a -7 -SELECT FOUND_ROWS() INTO @found_rows; -CALL just_log(2,3,@found_rows); -SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; -sect test count -2 1 3 -2 2 183 -2 3 183 -**** On Slave **** -SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; -sect test count -2 1 3 -2 2 183 -2 3 183 -==== 1.3. Stored functions ==== -**** On Master **** -CREATE FUNCTION log_rows(sect INT, test INT, found_rows INT) -RETURNS INT -BEGIN -INSERT INTO logtbl VALUES(sect,test,found_rows); -RETURN found_rows; -END $$ -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -a -7 -SELECT FOUND_ROWS() INTO @found_rows; -SELECT log_rows(3,1,@found_rows), log_rows(3,2,@found_rows); -log_rows(3,1,@found_rows) log_rows(3,2,@found_rows) -183 183 -SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test; -sect test count -3 1 183 -3 2 183 -**** On Slave **** -SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test; -sect test count -3 1 183 -3 2 183 -==== 1.9. Cleanup ==== -**** On Master **** -DELETE FROM logtbl; -DROP PROCEDURE just_log; -DROP PROCEDURE calc_and_log; -DROP FUNCTION log_rows; -**** Resetting master and slave **** -STOP SLAVE; -RESET SLAVE; -RESET MASTER; -START SLAVE; -#### 2. Using mixed mode #### -==== 2.1. Checking a procedure ==== -**** On Master **** -SET BINLOG_FORMAT=MIXED; -CREATE PROCEDURE just_log(sect INT, test INT) BEGIN -INSERT INTO logtbl VALUES (sect,test,FOUND_ROWS()); -END $$ -**** On Master 1 **** -SET BINLOG_FORMAT=MIXED; -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -a -7 -CALL just_log(1,1); -**** On Master **** -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -a -7 -CALL just_log(1,2); -**** On Master 1 **** -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -a -1 -CALL just_log(1,3); -**** On Master **** -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -a -7 -CALL just_log(1,4); -SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; -sect test count -1 1 183 -1 2 183 -1 3 3 -1 4 183 -**** On Slave **** -SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; -sect test count -1 1 183 -1 2 183 -1 3 3 -1 4 183 -==== 2.1. Checking a stored function ==== -**** On Master **** -CREATE FUNCTION log_rows(sect INT, test INT) -RETURNS INT -BEGIN -DECLARE found_rows INT; -SELECT FOUND_ROWS() INTO found_rows; -INSERT INTO logtbl VALUES(sect,test,found_rows); -RETURN found_rows; -END $$ -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -a -1 -SELECT log_rows(2,1), log_rows(2,2); -log_rows(2,1) log_rows(2,2) -3 3 -CREATE TABLE t2 (a INT, b INT); -CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW -BEGIN -INSERT INTO logtbl VALUES (NEW.a, NEW.b, FOUND_ROWS()); -END $$ -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -a -1 -INSERT INTO t2 VALUES (2,3), (2,4); -DROP TRIGGER t2_tr; -CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW -BEGIN -DECLARE dummy INT; -SELECT log_rows(NEW.a, NEW.b) INTO dummy; -END $$ -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -a -7 -INSERT INTO t2 VALUES (2,5), (2,6); -DROP TRIGGER t2_tr; -CREATE PROCEDURE log_me_inner(sect INT, test INT) -BEGIN -DECLARE dummy INT; -SELECT log_rows(sect, test) INTO dummy; -SELECT log_rows(sect, test+1) INTO dummy; -END $$ -CREATE PROCEDURE log_me(sect INT, test INT) -BEGIN -CALL log_me_inner(sect,test); -END $$ -CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW -BEGIN -CALL log_me(NEW.a, NEW.b); -END $$ -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -a -7 -INSERT INTO t2 VALUES (2,5), (2,6); -SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; -sect test count -2 1 3 -2 2 3 -2 3 3 -2 4 3 -2 5 183 -2 5 183 -2 6 183 -2 6 0 -2 6 183 -2 7 0 -SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; -sect test count -2 1 3 -2 2 3 -2 3 3 -2 4 3 -2 5 183 -2 5 183 -2 6 183 -2 6 0 -2 6 183 -2 7 0 -DROP TABLE t1, logtbl; -DROP PROCEDURE just_log; -DROP PROCEDURE log_me; -DROP PROCEDURE log_me_inner; -DROP FUNCTION log_rows; diff --git a/mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result b/mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result deleted file mode 100644 index 71c825183f7..00000000000 --- a/mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result +++ /dev/null @@ -1,59 +0,0 @@ -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; -create table t1 (a int not null primary key); -insert into t1 values (1); -create table t2 (a int); -insert into t2 values (1); -update t1, t2 set t1.a = 0 where t1.a = t2.a; -show tables; -Tables_in_test -t1 -select * from t1; -a -0 -drop table t1; -insert into t1 values (1); -SHOW SLAVE STATUS; -Slave_IO_State # -Master_Host 127.0.0.1 -Master_User root -Master_Port MASTER_PORT -Connect_Retry 1 -Master_Log_File master-bin.000001 -Read_Master_Log_Pos 1153 -Relay_Log_File # -Relay_Log_Pos # -Relay_Master_Log_File master-bin.000001 -Slave_IO_Running Yes -Slave_SQL_Running No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table # -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1146 -Last_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1` -Skip_Counter 0 -Exec_Master_Log_Pos 941 -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 # -Master_SSL_Verify_Server_Cert No -Last_IO_Errno # -Last_IO_Error # -Last_SQL_Errno 1146 -Last_SQL_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1` -drop table t1, t2; diff --git a/mysql-test/suite/rpl/t/rpl_found_rows.test b/mysql-test/suite/rpl/t/rpl_found_rows.test deleted file mode 100644 index f868061c951..00000000000 --- a/mysql-test/suite/rpl/t/rpl_found_rows.test +++ /dev/null @@ -1,256 +0,0 @@ -source include/master-slave.inc; - -# It is not possible to replicate FOUND_ROWS() using statement-based -# replication, but there is a workaround that stores the result of -# FOUND_ROWS() into a user variable and then replicates this instead. - -# The purpose of this test case is to test that the workaround -# function properly even when inside stored programs (i.e., stored -# routines and triggers). - ---echo ==== 0. Setting it all up ==== - -SET BINLOG_FORMAT=STATEMENT; - ---echo **** On Master **** -connection master; -CREATE TABLE t1 (a INT); -CREATE TABLE logtbl (sect INT, test INT, count INT); - -INSERT INTO t1 VALUES (1),(2),(3); -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; -INSERT INTO t1 SELECT 2*a+3 FROM t1; - ---echo #### 1. Using statement mode #### - ---echo ==== 1.1. Simple test ==== - -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; - -# Instead of -# INSERT INTO logtbl VALUES(1, 1, FOUND_ROWS()); -# we write -SELECT FOUND_ROWS() INTO @a; -INSERT INTO logtbl VALUES(1,1,@a); - -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -# Instead of -# INSERT INTO logtbl VALUES(1, 2, FOUND_ROWS()); -# we write -SELECT FOUND_ROWS() INTO @a; -INSERT INTO logtbl VALUES(1,2,@a); - -SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; ---echo **** On Slave **** -sync_slave_with_master; -SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; - ---echo ==== 1.2. Stored procedure ==== - -# Here we do both the calculation and the logging. We also do it twice -# to make sure that there are no limitations on how many times it can -# be used. - ---echo **** On Master **** -connection master; ---delimiter $$ -CREATE PROCEDURE calc_and_log(sect INT, test INT) BEGIN - DECLARE cnt INT; - SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; - SELECT FOUND_ROWS() INTO cnt; - INSERT INTO logtbl VALUES(sect,test,cnt); - SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; - SELECT FOUND_ROWS() INTO cnt; - INSERT INTO logtbl VALUES(sect,test+1,cnt); -END $$ ---delimiter ; - -CALL calc_and_log(2,1); - ---delimiter $$ -CREATE PROCEDURE just_log(sect INT, test INT, found_rows INT) BEGIN - INSERT INTO logtbl VALUES (sect,test,found_rows); -END $$ ---delimiter ; - -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -SELECT FOUND_ROWS() INTO @found_rows; -CALL just_log(2,3,@found_rows); - -SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; ---echo **** On Slave **** -sync_slave_with_master; -SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; - ---echo ==== 1.3. Stored functions ==== ---echo **** On Master **** -connection master; ---delimiter $$ -CREATE FUNCTION log_rows(sect INT, test INT, found_rows INT) - RETURNS INT -BEGIN - INSERT INTO logtbl VALUES(sect,test,found_rows); - RETURN found_rows; -END $$ ---delimiter ; - -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -SELECT FOUND_ROWS() INTO @found_rows; -SELECT log_rows(3,1,@found_rows), log_rows(3,2,@found_rows); - -SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test; ---echo **** On Slave **** -sync_slave_with_master; -SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test; - ---echo ==== 1.9. Cleanup ==== ---echo **** On Master **** -connection master; -DELETE FROM logtbl; -DROP PROCEDURE just_log; -DROP PROCEDURE calc_and_log; -DROP FUNCTION log_rows; -sync_slave_with_master; - -source include/reset_master_and_slave.inc; - ---echo #### 2. Using mixed mode #### - ---echo ==== 2.1. Checking a procedure ==== - ---echo **** On Master **** -connection master; -SET BINLOG_FORMAT=MIXED; - -# We will now check some stuff that will not work in statement-based -# replication, but which should cause the binary log to switch to -# row-based logging. - ---delimiter $$ -CREATE PROCEDURE just_log(sect INT, test INT) BEGIN - INSERT INTO logtbl VALUES (sect,test,FOUND_ROWS()); -END $$ ---delimiter ; -sync_slave_with_master; - ---echo **** On Master 1 **** -connection master1; -SET BINLOG_FORMAT=MIXED; -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -CALL just_log(1,1); - ---echo **** On Master **** -connection master; -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -CALL just_log(1,2); - ---echo **** On Master 1 **** - -connection master1; -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -CALL just_log(1,3); -sync_slave_with_master; - ---echo **** On Master **** -connection master; -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -CALL just_log(1,4); -sync_slave_with_master; - -connection master; -SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; ---echo **** On Slave **** -sync_slave_with_master; -SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; - ---echo ==== 2.1. Checking a stored function ==== ---echo **** On Master **** -connection master; ---delimiter $$ -CREATE FUNCTION log_rows(sect INT, test INT) - RETURNS INT -BEGIN - DECLARE found_rows INT; - SELECT FOUND_ROWS() INTO found_rows; - INSERT INTO logtbl VALUES(sect,test,found_rows); - RETURN found_rows; -END $$ ---delimiter ; - -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -SELECT log_rows(2,1), log_rows(2,2); - -CREATE TABLE t2 (a INT, b INT); - -# Trying with referencing FOUND_ROWS() directly in the trigger. - ---delimiter $$ -CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW -BEGIN - INSERT INTO logtbl VALUES (NEW.a, NEW.b, FOUND_ROWS()); -END $$ ---delimiter ; - -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; -INSERT INTO t2 VALUES (2,3), (2,4); - -# Referencing FOUND_ROWS() indirectly. - -DROP TRIGGER t2_tr; - ---delimiter $$ -CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW -BEGIN - DECLARE dummy INT; - SELECT log_rows(NEW.a, NEW.b) INTO dummy; -END $$ ---delimiter ; - -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -INSERT INTO t2 VALUES (2,5), (2,6); - -# Putting FOUND_ROWS() even lower in the call chain. - -connection master; -DROP TRIGGER t2_tr; - ---delimiter $$ -CREATE PROCEDURE log_me_inner(sect INT, test INT) -BEGIN - DECLARE dummy INT; - SELECT log_rows(sect, test) INTO dummy; - SELECT log_rows(sect, test+1) INTO dummy; -END $$ - -CREATE PROCEDURE log_me(sect INT, test INT) -BEGIN - CALL log_me_inner(sect,test); -END $$ ---delimiter ; - ---delimiter $$ -CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW -BEGIN - CALL log_me(NEW.a, NEW.b); -END $$ ---delimiter ; - -SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; -INSERT INTO t2 VALUES (2,5), (2,6); - -SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; -sync_slave_with_master; -SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; - -connection master; -DROP TABLE t1, logtbl; -DROP PROCEDURE just_log; -DROP PROCEDURE log_me; -DROP PROCEDURE log_me_inner; -DROP FUNCTION log_rows; -sync_slave_with_master; - diff --git a/mysql-test/suite/rpl/t/rpl_slave_status.test b/mysql-test/suite/rpl/t/rpl_slave_status.test deleted file mode 100644 index 0b1644ab8a0..00000000000 --- a/mysql-test/suite/rpl/t/rpl_slave_status.test +++ /dev/null @@ -1,59 +0,0 @@ ---source include/master-slave.inc - -############################################################################ -# Test case for BUG#10780 -# -# REQUIREMENT -# A slave without replication privileges should have Slave_IO_Running = No - -# 1. Create new replication user -connection master; -grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl'; - -connection slave; -stop slave; -change master to master_user='rpl',master_password='rpl'; -start slave; - -# 2. Do replication as new user -connection master; ---disable_warnings -drop table if exists t1; ---enable_warnings -create table t1 (n int); -insert into t1 values (1); -save_master_pos; -connection slave; -sync_with_master; -select * from t1; - -# 3. Delete new replication user -connection master; -delete from mysql.user where user='rpl'; -flush privileges; -connection slave; - -# 4. Restart slave without privileges -# (slave.err will contain access denied error for this START SLAVE command) -stop slave; -start slave; - -# 5. Make sure Slave_IO_Running = No ---replace_result $MASTER_MYPORT MASTER_MYPORT -# Column 1 is replaced, since the output can be either -# "Connecting to master" or "Waiting for master update" ---replace_column 1 # 7 # 8 # 9 # 22 # 23 # 35 # 36 # ---vertical_results -show slave status; - -# Cleanup (Note that slave IO thread is not running) -connection slave; -drop table t1; -delete from mysql.user where user='rpl'; -# cleanup: slave io thread has been stopped "irrecoverably" -# so we clean up mess manually - -connection master; -drop table t1; - -# end of 4.1 tests diff --git a/sql/log_event.cc b/sql/log_event.cc index 6b0e19f27cb..fc63b3b05f9 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6425,15 +6425,29 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) */ if (!thd->lock) { - bool need_reopen= 1; /* To execute the first lap of the loop below */ - /* - lock_tables() reads the contents of thd->lex, so they must be - initialized. Contrary to in - Table_map_log_event::do_apply_event() we don't call - mysql_init_query() as that may reset the binlog format. + Lock_tables() reads the contents of thd->lex, so they must be + initialized. + + We also call the mysql_reset_thd_for_next_command(), since this + is the logical start of the next "statement". Note that this + call might reset the value of current_stmt_binlog_row_based, so + we need to do any changes to that value after this function. */ lex_start(thd); + mysql_reset_thd_for_next_command(thd); + + /* + Check if the slave is set to use SBR. If so, it should switch + to using RBR until the end of the "statement", i.e., next + STMT_END_F or next error. + */ + if (!thd->current_stmt_binlog_row_based && + mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG)) + { + thd->set_current_stmt_binlog_row_based(); + } + /* There are a few flags that are replicated with each row event. @@ -6452,72 +6466,23 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) /* A small test to verify that objects have consistent types */ DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS)); - - while ((error= lock_tables(thd, rli->tables_to_lock, - rli->tables_to_lock_count, &need_reopen))) + if (simple_open_n_lock_tables(thd, rli->tables_to_lock)) { - if (!need_reopen) - { - if (thd->is_slave_error || thd->is_fatal_error) - { - /* - Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) - */ - uint actual_error= thd->main_da.sql_errno(); - rli->report(ERROR_LEVEL, actual_error, - "Error '%s' in %s event: when locking tables", - (actual_error ? thd->main_da.message(): - "unexpected success or fatal error"), - get_type_str()); - thd->is_fatal_error= 1; - } - else - { - rli->report(ERROR_LEVEL, error, - "Error in %s event: when locking tables", - get_type_str()); - } - const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); - DBUG_RETURN(error); - } - - /* - So we need to reopen the tables. - - We need to flush the pending RBR event, since it keeps a - pointer to an open table. - - ALTERNATIVE SOLUTION (not implemented): Extract a pointer to - the pending RBR event and reset the table pointer after the - tables has been reopened. - - NOTE: For this new scheme there should be no pending event: - need to add code to assert that is the case. - */ - thd->binlog_flush_pending_rows_event(false); - TABLE_LIST *tables= rli->tables_to_lock; - close_tables_for_reopen(thd, &tables); - - uint tables_count= rli->tables_to_lock_count; - if ((error= open_tables(thd, &tables, &tables_count, 0))) + uint actual_error= thd->main_da.sql_errno(); + if (thd->is_slave_error || thd->is_fatal_error) { - if (thd->is_slave_error || thd->is_fatal_error) - { - /* - Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) - */ - uint actual_error= thd->main_da.sql_errno(); - rli->report(ERROR_LEVEL, actual_error, - "Error '%s' on reopening tables", - (actual_error ? thd->main_da.message() : - "unexpected success or fatal error")); - thd->is_slave_error= 1; - } - const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); - DBUG_RETURN(error); + /* + Error reporting borrowed from Query_log_event with many excessive + simplifications (we don't honour --slave-skip-errors) + */ + rli->report(ERROR_LEVEL, actual_error, + "Error '%s' on opening tables", + (actual_error ? thd->main_da.message() : + "unexpected success or fatal error")); + thd->is_slave_error= 1; } + const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); + DBUG_RETURN(actual_error); } /* @@ -6570,6 +6535,8 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) table= m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id); + DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %lu", (ulong) m_table, m_table_id)); + if (table) { /* @@ -7293,71 +7260,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) } else { - /* - open_tables() reads the contents of thd->lex, so they must be - initialized, so we should call lex_start(); to be even safer, we - call mysql_init_query() which does a more complete set of inits. - */ - lex_start(thd); - mysql_reset_thd_for_next_command(thd); - /* - Check if the slave is set to use SBR. If so, it should switch - to using RBR until the end of the "statement", i.e., next - STMT_END_F or next error. - */ - if (!thd->current_stmt_binlog_row_based && - mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG)) - { - thd->set_current_stmt_binlog_row_based(); - } - - /* - Open the table if it is not already open and add the table to - table map. Note that for any table that should not be - replicated, a filter is needed. - - The creation of a new TABLE_LIST is used to up-cast the - table_list consisting of RPL_TABLE_LIST items. This will work - since the only case where the argument to open_tables() is - changed, is when thd->lex->query_tables == table_list, i.e., - when the statement requires prelocking. Since this is not - executed when a statement is executed, this case will not occur. - As a precaution, an assertion is added to ensure that the bad - case is not a fact. - - Either way, the memory in the list is *never* released - internally in the open_tables() function, hence we take a copy - of the pointer to make sure that it's not lost. - */ - uint count; DBUG_ASSERT(thd->lex->query_tables != table_list); - TABLE_LIST *tmp_table_list= table_list; - if ((error= open_tables(thd, &tmp_table_list, &count, 0))) - { - if (thd->is_slave_error || thd->is_fatal_error) - { - /* - Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) - */ - uint actual_error= thd->main_da.sql_errno(); - rli->report(ERROR_LEVEL, actual_error, - "Error '%s' on opening table `%s`.`%s`", - (actual_error ? thd->main_da.message() : - "unexpected success or fatal error"), - table_list->db, table_list->table_name); - thd->is_slave_error= 1; - } - goto err; - } - - m_table= table_list->table; - - /* - This will fail later otherwise, the 'in_use' field should be - set to the current thread. - */ - DBUG_ASSERT(m_table->in_use); /* Use placement new to construct the table_def instance in the @@ -7383,10 +7286,6 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) } DBUG_RETURN(error); - -err: - my_free(memory, MYF(MY_WME)); - DBUG_RETURN(error); } Log_event::enum_skip_reason diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 808356a05c7..c6b99b1bd69 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -53,81 +53,46 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info */ if (!thd->lock) { - bool need_reopen= 1; /* To execute the first lap of the loop below */ - /* - lock_tables() reads the contents of thd->lex, so they must be - initialized. Contrary to in - Table_map_log_event::do_apply_event() we don't call - mysql_init_query() as that may reset the binlog format. + Lock_tables() reads the contents of thd->lex, so they must be + initialized. + + We also call the mysql_reset_thd_for_next_command(), since this + is the logical start of the next "statement". Note that this + call might reset the value of current_stmt_binlog_row_based, so + we need to do any changes to that value after this function. */ lex_start(thd); + mysql_reset_thd_for_next_command(thd); - while ((error= lock_tables(thd, rli->tables_to_lock, - rli->tables_to_lock_count, &need_reopen))) + /* + Check if the slave is set to use SBR. If so, it should switch + to using RBR until the end of the "statement", i.e., next + STMT_END_F or next error. + */ + if (!thd->current_stmt_binlog_row_based && + mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG)) { - if (!need_reopen) - { - if (thd->is_slave_error || thd->is_fatal_error) - { - /* - Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) - */ - uint actual_error= thd->main_da.sql_errno(); - rli->report(ERROR_LEVEL, actual_error, - "Error '%s' in %s event: when locking tables", - (actual_error ? thd->main_da.message() : - "unexpected success or fatal error"), - ev->get_type_str()); - thd->is_fatal_error= 1; - } - else - { - rli->report(ERROR_LEVEL, error, - "Error in %s event: when locking tables", - ev->get_type_str()); - } - const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); - DBUG_RETURN(error); - } - - /* - So we need to reopen the tables. - - We need to flush the pending RBR event, since it keeps a - pointer to an open table. - - ALTERNATIVE SOLUTION (not implemented): Extract a pointer to - the pending RBR event and reset the table pointer after the - tables has been reopened. - - NOTE: For this new scheme there should be no pending event: - need to add code to assert that is the case. - */ - thd->binlog_flush_pending_rows_event(false); - TABLE_LIST *tables= rli->tables_to_lock; - close_tables_for_reopen(thd, &tables); + thd->set_current_stmt_binlog_row_based(); + } - uint tables_count= rli->tables_to_lock_count; - if ((error= open_tables(thd, &tables, &tables_count, 0))) + if (simple_open_n_lock_tables(thd, rli->tables_to_lock)) + { + uint actual_error= thd->main_da.sql_errno(); + if (thd->is_slave_error || thd->is_fatal_error) { - if (thd->is_slave_error || thd->is_fatal_error) - { - /* - Error reporting borrowed from Query_log_event with many excessive - simplifications (we don't honour --slave-skip-errors) - */ - uint actual_error= thd->main_da.sql_errno(); - rli->report(ERROR_LEVEL, actual_error, - "Error '%s' on reopening tables", - (actual_error ? thd->main_da.message() : - "unexpected success or fatal error")); - thd->is_slave_error= 1; - } - const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); - DBUG_RETURN(error); + /* + Error reporting borrowed from Query_log_event with many excessive + simplifications (we don't honour --slave-skip-errors) + */ + rli->report(ERROR_LEVEL, actual_error, + "Error '%s' on opening tables", + (actual_error ? thd->main_da.message() : + "unexpected success or fatal error")); + thd->is_slave_error= 1; } + const_cast<Relay_log_info*>(rli)->clear_tables_to_lock(); + DBUG_RETURN(actual_error); } /* diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3f0c1ee8a80..b680bbc1308 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4367,6 +4367,11 @@ bool fix_merge_after_open(TABLE_LIST *old_child_list, TABLE_LIST **old_last, prelocking it won't do such precaching and will simply reuse table list which is already built. + If any table has a trigger and start->trg_event_map is non-zero + the final lock will end up in thd->locked_tables, otherwise, the + lock will be placed in thd->lock. See also comments in + st_lex::set_trg_event_type_for_tables(). + RETURN 0 - OK -1 - error @@ -4579,7 +4584,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) process its triggers since they never will be activated. */ if (!thd->prelocked_mode && !thd->lex->requires_prelocking() && - tables->table->triggers && + tables->trg_event_map && tables->table->triggers && tables->lock_type >= TL_WRITE_ALLOW_WRITE) { if (!query_tables_last_own) |