List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:September 22 2009 9:28am
Subject:Re: bzr commit into mysql-5.0-bugteam branch (Dao-Gang.Qu:2812)
Bug#46998
View as plain text  
Dao-Gang.Qu@stripped wrote:
> #At file:///home/daogangqu/mysql/bzrwork/bug46998/mysql-5.0-bugteam/ based on
> revid:sergey.glukhov@stripped
> 
>  2812 Dao-Gang.Qu@stripped	2009-09-21
>       Bug #46998  mysqlbinlog can't output BEGIN even if the database is included in
> a transaction
>       
>       The 'BEGIN' just is output with associated database, so mysqlbinlog can't
> output 'BEGIN' 
>       with unassociated database even if the database is included in transaction.
>       Actually mysqlbinlog can't output 'COMMIT' and 'ROLLBACK' with unassociated
> database 
>       included in transaction for non-transactional tables, although it can output
> them for 
>       transactional tables.
>       

suggest something like:

The 'BEGIN/COMMIT/ROLLBACK' log event could be filtered out if the
database is not selected by --database option of mysqlbinlog command.
This can result in problem if there are some statements in the
transaction are not filtered out.

>       To fix the problem, mysqlbinlog will output 'BEGIN/ROLLBACK/COMMIT' for the
> database 
>       included in transaction in regardless of the database filtering rules.

suggest to remove 'for the database included in transaction' part.

>      @ client/mysqlbinlog.cc
>         Added a judgement condition, so that mysqlbinlog will output 'BEGIN' 
>         for the database included in transaction.

Suggest: Skip the database check for BEGIN/COMMIT/ROLLBACK log events.

>      @ mysql-test/r/binlog_transaction_complete.result
>         Test result for bug#46998
>      @ mysql-test/t/binlog_transaction_complete.test
>         Added test to verify if the 'BEGIN', 'COMMIT' and 'ROLLBACK' are output 
>         for the database included in transaction.
> 

suggest: for the database included in transaction => in regardless of
database filtering

>     added:
>       mysql-test/include/binlog_transaction_complete.inc
>       mysql-test/r/binlog_transaction_complete.result
>       mysql-test/t/binlog_transaction_complete.test
>     modified:
>       client/mysqlbinlog.cc
> === modified file 'client/mysqlbinlog.cc'
> --- a/client/mysqlbinlog.cc	2009-06-29 13:17:01 +0000
> +++ b/client/mysqlbinlog.cc	2009-09-21 10:15:50 +0000
> @@ -557,7 +557,10 @@ int process_event(PRINT_EVENT_INFO *prin
>  
>      switch (ev_type) {
>      case QUERY_EVENT:
> -      if (check_database(((Query_log_event*)ev)->db))
> +      if (check_database(((Query_log_event*)ev)->db) &&
> +          strncmp(((Query_log_event*)ev)->query, "BEGIN", 5) &&
> +          strncmp(((Query_log_event*)ev)->query, "COMMIT", 6) &&
> +          strncmp(((Query_log_event*)ev)->query, "ROLLBACK", 8)) 

Should first check for 'BEGIN/COMMIT/ROLLBACK', and skip
check_database() if it is one of 'BEGIN/COMMIT/ROLLBACK'.

>          goto end;
>        ev->print(result_file, print_event_info);
>        break;
> 
> === added file 'mysql-test/include/binlog_transaction_complete.inc'
> --- a/mysql-test/include/binlog_transaction_complete.inc	1970-01-01 00:00:00 +0000
> +++ b/mysql-test/include/binlog_transaction_complete.inc	2009-09-21 10:15:50 +0000
> @@ -0,0 +1,31 @@
> +#
> +# This test verifies if the 'BEGIN', 'COMMIT' and 'ROLLBACK' are output 
> +# for the database included in transaction.
> +#

suggest: for the database included in transaction => in regardless of
database filtering

> +
> +use test;
> +eval create table t1(a int) engine=$engine1_type;
> +use mysql;
> +eval create table t2(a int) engine=$engine2_type;
> +let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1);
> +SET TIMESTAMP=100000;
> +--echo # Transaction begin
> +begin;
> +use test;
> +insert into t1 (a) values (1);
> +use mysql;
> +insert into t2 (a) values (1);
> +eval $transaction_end_type;
> +--echo # Transaction end
> +FLUSH LOGS;
> +--echo # Test if the 'BEGIN' and '$transaction_end_type' are output for the 'test'
> database in above transaction
> +--exec $MYSQL_BINLOG --database=test --start-position=$pos0_master --short-form
> $MYSQLTEST_VARDIR/log/master-bin.000001
> +--echo # 
> +--echo # Test if the 'BEGIN' and '$transaction_end_type' are output if the database
> specified is not exist
> +--exec $MYSQL_BINLOG --database=not_exist --start-position=$pos0_master --short-form
> $MYSQLTEST_VARDIR/log/master-bin.000001
> +
> +use test;
> +drop table t1;
> +use mysql;
> +drop table t2;
> +
> 
> === added file 'mysql-test/r/binlog_transaction_complete.result'
> --- a/mysql-test/r/binlog_transaction_complete.result	1970-01-01 00:00:00 +0000
> +++ b/mysql-test/r/binlog_transaction_complete.result	2009-09-21 10:15:50 +0000
> @@ -0,0 +1,183 @@
> +# Test case1: Test if 'BEGIN' and 'COMMIT' are output for the 
> +# database included in transaction base on innodb engine tables.
> +use test;
> +create table t1(a int) engine=innodb;
> +use mysql;
> +create table t2(a int) engine=innodb;
> +SET TIMESTAMP=100000;
> +# Transaction begin
> +begin;
> +use test;
> +insert into t1 (a) values (1);
> +use mysql;
> +insert into t2 (a) values (1);
> +commit;
> +# Transaction end
> +FLUSH LOGS;
> +# Test if the 'BEGIN' and 'commit' are output for the 'test' database in above
> transaction
> +/*!40019 SET @@session.max_insert_delayed_threads=0*/;
> +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
> +DELIMITER /*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1,
> @@session.unique_checks=1/*!*/;
> +SET @@session.sql_mode=0/*!*/;
> +/*!\C latin1 *//*!*/;
> +SET
> @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
> +BEGIN
> +/*!*/;
> +use test/*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +insert into t1 (a) values (1)
> +/*!*/;
> +COMMIT/*!*/;
> +DELIMITER ;
> +# End of log file
> +ROLLBACK /* added by mysqlbinlog */;
> +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
> +# 
> +# Test if the 'BEGIN' and 'commit' are output if the database specified is not
> exist
> +/*!40019 SET @@session.max_insert_delayed_threads=0*/;
> +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
> +DELIMITER /*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1,
> @@session.unique_checks=1/*!*/;
> +SET @@session.sql_mode=0/*!*/;
> +/*!\C latin1 *//*!*/;
> +SET
> @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
> +BEGIN
> +/*!*/;
> +COMMIT/*!*/;
> +DELIMITER ;
> +# End of log file
> +ROLLBACK /* added by mysqlbinlog */;
> +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
> +use test;
> +drop table t1;
> +use mysql;
> +drop table t2;
> +reset master;
> +# Test case2: Test if 'BEGIN' and 'ROLLBACK' are output for the database
> +# included in transaction base on innodb and myisam engine tables.
> +use test;
> +create table t1(a int) engine=innodb;
> +use mysql;
> +create table t2(a int) engine=myisam;
> +SET TIMESTAMP=100000;
> +# Transaction begin
> +begin;
> +use test;
> +insert into t1 (a) values (1);
> +use mysql;
> +insert into t2 (a) values (1);
> +rollback;
> +Warnings:
> +Warning	1196	Some non-transactional changed tables couldn't be rolled back
> +# Transaction end
> +FLUSH LOGS;
> +# Test if the 'BEGIN' and 'rollback' are output for the 'test' database in above
> transaction
> +/*!40019 SET @@session.max_insert_delayed_threads=0*/;
> +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
> +DELIMITER /*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1,
> @@session.unique_checks=1/*!*/;
> +SET @@session.sql_mode=0/*!*/;
> +/*!\C latin1 *//*!*/;
> +SET
> @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
> +BEGIN
> +/*!*/;
> +use test/*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +insert into t1 (a) values (1)
> +/*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +ROLLBACK
> +/*!*/;
> +DELIMITER ;
> +# End of log file
> +ROLLBACK /* added by mysqlbinlog */;
> +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
> +# 
> +# Test if the 'BEGIN' and 'rollback' are output if the database specified is not
> exist
> +/*!40019 SET @@session.max_insert_delayed_threads=0*/;
> +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
> +DELIMITER /*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1,
> @@session.unique_checks=1/*!*/;
> +SET @@session.sql_mode=0/*!*/;
> +/*!\C latin1 *//*!*/;
> +SET
> @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
> +BEGIN
> +/*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +ROLLBACK
> +/*!*/;
> +DELIMITER ;
> +# End of log file
> +ROLLBACK /* added by mysqlbinlog */;
> +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
> +use test;
> +drop table t1;
> +use mysql;
> +drop table t2;
> +reset master;
> +# Test case3: Test if 'BEGIN' and 'COMMIT' are output for the 
> +# database included in transaction base on NDB engine tables.
> +use test;
> +create table t1(a int) engine=NDB;
> +use mysql;
> +create table t2(a int) engine=NDB;
> +SET TIMESTAMP=100000;
> +# Transaction begin
> +begin;
> +use test;
> +insert into t1 (a) values (1);
> +use mysql;
> +insert into t2 (a) values (1);
> +commit;
> +# Transaction end
> +FLUSH LOGS;
> +# Test if the 'BEGIN' and 'commit' are output for the 'test' database in above
> transaction
> +/*!40019 SET @@session.max_insert_delayed_threads=0*/;
> +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
> +DELIMITER /*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1,
> @@session.unique_checks=1/*!*/;
> +SET @@session.sql_mode=0/*!*/;
> +/*!\C latin1 *//*!*/;
> +SET
> @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
> +BEGIN
> +/*!*/;
> +use test/*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +insert into t1 (a) values (1)
> +/*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +COMMIT
> +/*!*/;
> +DELIMITER ;
> +# End of log file
> +ROLLBACK /* added by mysqlbinlog */;
> +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
> +# 
> +# Test if the 'BEGIN' and 'commit' are output if the database specified is not
> exist
> +/*!40019 SET @@session.max_insert_delayed_threads=0*/;
> +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
> +DELIMITER /*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1,
> @@session.unique_checks=1/*!*/;
> +SET @@session.sql_mode=0/*!*/;
> +/*!\C latin1 *//*!*/;
> +SET
> @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
> +BEGIN
> +/*!*/;
> +SET TIMESTAMP=100000/*!*/;
> +COMMIT
> +/*!*/;
> +DELIMITER ;
> +# End of log file
> +ROLLBACK /* added by mysqlbinlog */;
> +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
> +use test;
> +drop table t1;
> +use mysql;
> +drop table t2;
> 
> === added file 'mysql-test/t/binlog_transaction_complete.test'
> --- a/mysql-test/t/binlog_transaction_complete.test	1970-01-01 00:00:00 +0000
> +++ b/mysql-test/t/binlog_transaction_complete.test	2009-09-21 10:15:50 +0000
> @@ -0,0 +1,31 @@
> +#
> +# #46998
> +# This test verifies if the 'BEGIN', 'COMMIT' and 'ROLLBACK' are output 
> +# for the database included in transaction.
> +#

I'd suggest to pre-generate the binlog file that includes all kinds of
transaction statements required by the test and save it in std_data
instead of generating the binlog files every time.

> +--source include/have_log_bin.inc
> +--source include/have_innodb.inc
> +--source include/have_ndb.inc
> +--echo # Test case1: Test if 'BEGIN' and 'COMMIT' are output for the 
> +--echo # database included in transaction base on innodb engine tables.
> +let $engine1_type= innodb;
> +let $engine2_type= innodb;
> +let $transaction_end_type=commit;
> +source include/binlog_transaction_complete.inc;
> +reset master;
> +
> +--echo # Test case2: Test if 'BEGIN' and 'ROLLBACK' are output for the database
> +--echo # included in transaction base on innodb and myisam engine tables.
> +let $engine1_type= innodb;
> +let $engine2_type= myisam;
> +let $transaction_end_type=rollback;
> +source include/binlog_transaction_complete.inc;
> +reset master;
> +
> +--echo # Test case3: Test if 'BEGIN' and 'COMMIT' are output for the 
> +--echo # database included in transaction base on NDB engine tables.
> +let $engine1_type= NDB;
> +let $engine2_type= NDB;
> +let $transaction_end_type=commit;
> +source include/binlog_transaction_complete.inc;
> +
> 

Thread
bzr commit into mysql-5.0-bugteam branch (Dao-Gang.Qu:2812) Bug#46998Dao-Gang.Qu21 Sep
  • Re: bzr commit into mysql-5.0-bugteam branch (Dao-Gang.Qu:2812)Bug#46998He Zhenxing22 Sep