Commit f4b6aeaf authored by 's avatar

Bug #46998 mysqlbinlog can't output BEGIN even if the database is included in a transaction

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' 
in regardless of the database filtering rules.
parents 00e5cea8 869c0112
...@@ -726,7 +726,10 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, ...@@ -726,7 +726,10 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
switch (ev_type) { switch (ev_type) {
case QUERY_EVENT: case QUERY_EVENT:
if (shall_skip_database(((Query_log_event*)ev)->db)) if (strncmp(((Query_log_event*)ev)->query, "BEGIN", 5) &&
strncmp(((Query_log_event*)ev)->query, "COMMIT", 6) &&
strncmp(((Query_log_event*)ev)->query, "ROLLBACK", 8) &&
shall_skip_database(((Query_log_event*)ev)->db))
goto end; goto end;
if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS)
{ {
......
...@@ -473,5 +473,94 @@ IS NOT NULL ...@@ -473,5 +473,94 @@ IS NOT NULL
SET @@global.server_id= 1; SET @@global.server_id= 1;
RESET MASTER; RESET MASTER;
FLUSH LOGS; FLUSH LOGS;
RESET MASTER;
FLUSH LOGS;
#
# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is exist
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
ROLLBACK/*!*/;
use test/*!*/;
SET TIMESTAMP=1253783037/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table t1(a int) engine= innodb
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
insert into t1 (a) values (1)
/*!*/;
COMMIT/*!*/;
SET TIMESTAMP=1253783037/*!*/;
create table t3(a int) engine= innodb
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
insert into t3 (a) values (2)
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
ROLLBACK
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
create table t5(a int) engine= NDB
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
insert into t5 (a) values (3)
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
COMMIT
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
#
# Test if the 'BEGIN', 'ROLLBACK' 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 /*!*/;
ROLLBACK/*!*/;
SET TIMESTAMP=1253783037/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
COMMIT/*!*/;
SET TIMESTAMP=1253783037/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
ROLLBACK
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
BEGIN
/*!*/;
SET TIMESTAMP=1253783037/*!*/;
COMMIT
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
End of 5.0 tests End of 5.0 tests
End of 5.1 tests End of 5.1 tests
...@@ -112,17 +112,22 @@ while($i) ...@@ -112,17 +112,22 @@ while($i)
# remove unecessary files # remove unecessary files
-- remove_file $outfile.1 -- remove_file $outfile.1
-- remove_file $outfile.2 -- remove_file $outfile.2
#
# The two tests are canceled since we introduced the patch of bug#46998,
# which will make mydsqlbinlog output the 'BEGIN', 'COMMIT' and 'ROLLBACK'
# in regardless of database filtering
#
# assertion: events for database test are filtered # assertion: events for database test are filtered
if (`SELECT INSTR(@b42941_output.1, 'test')`) #if (`SELECT INSTR(@b42941_output.1, 'test')`)
{ #{
-- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.1). #-- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.1).
} #}
if (`SELECT INSTR(@b42941_output.2, 'test')`) #if (`SELECT INSTR(@b42941_output.2, 'test')`)
{ #{
-- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.2). #-- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.2).
} #}
# assertion: events for database b42941 are not filtered # assertion: events for database b42941 are not filtered
if (!`SELECT INSTR(@b42941_output.1, 'b42941')`) if (!`SELECT INSTR(@b42941_output.1, 'b42941')`)
......
...@@ -378,6 +378,68 @@ FLUSH LOGS; ...@@ -378,6 +378,68 @@ FLUSH LOGS;
# We do not need the results, just make sure that mysqlbinlog does not crash # We do not need the results, just make sure that mysqlbinlog does not crash
--exec $MYSQL_BINLOG --hexdump --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 >/dev/null --exec $MYSQL_BINLOG --hexdump --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 >/dev/null
#
# #46998
# This test verifies if the 'BEGIN', 'COMMIT' and 'ROLLBACK' are output
# in regardless of database filtering
#
RESET MASTER;
FLUSH LOGS;
# The following three test cases were wrtten into binlog_transaction.000001
# Test case1: Test if the 'BEGIN' and 'COMMIT' are output for the 'test' database
# in transaction1 base on innodb engine tables
# use test;
# create table t1(a int) engine= innodb;
# use mysql;
# create table t2(a int) engine= innodb;
# Transaction1 begin
# begin;
# use test;
# insert into t1 (a) values (1);
# use mysql;
# insert into t2 (a) values (1);
# commit;
# Transaction1 end
# Test case2: Test if the 'BEGIN' and 'ROLLBACK' are output for the 'test' database
# in transaction2 base on innodb and myisam engine tables
# use test;
# create table t3(a int) engine= innodb;
# use mysql;
# create table t4(a int) engine= myisam;
# Transaction2 begin
# begin;
# use test;
# insert into t3 (a) values (2);
# use mysql;
# insert into t4 (a) values (2);
# rollback;
# Transaction2 end
# Test case3: Test if the 'BEGIN' and 'COMMIT' are output for the 'test' database
# in transaction3 base on NDB engine tables
# use test;
# create table t5(a int) engine= NDB;
# use mysql;
# create table t6(a int) engine= NDB;
# Transaction3 begin
# begin;
# use test;
# insert into t5 (a) values (3);
# use mysql;
# insert into t6 (a) values (3);
# commit;
# Transaction3 end
--echo #
--echo # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is exist
--exec $MYSQL_BINLOG --database=test --short-form $MYSQLTEST_VARDIR/std_data/binlog_transaction.000001
--echo #
--echo # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is not exist
--exec $MYSQL_BINLOG --database=not_exist --short-form $MYSQLTEST_VARDIR/std_data/binlog_transaction.000001
--echo End of 5.0 tests --echo End of 5.0 tests
--echo End of 5.1 tests --echo End of 5.1 tests
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment