diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 77f74e0d42cae..f677586e43695 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -884,7 +884,7 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, char ll_buff[21]; bool result= 0; - if (opt_flashback) + if (opt_flashback && !skip_event) { Rows_log_event *e= (Rows_log_event*) ev; // The last Row_log_event will be the first event in Flashback @@ -936,7 +936,7 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, result_file (as it would happen in ev->print(...) if event was not skipped). */ - if (skip_event) + if (skip_event && !opt_flashback) { // append END-MARKER(') with delimiter IO_CACHE *const body_cache= &print_event_info->body_cache; @@ -955,14 +955,14 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, } /* skip the event check */ - if (skip_event) + if (skip_event && !(opt_flashback && is_stmt_end)) return 0; if (!opt_flashback) result= print_base64(print_event_info, ev); else { - if (is_stmt_end) + if (is_stmt_end && events_in_stmt.elements) { Log_event *e= NULL; @@ -1576,7 +1576,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end)); if (is_stmt_end) print_event_info->found_row_event= 0; - else if (opt_flashback) + else if (opt_flashback && + !print_event_info->m_table_map_ignored.get_table(e->get_table_id())) destroy_evt= FALSE; break; } @@ -1590,7 +1591,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, e->get_flags(Old_rows_log_event::STMT_END_F))) goto err; DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end)); - if (!is_stmt_end && opt_flashback) + if (!is_stmt_end && opt_flashback && + !print_event_info->m_table_map_ignored.get_table(e->get_table_id())) destroy_evt= FALSE; break; } diff --git a/mysql-test/suite/binlog/r/flashback.result b/mysql-test/suite/binlog/r/flashback.result index da6dc7e07ff2a..6f9140684c516 100644 --- a/mysql-test/suite/binlog/r/flashback.result +++ b/mysql-test/suite/binlog/r/flashback.result @@ -702,6 +702,89 @@ include/assert.inc [Table t1 should have 0 rows.] # 6- Rows must be present upon restoring from flashback include/assert.inc [Table t1 should have six rows.] DROP TABLE t1; +# < CASE 8 > +# MDEV-23077: --flashback + --table produces buggy results +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1), (-1); +CREATE TABLE t2 (i INT); +INSERT INTO t2 VALUES (1), (-2); +RESET MASTER; +BEGIN; +UPDATE t1, t2 SET t1.i=2, t2.i=2 WHERE t1.i=t2.i AND t1.i=1; +DELETE t1, t2 FROM t1 INNER JOIN t2 WHERE t1.i=2; +COMMIT; +FLUSH BINARY LOGS; +SELECT * FROM t1; +i +-1 +SELECT * FROM t2; +i +# < CASE 8.1 > +# Only the table used in WHERE +# MDEV-23077 bug03: Only the first Base64 was in a BINLOG statement. +# +SELECT * FROM t1; +i +1 +-1 +SELECT * FROM t2; +i +# < CASE 8.2 > +# Ignore the table used in WHERE +# MDEV-23077 bug02: Output includes extraneous "unknown table". +# +SELECT * FROM t1; +i +1 +-1 +SELECT * FROM t2; +i +1 +-2 +NOT FOUND /### Row event for unknown table/ in mysqlbinlog_row_flashback_8_2.sql +DROP TABLE t1; +DROP TABLE t2; +# < CASE 9 > +# --flashback + --database +# +CREATE DATABASE d1; +CREATE DATABASE d2; +CREATE TABLE d1.t (i INT); +INSERT INTO d1.t VALUES (1), (-1); +CREATE TABLE d2.t (i INT); +INSERT INTO d2.t VALUES (1), (-2); +RESET MASTER; +BEGIN; +UPDATE d1.t, d2.t SET d1.t.i=2, d2.t.i=2 WHERE d1.t.i=d2.t.i AND d1.t.i=1; +DELETE d1.t, d2.t FROM d1.t INNER JOIN d2.t WHERE d1.t.i=2; +COMMIT; +FLUSH BINARY LOGS; +# < CASE 9.1 > +# Only the database used in WHERE +# MDEV-23077 bug03: Only the first Base64 was in a BINLOG statement. +# +SELECT * FROM d1.t; +i +1 +-1 +SELECT * FROM d2.t; +i +# < CASE 9.2 > +# Ignore the database used in WHERE +# MDEV-23077 bug02: Output includes extraneous "unknown table". +# +SELECT * FROM d1.t; +i +1 +-1 +SELECT * FROM d2.t; +i +1 +-2 +NOT FOUND /### Row event for unknown table/ in mysqlbinlog_row_flashback_9_2.sql +DROP DATABASE d1; +DROP DATABASE d2; # # MDEV-30698 Cover missing test cases for mariadb-binlog options # --raw [and] --flashback diff --git a/mysql-test/suite/binlog/t/flashback.test b/mysql-test/suite/binlog/t/flashback.test index 8daf3f43a2399..f93c175b46255 100644 --- a/mysql-test/suite/binlog/t/flashback.test +++ b/mysql-test/suite/binlog/t/flashback.test @@ -364,13 +364,118 @@ FLUSH LOGS; DROP TABLE t1; +--echo # < CASE 8 > +--echo # MDEV-23077: --flashback + --table produces buggy results +--echo # + +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1), (-1); +CREATE TABLE t2 (i INT); +INSERT INTO t2 VALUES (1), (-2); + +RESET MASTER; +BEGIN; + UPDATE t1, t2 SET t1.i=2, t2.i=2 WHERE t1.i=t2.i AND t1.i=1; + DELETE t1, t2 FROM t1 INNER JOIN t2 WHERE t1.i=2; +COMMIT; +FLUSH BINARY LOGS; + +# only (-1) +SELECT * FROM t1; +# empty +SELECT * FROM t2; + +--echo # < CASE 8.1 > +--echo # Only the table used in WHERE +--echo # MDEV-23077 bug03: Only the first Base64 was in a BINLOG statement. +--echo # + +--exec $MYSQL_BINLOG -Bvv --table=t1 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_8_1.sql +--exec $MYSQL -e "SOURCE $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_8_1.sql;" + +# (1), (-1) +SELECT * FROM t1; +# still empty +SELECT * FROM t2; + +--echo # < CASE 8.2 > +--echo # Ignore the table used in WHERE +--echo # MDEV-23077 bug02: Output includes extraneous "unknown table". +--echo # + +--exec $MYSQL_BINLOG -Bvv --table=t2 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_8_2.sql +--exec $MYSQL -e "SOURCE $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_8_2.sql;" + +# (1), (-1) +SELECT * FROM t1; +# (1), (-2) +SELECT * FROM t2; + +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_8_2.sql +--let SEARCH_PATTERN= ### Row event for unknown table +--source include/search_pattern_in_file.inc + +DROP TABLE t1; +DROP TABLE t2; + +--echo # < CASE 9 > +--echo # --flashback + --database +--echo # + +CREATE DATABASE d1; +CREATE DATABASE d2; +CREATE TABLE d1.t (i INT); +INSERT INTO d1.t VALUES (1), (-1); +CREATE TABLE d2.t (i INT); +INSERT INTO d2.t VALUES (1), (-2); + +RESET MASTER; +BEGIN; + UPDATE d1.t, d2.t SET d1.t.i=2, d2.t.i=2 WHERE d1.t.i=d2.t.i AND d1.t.i=1; + DELETE d1.t, d2.t FROM d1.t INNER JOIN d2.t WHERE d1.t.i=2; +COMMIT; +FLUSH BINARY LOGS; + +--echo # < CASE 9.1 > +--echo # Only the database used in WHERE +--echo # MDEV-23077 bug03: Only the first Base64 was in a BINLOG statement. +--echo # + +--exec $MYSQL_BINLOG -Bvv --database=d1 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_9_1.sql +--exec $MYSQL -e "SOURCE $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_9_1.sql;" + +# (1), (-1) +SELECT * FROM d1.t; +# still empty +SELECT * FROM d2.t; + +--echo # < CASE 9.2 > +--echo # Ignore the database used in WHERE +--echo # MDEV-23077 bug02: Output includes extraneous "unknown table". +--echo # + +--exec $MYSQL_BINLOG -Bvv --database=d2 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_9_2.sql +--exec $MYSQL -e "SOURCE $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_9_2.sql;" + +# (1), (-1) +SELECT * FROM d1.t; +# (1), (-2) +SELECT * FROM d2.t; + +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_9_2.sql +--let SEARCH_PATTERN= ### Row event for unknown table +--source include/search_pattern_in_file.inc + +DROP DATABASE d1; +DROP DATABASE d2; + --echo # --echo # MDEV-30698 Cover missing test cases for mariadb-binlog options --echo # --raw [and] --flashback --echo # --error 1 # --raw mode and --flashback mode are not allowed ---exec $MYSQL_BINLOG -vv -B --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000003> $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_8.sql +--exec $MYSQL_BINLOG -vv -B --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000003> $MYSQLTEST_VARDIR/tmp/mysqlbinlog_row_flashback_0.sql ## Clear SET binlog_format=statement;