From: Luis Soares Date: July 26 2009 10:03pm Subject: bzr commit into mysql-pe branch (luis.soares:3486) Bug#43046 List-Archive: http://lists.mysql.com/commits/79299 X-Bug: 43046 Message-Id: <0KNE004JATAAAD00@fe-emea-09.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_7GUm4GtfQEi1B2QznXcGWw)" --Boundary_(ID_7GUm4GtfQEi1B2QznXcGWw) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline #At file:///home/lsoares/Workspace/mysql-server/bugfix/b43046/mysql-pe-to-push/ based on revid:davi.arnaut@stripped 3486 Luis Soares 2009-07-26 [merge] BUG#43046: mixed mode switch to row format with temp table lead to wrong result Automerge: mysql-5.1-bugteam --> mysql-pe modified: mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test sql/sql_table.cc === modified file 'mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result' --- a/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result 2009-02-23 03:26:38 +0000 +++ b/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result 2009-07-26 21:48:24 +0000 @@ -24,3 +24,48 @@ Slave_open_temp_tables 0 [on master] DROP TABLE t1; [on slave] +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); +CREATE TABLE t2 ( i1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (i1) ); +CREATE TABLE t3 ( i1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (i1) ); +CREATE TRIGGER tr1 AFTER DELETE ON t2 FOR EACH ROW INSERT INTO t3 () VALUES (); +CREATE TEMPORARY TABLE t1_tmp (i1 int); +ALTER TABLE t1_tmp ADD COLUMN b INT; +DELETE FROM t2; +CREATE TEMPORARY TABLE t2_tmp (a int); +ALTER TABLE t1_tmp ADD COLUMN c INT; +### assertion: assert that there is one open temp table on slave +SHOW STATUS LIKE 'Slave_open_temp_tables'; +Variable_name Value +Slave_open_temp_tables 1 +DROP TABLE t1_tmp, t2; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE t2_tmp; +INSERT INTO t1 VALUES (2); +### assertion: assert that slave has no temporary tables opened +SHOW STATUS LIKE 'Slave_open_temp_tables'; +Variable_name Value +Slave_open_temp_tables 0 +DROP TABLE t3, t1; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int) +slave-bin.000001 # Query # # use `test`; CREATE TABLE t2 ( i1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (i1) ) +slave-bin.000001 # Query # # use `test`; CREATE TABLE t3 ( i1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (i1) ) +slave-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER DELETE ON t2 FOR EACH ROW INSERT INTO t3 () VALUES () +slave-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE t1_tmp (i1 int) +slave-bin.000001 # Query # # use `test`; ALTER TABLE t1_tmp ADD COLUMN b INT +slave-bin.000001 # Query # # use `test`; DROP TABLE `t2` /* generated by server */ +slave-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t1_tmp` /* generated by server */ +slave-bin.000001 # Query # # BEGIN +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `t2_tmp` /* generated by server */ +slave-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (2) +slave-bin.000001 # Query # # use `test`; DROP TABLE t3, t1 === modified file 'mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test' --- a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test 2009-03-24 08:55:03 +0000 +++ b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test 2009-07-26 21:48:24 +0000 @@ -51,3 +51,98 @@ DROP TABLE t1; --echo [on slave] sync_slave_with_master; + +# +# BUG#43046: mixed mode switch to row format with temp table lead to wrong +# result +# +# NOTES +# ===== +# +# 1. Temporary tables cannot be logged using the row-based +# format. Thus, once row-based logging is used, all subsequent +# statements using that table are unsafe, and we approximate this +# condition by treating all statements made by that client as +# unsafe until the client no longer holds any temporary tables. +# +# 2. Two different connections can use the same temporary table +# name without conflicting with each other or with an +# existing non-TEMPORARY table of the same name. +# +# DESCRIPTION +# =========== +# +# The test is implemented as follows: +# 1. create regular tables +# 2. create a temporary table t1_tmp: should be logged as statement +# 3. issue an alter table: should be logged as statement +# 4. issue statement that forces switch to RBR +# 5. create another temporary table t2_tmp: should not be logged +# 6. issue alter table on t1_tmp: should not be logged +# 7. drop t1_tmp and regular table on same statement: should log both in +# statement format (but different statements) +# 8. issue deterministic insert: logged as row (because t2_tmp still +# exists). +# 9. drop t2_tmp and issue deterministic statement: should log drop and +# query in statement format (show switch back to STATEMENT format) +# 10. in the end the slave should not have open temp tables. +# + +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); +-- source include/master-slave-reset.inc +-- connection master + +# action: setup environment +CREATE TABLE t1 (a int); +CREATE TABLE t2 ( i1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (i1) ); +CREATE TABLE t3 ( i1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (i1) ); +CREATE TRIGGER tr1 AFTER DELETE ON t2 FOR EACH ROW INSERT INTO t3 () VALUES (); + +# assertion: assert that CREATE is logged as STATEMENT +CREATE TEMPORARY TABLE t1_tmp (i1 int); + +# assertion: assert that ALTER TABLE is logged as STATEMENT +ALTER TABLE t1_tmp ADD COLUMN b INT; + +# action: force switch to RBR +DELETE FROM t2; + +# assertion: assert that t2_tmp will not make into the binlog (RBR logging atm) +CREATE TEMPORARY TABLE t2_tmp (a int); + +# assertion: assert that ALTER TABLE on t1_tmp will not make into the binlog +ALTER TABLE t1_tmp ADD COLUMN c INT; + +-- echo ### assertion: assert that there is one open temp table on slave +-- sync_slave_with_master +SHOW STATUS LIKE 'Slave_open_temp_tables'; + +-- connection master + +# assertion: assert that both drops are logged +DROP TABLE t1_tmp, t2; + +# assertion: assert that statement is logged as row (master still has one +# opened temporary table - t2_tmp. +INSERT INTO t1 VALUES (1); + +# assertion: assert that DROP TABLE *is* logged despite CREATE is not. +DROP TEMPORARY TABLE t2_tmp; + +# assertion: assert that statement is now logged as STMT (mixed mode switches +# back to STATEMENT). +INSERT INTO t1 VALUES (2); + +-- sync_slave_with_master + +-- echo ### assertion: assert that slave has no temporary tables opened +SHOW STATUS LIKE 'Slave_open_temp_tables'; + +-- connection master + +# action: drop remaining tables +DROP TABLE t3, t1; + +-- sync_slave_with_master + +-- source include/show_binlog_events.inc === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2009-07-10 12:31:32 +0000 +++ b/sql/sql_table.cc 2009-07-26 22:02:13 +0000 @@ -1797,6 +1797,7 @@ int mysql_rm_table_part2(THD *thd, TABLE int non_temp_tables_count= 0; bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0; String built_query; + String built_tmp_query; DBUG_ENTER("mysql_rm_table_part2"); LINT_INIT(alias); @@ -1900,6 +1901,25 @@ int mysql_rm_table_part2(THD *thd, TABLE case 0: // removed temporary table tmp_table_deleted= 1; + if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED && + thd->current_stmt_binlog_row_based) + { + if (built_tmp_query.is_empty()) + { + built_tmp_query.set_charset(system_charset_info); + built_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS "); + } + + built_tmp_query.append("`"); + if (thd->db == NULL || strcmp(db,thd->db) != 0) + { + built_tmp_query.append(db); + built_tmp_query.append("`.`"); + } + built_tmp_query.append(table->table_name); + built_tmp_query.append("`,"); + } + continue; case -1: DBUG_ASSERT(thd->in_sub_stmt); @@ -2066,29 +2086,52 @@ int mysql_rm_table_part2(THD *thd, TABLE write_bin_log(thd, !error, thd->query, thd->query_length); } else if (thd->current_stmt_binlog_row_based && - non_temp_tables_count > 0 && tmp_table_deleted) { - /* - In this case we have deleted both temporary and - non-temporary tables, so: - - since we have deleted a non-temporary table we have to - binlog the statement, but - - since we have deleted a temporary table we cannot binlog - the statement (since the table has not been created on the - slave, this might cause the slave to stop). + if (non_temp_tables_count > 0) + { + /* + In this case we have deleted both temporary and + non-temporary tables, so: + - since we have deleted a non-temporary table we have to + binlog the statement, but + - since we have deleted a temporary table we cannot binlog + the statement (since the table may have not been created on the + slave - check "if" branch below, this might cause the slave to + stop). - Instead, we write a built statement, only containing the - non-temporary tables, to the binary log + Instead, we write a built statement, only containing the + non-temporary tables, to the binary log + */ + built_query.chop(); // Chop of the last comma + built_query.append(" /* generated by server */"); + write_bin_log(thd, !error, built_query.ptr(), built_query.length()); + } + + /* + One needs to always log any temporary table drop, if: + 1. thread logging format is mixed mode; AND + 2. current statement logging format is set to row. */ - built_query.chop(); // Chop of the last comma - built_query.append(" /* generated by server */"); - write_bin_log(thd, !error, built_query.ptr(), built_query.length()); + if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED) + { + /* + In this case we have deleted some temporary tables but we are using + row based logging for the statement. However, thread uses mixed mode + format, thence we need to log the dropping as we cannot tell for + sure whether the create was logged as statement previously or not, ie, + before switching to row mode. + */ + built_tmp_query.chop(); // Chop of the last comma + built_tmp_query.append(" /* generated by server */"); + write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length()); + } } + /* The remaining cases are: - - no tables where deleted and - - only temporary tables where deleted and row-based + - no tables were deleted and + - only temporary tables were deleted and row-based replication is used. In both these cases, nothing should be written to the binary log. --Boundary_(ID_7GUm4GtfQEi1B2QznXcGWw) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/luis.soares@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/luis.soares@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: luis.soares@stripped # target_branch: file:///home/lsoares/Workspace/mysql-\ # server/bugfix/b43046/mysql-pe-to-push/ # testament_sha1: cea82c0e20baee56f1fcae64ec8d5f1e8738f7f7 # timestamp: 2009-07-26 23:03:45 +0100 # source_branch: file:///home/lsoares/Workspace/mysql-\ # server/bugfix/b43046/mysql-5.1-bugteam-to-push/ # base_revision_id: davi.arnaut@stripped\ # x1znfsehrj4qgcmd # # Begin bundle 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 q96vSqbhPX7vlD/OWID/xdyRThQkFm7CGYA= --Boundary_(ID_7GUm4GtfQEi1B2QznXcGWw)--