Alfranio Correia wrote:
> Hi all,
>
> Daogang Qu wrote:
>
>> Libing Song wrote:
>>
>>> Hi Daogang,
>>>
>>>
>>> Nice Work. Please find my review comments below.
>>>
>>> STATUS
>>> ------
>>> Not approved.
>>>
>>> REQUIRED CHANGES
>>> ----------------
>>>
>>> RC1. I think the following patch is better.
>>>
>>> === modified file 'sql/sql_class.h'
>>> --- sql/sql_class.h 2009-12-02 13:49:21 +0000
>>> +++ sql/sql_class.h 2009-12-29 09:29:10 +0000
>>> @@ -2213,7 +2213,8 @@
>>> ("temporary_tables: %s, in_sub_stmt: %s, system_thread:
>>> %s",
>>> YESNO(temporary_tables), YESNO(in_sub_stmt),
>>> show_system_thread(system_thread)));
>>> - if ((temporary_tables == NULL) && (in_sub_stmt == 0) &&
>>> + if ((temporary_tables == NULL || !current_stmt_binlog_row_based)
>>>
>>>
>> Good. Maybe the following is better:
>>
>> - if ((temporary_tables == NULL) && (in_sub_stmt == 0) &&
>> + if ((temporary_tables == NULL || (!current_stmt_binlog_row_based &&
>> + variables.binlog_format == BINLOG_FORMAT_ROW)) && (in_sub_stmt
>> == 0) &&
>> (system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG))
>>
>
>
> Although I said in the IRC that it was possible to restore the correct value in the
> reset_current_stmt_binlog_row_based, I was wrong. It is not possible.
> Consider for instance the following example:
>
> --source include/master-slave.inc
> --source include/have_binlog_format_mixed.inc
>
> CREATE TABLE t (a int);
>
> INSERT INTO t VALUES(1), (2);
> CREATE TEMPORARY TABLE tt (a int, b int) SELECT *, UUID() from t;
> INSERT INTO t VALUES(3), (4);
>
> DELIMITER |;
> CREATE PROCEDURE p1() BEGIN SELECT 1 ; END |
> DELIMITER ;|
>
> INSERT INTO tt(a) VALUES(1), (2);
> INSERT INTO t VALUES(5), (6);
>
> DROP TABLE t;
>
> SHOW BINLOG EVENTS;
>
> sync_slave_with_master;
>
> exit;
>
>
> WRONG RESULT:
> -------------
>
> Log_name Pos Event_type Server_id End_log_pos Info
> master-bin.000001 4 Format_desc 1 106 Server ver:
> 5.1.42-debug-log, Binlog ver: 4
> master-bin.000001 106 Query 1 191 use `test`; CREATE TABLE t (a
> int)
> master-bin.000001 191 Query 1 282 use `test`; INSERT INTO t
> VALUES(1), (2)
> master-bin.000001 282 Query 1 350 BEGIN
> master-bin.000001 350 Table_map 1 390 table_id: 23
> (test.t)
> master-bin.000001 390 Write_rows 1 429 table_id: 23 flags:
> STMT_END_F
> master-bin.000001 429 Query 1 498 COMMIT
> master-bin.000001 498 Query 1 633 use `test`; CREATE
> DEFINER=`root`@`localhost` PROCEDURE `p1`()
> BEGIN SELECT 1 ; END
> master-bin.000001 633 Query 1 728 use `test`; INSERT INTO tt(a)
> VALUES(1), (2)
> master-bin.000001 728 Query 1 819 use `test`; INSERT INTO t
> VALUES(5), (6)
> master-bin.000001 819 Query 1 894 use `test`; DROP TABLE t
> master-bin.000001 894 Query 1 1004 use `test`; DROP /*!40005
> TEMPORARY */ TABLE IF EXISTS `tt`
>
>
> RIGHT RESULT:
> -------------
>
> master-bin.000001 4 Format_desc 1 106 Server ver:
> 5.1.42-debug-log, Binlog ver: 4
> master-bin.000001 106 Query 1 191 use `test`; CREATE TABLE t (a
> int)
> master-bin.000001 191 Query 1 282 use `test`; INSERT INTO t
> VALUES(1), (2)
> master-bin.000001 282 Query 1 350 BEGIN
> master-bin.000001 350 Table_map 1 390 table_id: 23
> (test.t)
> master-bin.000001 390 Write_rows 1 429 table_id: 23 flags:
> STMT_END_F
> master-bin.000001 429 Query 1 498 COMMIT
> master-bin.000001 498 Query 1 633 use `test`; CREATE
> DEFINER=`root`@`localhost` PROCEDURE `p1`()
> BEGIN SELECT 1 ; END
> master-bin.000001 282 Query 1 350 BEGIN
> master-bin.000001 350 Table_map 1 390 table_id: 23
> (test.t)
> master-bin.000001 390 Write_rows 1 429 table_id: 23 flags:
> STMT_END_F
> master-bin.000001 429 Query 1 498 COMMIT
> master-bin.000001 894 Query 1 1004 use `test`; DROP /*!40005
> TEMPORARY */ TABLE IF EXISTS `tt`
>
>
>
> It is not possible to figure out what is the current value.
> In this case, after creating the procedure current_stmt_binlog_row_based
> should be TRUE.
>
> So, either
>
> 1 - we create a "global" variable to save the current value and restore it
> when necessary.
>
Concurrency will bring some problems if create a "global" variable to
save the current value.
> 2 - we create a "local" variable to save the current value and restore it.
>
It's better.
> 3 - we force the current_stmt_binlog_row_based to be TRUE if there is
> a temporary table and the format is MIXED.
>
The problem can be resolved by updating
reset_current_stmt_binlog_row_based().
But it will have a logic confusion, we have to write code as following:
if (temporary_tables != NULL)
{
if (variables.binlog_format == BINLOG_FORMAT_STMT)
current_stmt_binlog_row_based= false;
else
current_stmt_binlog_row_based= true;
}
else ((temporary_tables == NULL) && (in_sub_stmt == 0) &&
(system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG))
{
current_stmt_binlog_row_based=
test(variables.binlog_format == BINLOG_FORMAT_ROW);
}
So I more like the second solution. Thanks!
Cheers,
Daogang
>
> Note that the current patch and several other places in the code are wrong
> as the value should be saved and restored.
>
>
> Cheers.
>
>
>
>
>> What's your opinion?
>>
>>
>> Best Regards,
>>
>> Daogang
>>
>>> + && (in_sub_stmt == 0) &&
>>> (system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG))
>>> {
>>> current_stmt_binlog_row_based=
>>>
>>> REQUESTS
>>> --------
>>> n/a
>>>
>>> SUGGESTIONS
>>> -----------
>>> n/a
>>>
>>> DETAILS -------
>>> On Tue, 2009-12-29 at 08:55 +0000, Dao-Gang.Qu@stripped wrote:
>>>
>>>
>>>> #At file:///home/daogangqu/mysql/bzrwork/bug49132/mysql-5.1-bugteam/
>>>> based on revid:alexey.kopytov@stripped
>>>>
>>>> 3271 Dao-Gang.Qu@stripped 2009-12-29
>>>> Bug #49132 Replication failure on temporary table + DDL
>>>> In RBR, DDL statement will change binlog format to non
>>>> row-based format, and then manipulating a temporary table can
>>>> not reset binlog format to row-based format rightly. So that
>>>> the manipulated statement is binlogged with statement-based
>>>> format.
>>>> To fix the problem, restore the state of binlog format
>>>> after the DDL statement is binlogged.
>>>> @ mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
>>>> Correct the test result, all the above binlog event
>>>> should be row-based after the bug49132 is fixed IN RBR.
>>>> @ mysql-test/suite/rpl/r/rpl_failure_on_tmp_table_and_DDL.result
>>>> Test result of the bug#49132.
>>>> @ mysql-test/suite/rpl/t/rpl_failure_on_tmp_table_and_DDL.test
>>>> Added the test file to verify if executing DDL statement
>>>> before trying to manipulate a temporary table causes
>>>> row-based replication to break with error 'table does not
>>>> exist'.
>>>>
>>>> added:
>>>> mysql-test/suite/rpl/r/rpl_failure_on_tmp_table_and_DDL.result
>>>> mysql-test/suite/rpl/t/rpl_failure_on_tmp_table_and_DDL.test
>>>> modified:
>>>> mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
>>>> sql/events.cc
>>>> sql/sp.cc
>>>> sql/sql_acl.cc
>>>> === modified file
>>>> 'mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result'
>>>> ---
>>>> a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
>>>> 2009-10-06 10:25:36 +0000
>>>> +++
>>>> b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
>>>> 2009-12-29 08:54:57 +0000
>>>> @@ -772,8 +772,11 @@ insert into t2 values (bug27417(2));
>>>> 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=3
>>>> -master-bin.000001 # Query # # use `test`; insert into
>>>> t2 values (bug27417(2))
>>>> +master-bin.000001 # Query # # BEGIN
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t2)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Write_rows # # table_id: # flags:
>>>> STMT_END_F
>>>> +master-bin.000001 # Query # # ROLLBACK
>>>> select count(*) from t1 /* must be 3 */;
>>>> count(*)
>>>> 3
>>>> @@ -787,8 +790,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=4
>>>> -master-bin.000001 # Query # # use `test`; delete from
>>>> t2 where a=bug27417(3)
>>>> +master-bin.000001 # Query # # BEGIN
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t2)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Write_rows # # table_id: # flags:
>>>> STMT_END_F
>>>> +master-bin.000001 # Query # # COMMIT
>>>> select count(*) from t1 /* must be 5 */;
>>>> count(*)
>>>> 5
>>>> @@ -810,8 +816,9 @@ ERROR 23000: Duplicate entry '1' for key
>>>> show binlog events from <binlog_start>;
>>>> Log_name Pos Event_type Server_id End_log_pos Info
>>>> master-bin.000001 # Query # # BEGIN
>>>> -master-bin.000001 # Intvar # # INSERT_ID=1
>>>> -master-bin.000001 # Query # # use `test`; insert into
>>>> t2 values (bug27417(1))
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t2)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Write_rows # # table_id: # flags:
>>>> STMT_END_F
>>>> master-bin.000001 # Query # # ROLLBACK
>>>> select count(*) from t1 /* must be 1 */;
>>>> count(*)
>>>> @@ -825,8 +832,10 @@ ERROR 23000: Duplicate entry '2' for key
>>>> show binlog events from <binlog_start>;
>>>> Log_name Pos Event_type Server_id End_log_pos Info
>>>> master-bin.000001 # Query # # BEGIN
>>>> -master-bin.000001 # Intvar # # INSERT_ID=2
>>>> -master-bin.000001 # Query # # use `test`; insert into
>>>> t2 select bug27417(1) union select bug27417(2)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t2)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Write_rows # # table_id: #
>>>> +master-bin.000001 # Write_rows # # table_id: # flags:
>>>> STMT_END_F
>>>> master-bin.000001 # Query # # ROLLBACK
>>>> select count(*) from t1 /* must be 2 */;
>>>> count(*)
>>>> @@ -838,8 +847,13 @@ update t3 set b=b+bug27417(1);
>>>> ERROR 23000: Duplicate entry '4' for key 'b'
>>>> show binlog events from <binlog_start>;
>>>> Log_name Pos Event_type Server_id End_log_pos Info
>>>> -master-bin.000001 # Intvar # # INSERT_ID=4
>>>> -master-bin.000001 # Query # # use `test`; update t3
>>>> set b=b+bug27417(1)
>>>> +master-bin.000001 # Query # # BEGIN
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t3)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Write_rows # # table_id: #
>>>> +master-bin.000001 # Update_rows # # table_id: #
>>>> +master-bin.000001 # Write_rows # # table_id: # flags:
>>>> STMT_END_F
>>>> +master-bin.000001 # Query # # ROLLBACK
>>>> select count(*) from t1 /* must be 2 */;
>>>> count(*)
>>>> 2
>>>> @@ -853,8 +867,9 @@ ERROR 23000: Duplicate entry '2' for key
>>>> show binlog events from <binlog_start>;
>>>> Log_name Pos Event_type Server_id End_log_pos Info
>>>> master-bin.000001 # Query # # BEGIN
>>>> -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 # Table_map # # table_id: # (test.t4)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Write_rows # # table_id: # flags:
>>>> STMT_END_F
>>>> master-bin.000001 # Query # # ROLLBACK
>>>> select count(*) from t1 /* must be 4 */;
>>>> count(*)
>>>> @@ -869,7 +884,7 @@ 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
>>>> +2
>>>> drop table t4;
>>>> delete from t1;
>>>> delete from t2;
>>>> @@ -884,8 +899,10 @@ ERROR 23000: Duplicate entry '1' for key
>>>> show binlog events from <binlog_start>;
>>>> Log_name Pos Event_type Server_id End_log_pos Info
>>>> master-bin.000001 # Query # # BEGIN
>>>> -master-bin.000001 # Intvar # # INSERT_ID=9
>>>> -master-bin.000001 # Query # # use `test`; delete from t2
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t2)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t3)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Write_rows # # table_id: # flags:
>>>> STMT_END_F
>>>> master-bin.000001 # Query # # ROLLBACK
>>>> select count(*) from t1 /* must be 1 */;
>>>> count(*)
>>>> @@ -904,7 +921,11 @@ ERROR 23000: Duplicate entry '1' for key
>>>> show binlog events from <binlog_start>;
>>>> Log_name Pos Event_type Server_id End_log_pos Info
>>>> master-bin.000001 # Query # # BEGIN
>>>> -master-bin.000001 # Query # # use `test`; delete t2.*
>>>> from t2,t5 where t2.a=t5.a + 1
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t2)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Delete_rows # # table_id: #
>>>> +master-bin.000001 # Write_rows # # table_id: #
>>>> +master-bin.000001 # Delete_rows # # table_id: #
>>>> flags: STMT_END_F
>>>> master-bin.000001 # Query # # ROLLBACK
>>>> select count(*) from t1 /* must be 1 */;
>>>> count(*)
>>>> @@ -924,12 +945,11 @@ count(*)
>>>> show binlog events from <binlog_start>;
>>>> Log_name Pos Event_type Server_id End_log_pos Info
>>>> master-bin.000001 # Query # # BEGIN
>>>> -master-bin.000001 # Intvar # # INSERT_ID=10
>>>> -master-bin.000001 # User var # # @`b`=_latin1 0x3135
>>>> COLLATE latin1_swedish_ci
>>>> -master-bin.000001 # Begin_load_query # #
>>>> ;file_id=#;block_len=#
>>>> -master-bin.000001 # Intvar # # INSERT_ID=10
>>>> -master-bin.000001 # User var # # @`b`=_latin1 0x3135
>>>> COLLATE latin1_swedish_ci
>>>> -master-bin.000001 # Execute_load_query # # use
>>>> `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE
>>>> `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES
>>>> TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=#
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t4)
>>>> +master-bin.000001 # Table_map # # table_id: # (test.t1)
>>>> +master-bin.000001 # Write_rows # # table_id: #
>>>> +master-bin.000001 # Write_rows # # table_id: #
>>>> +master-bin.000001 # Write_rows # # table_id: # flags:
>>>> STMT_END_F
>>>> master-bin.000001 # Query # # ROLLBACK
>>>> drop trigger trg_del_t2;
>>>> drop table t1,t2,t3,t4,t5;
>>>>
>>>> === added file
>>>> 'mysql-test/suite/rpl/r/rpl_failure_on_tmp_table_and_DDL.result'
>>>> ---
>>>> a/mysql-test/suite/rpl/r/rpl_failure_on_tmp_table_and_DDL.result
>>>> 1970-01-01 00:00:00 +0000
>>>> +++
>>>> b/mysql-test/suite/rpl/r/rpl_failure_on_tmp_table_and_DDL.result
>>>> 2009-12-29 08:54:57 +0000
>>>> @@ -0,0 +1,109 @@
>>>> +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 TEMPORARY TABLE t1 (a int);
>>>> +CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT "nothing";
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP EVENT IF EXISTS e1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE PROCEDURE p1() BEGIN SELECT 1 ; END |
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +ALTER PROCEDURE p1 SQL SECURITY INVOKER;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP PROCEDURE p1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE FUNCTION f1() RETURNS INT RETURN 123;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +ALTER FUNCTION f1 SQL SECURITY INVOKER;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP FUNCTION f1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE TABLE t2 (b int);
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP TABLE t2;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE DATABASE mysqltest1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP DATABASE mysqltest1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE TABLE t2 (a int);
>>>> +CREATE TABLE t3 (a int);
>>>> +CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2
>>>> VALUES(22);
>>>> +insert into t3 values (1);
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +drop table t2, t3;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE TABLE t2 (a int);
>>>> +CREATE VIEW v2 AS SELECT * FROM t2;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP VIEW v2;
>>>> +drop table t2;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE USER test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +create table t2 (a int, b int);
>>>> +grant select on t2 to test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +create procedure stamp() insert into t2 values (1,2);
>>>> +grant execute on procedure stamp to test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +DROP PROCEDURE stamp;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +grant usage on *.* to test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +revoke all privileges on t2 from test_1@localhost;
>>>> +revoke usage on *.* from test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +RENAME USER test_1@localhost TO test_2@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +drop user test_2@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +drop table t2;
>>>>
>>>> === added file
>>>> 'mysql-test/suite/rpl/t/rpl_failure_on_tmp_table_and_DDL.test'
>>>> --- a/mysql-test/suite/rpl/t/rpl_failure_on_tmp_table_and_DDL.test
>>>> 1970-01-01 00:00:00 +0000
>>>> +++ b/mysql-test/suite/rpl/t/rpl_failure_on_tmp_table_and_DDL.test
>>>> 2009-12-29 08:54:57 +0000
>>>> @@ -0,0 +1,164 @@
>>>> +#
>>>> +# Bug#49132
>>>> +# This test verify if executing DDL statement before trying to +#
>>>> manipulate a temporary table causes row-based replication to +# break
>>>> with error 'table does not exist'.
>>>> +#
>>>> +--source include/master-slave.inc
>>>> +--source include/have_binlog_format_row.inc
>>>> +
>>>> +# CREATE EVENT when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# ALTER EVENT when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT "nothing";
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# DROP EVENT when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP EVENT IF EXISTS e1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# CREATE PROCEDURE when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DELIMITER |;
>>>> +CREATE PROCEDURE p1() BEGIN SELECT 1 ; END |
>>>> +DELIMITER ;|
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# Alter PROCEDURE when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +ALTER PROCEDURE p1 SQL SECURITY INVOKER;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +
>>>> +# DROP PROCEDURE when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP PROCEDURE p1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# CREATE FUNCTION when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE FUNCTION f1() RETURNS INT RETURN 123;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# ALTER FUNCTION when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +ALTER FUNCTION f1 SQL SECURITY INVOKER;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# DROP FUNCTION when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP FUNCTION f1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# CREATE TABLE when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE TABLE t2 (b int);
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# DROP TABLE when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP TABLE t2;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# CREATE DATABASE when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE DATABASE mysqltest1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# DROP DATABASE when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP DATABASE mysqltest1;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# CREATE TRIGGER when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE TABLE t2 (a int);
>>>> +CREATE TABLE t3 (a int);
>>>> +CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW INSERT INTO t2
>>>> VALUES(22);
>>>> +insert into t3 values (1);
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +drop table t2, t3;
>>>> +
>>>> +# CREATE VIEW when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE TABLE t2 (a int);
>>>> +CREATE VIEW v2 AS SELECT * FROM t2;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# DROP VIEW when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +DROP VIEW v2;
>>>> +drop table t2;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# CREATE USER when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +CREATE USER test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# TABLE GRANT when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +create table t2 (a int, b int);
>>>> +grant select on t2 to test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# ROUTINE GRANT when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +create procedure stamp() insert into t2 values (1,2);
>>>> +grant execute on procedure stamp to test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +DROP PROCEDURE stamp;
>>>> +
>>>> +# MYSQL GRANT when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +grant usage on *.* to test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# REVOKE PRIVILEGES when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +revoke all privileges on t2 from test_1@localhost;
>>>> +revoke usage on *.* from test_1@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# RENAME USER when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +RENAME USER test_1@localhost TO test_2@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +# DROP USER when a temporary table is open.
>>>> +CREATE TEMPORARY TABLE t1 (a int);
>>>> +drop user test_2@localhost;
>>>> +insert into t1 values (1);
>>>> +DROP TEMPORARY TABLE t1;
>>>> +
>>>> +drop table t2;
>>>> +
>>>> +--sync_slave_with_master
>>>> +
>>>>
>>>> === modified file 'sql/events.cc'
>>>> --- a/sql/events.cc 2009-10-16 10:29:42 +0000
>>>> +++ b/sql/events.cc 2009-12-29 08:54:57 +0000
>>>> @@ -479,6 +479,9 @@ Events::create_event(THD *thd, Event_par
>>>> }
>>>> }
>>>> pthread_mutex_unlock(&LOCK_event_metadata);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>>
>>>> DBUG_RETURN(ret);
>>>> }
>>>> @@ -600,6 +603,9 @@ Events::update_event(THD *thd, Event_par
>>>> }
>>>> }
>>>> pthread_mutex_unlock(&LOCK_event_metadata);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>>
>>>> DBUG_RETURN(ret);
>>>> }
>>>> @@ -674,6 +680,9 @@ Events::drop_event(THD *thd, LEX_STRING
>>>> write_bin_log(thd, TRUE, thd->query(), thd->query_length());
>>>> }
>>>> pthread_mutex_unlock(&LOCK_event_metadata);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE; DBUG_RETURN(ret);
>>>> }
>>>>
>>>>
>>>> === modified file 'sql/sp.cc'
>>>> --- a/sql/sp.cc 2009-12-02 11:17:08 +0000
>>>> +++ b/sql/sp.cc 2009-12-29 08:54:57 +0000
>>>> @@ -1118,6 +1118,9 @@ done:
>>>> thd->variables.sql_mode= saved_mode;
>>>>
>>>> close_thread_tables(thd);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(ret);
>>>> }
>>>>
>>>> @@ -1171,6 +1174,9 @@ sp_drop_routine(THD *thd, int type, sp_n
>>>> }
>>>>
>>>> close_thread_tables(thd);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(ret);
>>>> }
>>>>
>>>> @@ -1241,6 +1247,9 @@ sp_update_routine(THD *thd, int type, sp
>>>> }
>>>>
>>>> close_thread_tables(thd);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(ret);
>>>> }
>>>>
>>>>
>>>> === modified file 'sql/sql_acl.cc'
>>>> --- a/sql/sql_acl.cc 2009-12-06 23:12:11 +0000
>>>> +++ b/sql/sql_acl.cc 2009-12-29 08:54:57 +0000
>>>> @@ -3083,7 +3083,12 @@ int mysql_table_grant(THD *thd, TABLE_LI
>>>> */
>>>> tables[0].updating= tables[1].updating= tables[2].updating= 1;
>>>> if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
>>>> + {
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(FALSE);
>>>> + }
>>>> }
>>>> #endif
>>>>
>>>> @@ -3096,6 +3101,9 @@ int mysql_table_grant(THD *thd, TABLE_LI
>>>> if (simple_open_n_lock_tables(thd,tables))
>>>> { // Should never happen
>>>> close_thread_tables(thd); /* purecov: deadcode */
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(TRUE); /* purecov: deadcode */
>>>> }
>>>>
>>>> @@ -3222,6 +3230,9 @@ int mysql_table_grant(THD *thd, TABLE_LI
>>>>
>>>> /* Tables are automatically closed */
>>>> thd->lex->restore_backup_query_tables_list(&backup);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(result);
>>>> }
>>>>
>>>> @@ -3300,13 +3311,21 @@ bool mysql_routine_grant(THD *thd, TABLE
>>>> */
>>>> tables[0].updating= tables[1].updating= 1;
>>>> if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
>>>> + {
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(FALSE);
>>>> + }
>>>> }
>>>> #endif
>>>>
>>>> if (simple_open_n_lock_tables(thd,tables))
>>>> { // Should never happen
>>>> close_thread_tables(thd);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(TRUE);
>>>> }
>>>>
>>>> @@ -3382,6 +3401,9 @@ bool mysql_routine_grant(THD *thd, TABLE
>>>> }
>>>>
>>>> rw_unlock(&LOCK_grant);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>>
>>>> /* Tables are automatically closed */
>>>> DBUG_RETURN(result);
>>>> @@ -3439,13 +3461,21 @@ bool mysql_grant(THD *thd, const char *d
>>>> */
>>>> tables[0].updating= tables[1].updating= 1;
>>>> if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
>>>> + {
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(FALSE);
>>>> + }
>>>> }
>>>> #endif
>>>>
>>>> if (simple_open_n_lock_tables(thd,tables))
>>>> { // This should never happen
>>>> close_thread_tables(thd); /* purecov: deadcode */
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(TRUE); /* purecov: deadcode */
>>>> }
>>>>
>>>> @@ -3505,6 +3535,9 @@ bool mysql_grant(THD *thd, const char *d
>>>>
>>>> if (!result)
>>>> my_ok(thd);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>>
>>>> DBUG_RETURN(result);
>>>> }
>>>> @@ -5672,7 +5705,12 @@ bool mysql_create_user(THD *thd, List <L
>>>>
>>>> /* CREATE USER may be skipped on replication client. */
>>>> if ((result= open_grant_tables(thd, tables)))
>>>> + {
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(result != 1);
>>>> + }
>>>>
>>>> rw_wrlock(&LOCK_grant);
>>>> VOID(pthread_mutex_lock(&acl_cache->lock));
>>>> @@ -5715,6 +5753,9 @@ bool mysql_create_user(THD *thd, List <L
>>>>
>>>> rw_unlock(&LOCK_grant);
>>>> close_thread_tables(thd);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(result);
>>>> }
>>>>
>>>> @@ -5752,7 +5793,12 @@ bool mysql_drop_user(THD *thd, List <LEX
>>>>
>>>> /* DROP USER may be skipped on replication client. */
>>>> if ((result= open_grant_tables(thd, tables)))
>>>> + {
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(result != 1);
>>>> + }
>>>>
>>>> thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
>>>>
>>>> @@ -5789,6 +5835,9 @@ bool mysql_drop_user(THD *thd, List <LEX
>>>> rw_unlock(&LOCK_grant);
>>>> close_thread_tables(thd);
>>>> thd->variables.sql_mode= old_sql_mode;
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(result);
>>>> }
>>>>
>>>> @@ -5826,7 +5875,12 @@ bool mysql_rename_user(THD *thd, List <L
>>>>
>>>> /* RENAME USER may be skipped on replication client. */
>>>> if ((result= open_grant_tables(thd, tables)))
>>>> + {
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(result != 1);
>>>> + }
>>>>
>>>> rw_wrlock(&LOCK_grant);
>>>> VOID(pthread_mutex_lock(&acl_cache->lock));
>>>> @@ -5873,6 +5927,9 @@ bool mysql_rename_user(THD *thd, List <L
>>>>
>>>> rw_unlock(&LOCK_grant);
>>>> close_thread_tables(thd);
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(result);
>>>> }
>>>>
>>>> @@ -5907,7 +5964,12 @@ bool mysql_revoke_all(THD *thd, List <L
>>>> thd->clear_current_stmt_binlog_row_based();
>>>>
>>>> if ((result= open_grant_tables(thd, tables)))
>>>> + {
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>> DBUG_RETURN(result != 1);
>>>> + }
>>>>
>>>> rw_wrlock(&LOCK_grant);
>>>> VOID(pthread_mutex_lock(&acl_cache->lock));
>>>> @@ -6058,6 +6120,9 @@ bool mysql_revoke_all(THD *thd, List <L
>>>>
>>>> if (result)
>>>> my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>>
>>>> DBUG_RETURN(result);
>>>> }
>>>> @@ -6193,6 +6258,9 @@ bool sp_revoke_privileges(THD *thd, cons
>>>> close_thread_tables(thd);
>>>>
>>>> thd->pop_internal_handler();
>>>> + /* Restore the state of binlog format */
>>>> + if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
>>>> + thd->current_stmt_binlog_row_based= TRUE;
>>>>
>>>> DBUG_RETURN(error_handler.has_errors());
>>>> }
>>>>
>>>>
>>>>
>>>
>>>
>>
>
>