From: Andrei Elkin Date: September 30 2010 6:11pm Subject: Re: bzr commit into mysql-next-mr-bugfixing branch (Dao-Gang.Qu:3299) Bug#55869 List-Archive: http://lists.mysql.com/commits/119600 Message-Id: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hello, Dao-Gang. Alfranio and I just have talked to identify the problem. Taking your patch's regression test (t2 is of T type, t1 of func() is of N) insert into t2 values (func(),1); you can see that two Table-map events that are written straight to the stmt= and=20 the trans caches by write_locked_table_maps() when the N-rows event of func= () was being logged through=20 binlog_log_row() <- handler::ha_write_row() As the following insert into t2 dup-key errored out in the following, show binlog events displays the first table map accompanied by the N-rows event and the 2nd table map as "orphane= d". Evidently Table-map flushing logics needs refinement such that Table-map(s) is(are) stored to the cache always with at least one Rows-even= t. There are few approaches how that can be implemented but anyone will require a mandatory change in THD::binlog_write_table_map() to hold on with writing Table-maps into the caches. I can't come up with a very detailed method by now, still it views to me that both caches have to keep the created at write_locked_table_maps() Table-maps marked by some pending state. The pending state is ceased and th= e maps=20 are flushed when a first Rows-event is being written to that cache. The pending state for Table-maps should be cleared in case of an error as w= ell. You welcome to talk on #rep tomorrow on this matter. cheers, Andrei =20 ----- Original Message ----- From: Dao-Gang.Qu@stripped To: alfranio.correia@stripped Cc: commits@stripped, Andrei.Elkin@stripped Sent: Thursday, September 30, 2010 4:08:04 AM GMT +02:00 Athens, Beirut, Bu= charest, Istanbul Subject: Re: bzr commit into mysql-next-mr-bugfixing branch (Dao-Gang.Qu:32= 99) Bug#55869 2010-09-30 07:49, Alfranio Correia wrote: > Hi Daogang, > > Apparently there is no problem with your patch. > However, I prefer a different approach that will help us in the future=20 > to simply the "if" > in binlog_rollback. Besides the approach is less risky. > > Add a flag to trx_cache in order to track if a non-transactional=20 > change was written > to it. Something like set_changes_to_non_trans_temp_table(); > > If you want we can discuss this tomorrow. Sure. Thanks! Best Regards, Daogang > > Cheers. > > > On 09/27/2010 05:04 AM, Dao-Gang.Qu@stripped wrote: >> #At=20 >> file:///home/daogangqu/mysql/bzrwork1/bug55869/mysql-next-mr-bugfixing/= =20 >> based on revid:mats.kindahl@stripped >> >> 3299 Dao-Gang.Qu@stripped 2010-09-27 >> Bug #55869 In mixed mode, the Table_map_event is binloged=20 >> without any rows_log_event. >> >> In mixed mode, the Table_map_event is binlogged without any=20 >> rows_log_event >> when a unsafe single statement transaction corrupted. It's a=20 >> wrong behavior. >> The reason is that the Table_map_event will be binlogged with=20 >> the "ROLLBACK" >> Query_log_event together for a unsafe single stmt transaction,=20 >> which has >> updated non-transactional table regardless of corruption. >> >> To fix the problem to not binlog the Table_map_event and=20 >> "ROLLBACK" >> Query_log_event for a unsafe corrupted single stmt transaction, >> although it has updated non-transactional table. >> @ mysql-test/suite/binlog/r/binlog_trans_log.result >> Test result for Bug #55869. >> @ mysql-test/suite/binlog/t/binlog_trans_log.test >> Added the test to verify if Table_map_event is binlogged=20 >> without >> any rows_log_event for a unsafe corrupted single stmt=20 >> transaction, >> although it has updated non-transactional table. >> >> added: >> mysql-test/suite/binlog/r/binlog_trans_log.result >> mysql-test/suite/binlog/t/binlog_trans_log.test >> modified: >> sql/binlog.cc >> =3D=3D=3D added file 'mysql-test/suite/binlog/r/binlog_trans_log.result' >> --- a/mysql-test/suite/binlog/r/binlog_trans_log.result 1970-01-01=20 >> 00:00:00 +0000 >> +++ b/mysql-test/suite/binlog/r/binlog_trans_log.result 2010-09-27=20 >> 04:04:43 +0000 >> @@ -0,0 +1,26 @@ >> +CREATE TABLE t1 (a int NOT NULL auto_increment primary key)=20 >> ENGINE=3DMyISAM| >> +CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY=20 >> (a)) ENGINE=3DInnoDB| >> +insert into t2 values (1,3)| >> +create function func() >> +RETURNS int(11) >> +DETERMINISTIC >> +begin >> +insert into t1 values (null); >> +select count(*) from t1 into @a; >> +return @a; >> +end| >> +reset master| >> +insert into t2 values (func(),1)| >> +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' >> +# The following must show there are events after the query >> +show binlog events from| >> +Log_name Pos Event_type Server_id End_log_pos Info >> +master-bin.000001 # Query # # BEGIN >> +master-bin.000001 # Table_map # # table_id: # (test.t1) >> +master-bin.000001 # Write_rows # # table_id: # flags:=20 >> STMT_END_F >> +master-bin.000001 # Query # # COMMIT >> +select count(*),@a from t1 /* must be 1,1 */| >> +count(*) @a >> +1 1 >> +drop table t1,t2; >> +drop function func; >> >> =3D=3D=3D added file 'mysql-test/suite/binlog/t/binlog_trans_log.test' >> --- a/mysql-test/suite/binlog/t/binlog_trans_log.test 1970-01-01=20 >> 00:00:00 +0000 >> +++ b/mysql-test/suite/binlog/t/binlog_trans_log.test 2010-09-27=20 >> 04:04:43 +0000 >> @@ -0,0 +1,41 @@ >> +# >> +# Bug #55869 >> +# This test verifies if Table_map_event is binlogged without any >> +# rows_log_event for a unsafe corrupted single stmt transaction, >> +# although it has updated non-transactional table. >> +# >> + >> +--source include/have_innodb.inc >> +--source include/have_binlog_format_mixed.inc >> + >> +delimiter |; >> + >> +CREATE TABLE t1 (a int NOT NULL auto_increment primary key)=20 >> ENGINE=3DMyISAM| >> +CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY=20 >> (a)) ENGINE=3DInnoDB| >> + >> +insert into t2 values (1,3)| >> + >> +create function func() >> +RETURNS int(11) >> +DETERMINISTIC >> +begin >> + insert into t1 values (null); >> + select count(*) from t1 into @a; >> + return @a; >> +end| >> + >> +reset master| >> + >> +--error ER_DUP_ENTRY >> +insert into t2 values (func(),1)| >> + >> +--echo # The following must show there are events after the query >> +--source include/show_binlog_events.inc >> + >> +select count(*),@a from t1 /* must be 1,1 */| >> +delimiter ;| >> + >> +# clean-up >> +drop table t1,t2; >> +drop function func; >> + >> >> =3D=3D=3D modified file 'sql/binlog.cc' >> --- a/sql/binlog.cc 2010-09-17 13:22:22 +0000 >> +++ b/sql/binlog.cc 2010-09-27 04:04:43 +0000 >> @@ -665,7 +665,8 @@ static int binlog_rollback(handlerton *h >> thd->variables.binlog_format =3D=3D BINLOG_FORMAT_MIXED) || >> (trans_has_updated_non_trans_table(thd)&& >> ending_single_stmt_trans(thd,all)&& >> - thd->variables.binlog_format =3D=3D BINLOG_FORMAT_MIXED))) >> + thd->variables.binlog_format =3D=3D BINLOG_FORMAT_MIXED >> +&& !(thd->is_error()&& thd->lex->is_stmt_unsafe())))) >> { >> Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE,=20 >> FALSE, TRUE, 0); >> error=3D binlog_flush_trx_cache(thd, cache_mngr,&qev); >> >> >> >> >>