diff options
author | Brandon Nesterenko <brandon.nesterenko@mariadb.com> | 2021-09-14 09:48:53 -0600 |
---|---|---|
committer | Brandon Nesterenko <brandon.nesterenko@mariadb.com> | 2021-11-01 11:01:34 -0600 |
commit | 76a583a411f7b5f278d4b3c9c0248d78aaef7fb0 (patch) | |
tree | d5365e13a7890cc49126b959c074eed234ef9cd1 | |
parent | 007336d3ec9cf486b53d2d9cb209f5f50c9df76c (diff) | |
download | mariadb-git-76a583a411f7b5f278d4b3c9c0248d78aaef7fb0.tar.gz |
MDEV-4989: Support for GTID in mysqlbinlog
Intermediary commit addressing the following:
1. Refined error messages
2. Changed gtid seq no out of order to warn instead
of error. Warning is issued at the end.
-rw-r--r-- | client/mysqlbinlog.cc | 15 | ||||
-rw-r--r-- | mysql-test/suite/binlog/include/mysqlbinlog_gtid_window_test_cases.inc | 19 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_mysqlbinlog_gtid_window.result | 58 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_window.test | 99 | ||||
-rw-r--r-- | sql/rpl_gtid.cc | 91 | ||||
-rw-r--r-- | sql/rpl_gtid.h | 35 |
6 files changed, 210 insertions, 107 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index edfd2455f42..b31439c2d66 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -2153,13 +2153,7 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi { rpl_gtid *stop_gtid= &stop_gtids[gtid_idx]; if (domain_gtid_filter->add_stop_gtid(stop_gtid)) - { - sql_print_error( - "Domain id is invalid for GTID stop position %u-%u-%llu", - stop_gtid->domain_id, stop_gtid->server_id, - stop_gtid->seq_no); return 1; - } } } else @@ -2202,13 +2196,7 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi { rpl_gtid *start_gtid= &start_gtids[gtid_idx]; if (domain_gtid_filter->add_start_gtid(start_gtid)) - { - sql_print_error( - "Domain id is invalid for GTID start position %u-%u-%llu", - start_gtid->domain_id, start_gtid->server_id, - start_gtid->seq_no); return 1; - } } } else @@ -3397,6 +3385,9 @@ int main(int argc, char** argv) } } + if (domain_gtid_filter) + domain_gtid_filter->write_warnings(stderr); + if (tmpdir.list) free_tmpdir(&tmpdir); if (result_file && result_file != stdout) diff --git a/mysql-test/suite/binlog/include/mysqlbinlog_gtid_window_test_cases.inc b/mysql-test/suite/binlog/include/mysqlbinlog_gtid_window_test_cases.inc index c1a833581ca..0b2e3180a62 100644 --- a/mysql-test/suite/binlog/include/mysqlbinlog_gtid_window_test_cases.inc +++ b/mysql-test/suite/binlog/include/mysqlbinlog_gtid_window_test_cases.inc @@ -265,4 +265,23 @@ DROP TABLE t2; DROP TABLE t1; --echo # MYSQL_BINLOG BINLOG_FILE_PARAM --start-position=0-1-0 --stop-position=512 | MYSQL --exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --start-position=0-1-0 --stop-position=512 | $MYSQL +DROP TABLE t1; + +--echo # Test Case 13: +--echo # Start position is delayed within the binlog +CREATE TABLE t1 (a int); +--echo # MYSQL_BINLOG BINLOG_FILE_PARAM --start-position=0-1-1 --stop-position=0-1-2 | MYSQL +--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM --start-position=0-1-1 --stop-position=0-1-2 | $MYSQL +if ($test2_t1_good_checksum != `CHECKSUM TABLE t1`) +{ + die $data_inconsistent_err; +} +if (0 < `SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'test' AND table_name = 't2'`) +{ + die "t2 should not exist as binlog replay should exclude domain 1 from results"; +} +--let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=WARNING +--source include/search_pattern_in_file.inc DROP TABLE t1;
\ No newline at end of file diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_gtid_window.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_gtid_window.result index cb0c41437ed..b1bf1e2a8b1 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_gtid_window.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_gtid_window.result @@ -114,6 +114,12 @@ DROP TABLE t2; DROP TABLE t1; # MYSQL_BINLOG BINLOG_FILE_PARAM --start-position=0-1-0 --stop-position=512 | MYSQL DROP TABLE t1; +# Test Case 13: +# Start position is delayed within the binlog +CREATE TABLE t1 (a int); +# MYSQL_BINLOG BINLOG_FILE_PARAM --start-position=0-1-1 --stop-position=0-1-2 | MYSQL +NOT FOUND /WARNING/ in mysqld.1.err +DROP TABLE t1; ###################################### # Test Group 2 # Run test cases on remote host @@ -220,6 +226,12 @@ DROP TABLE t2; DROP TABLE t1; # MYSQL_BINLOG BINLOG_FILE_PARAM --start-position=0-1-0 --stop-position=512 | MYSQL DROP TABLE t1; +# Test Case 13: +# Start position is delayed within the binlog +CREATE TABLE t1 (a int); +# MYSQL_BINLOG BINLOG_FILE_PARAM --start-position=0-1-1 --stop-position=0-1-2 | MYSQL +NOT FOUND /WARNING/ in mysqld.1.err +DROP TABLE t1; ############################## # Error Cases ############################## @@ -241,9 +253,12 @@ DROP TABLE t1; # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-2 --stop-position=0-1-1 # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 --stop-position=0-1-1 # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-2,1-2-1 --stop-position=0-1-1,1-2-2 +############################## +# Warning Cases +############################## # -# Error Case 4: -# A gap in sequence number at end of window results in error +# Warning Case 1: +# A gap in sequence number at end of window results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -253,11 +268,12 @@ INSERT INTO t1 values (2); SET @@session.gtid_seq_no= 5; INSERT INTO t1 values (3); FLUSH LOGS; -# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 > MYSQLTEST_VARDIR/tmp/out.binlog +# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +FOUND 1 /WARNING/ in out.err DROP TABLE t1; # -# Error Case 5: -# A gap in sequence number at beginning of window results in error +# Warning Case 2: +# A gap in sequence number at beginning of window results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -265,11 +281,12 @@ CREATE TABLE t1 (a int); SET @@session.gtid_seq_no= 3; INSERT INTO t1 values (1); FLUSH LOGS; -# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 > MYSQLTEST_VARDIR/tmp/out.binlog +# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 > /home/brandon/workspace/server/build/mysql-test/var/tmp/out.err > MYSQLTEST_VARDIR/tmp/out.binlog +FOUND 1 /WARNING/ in out.err DROP TABLE t1; # -# Error Case 6: -# A gap in sequence number within a window results in error +# Warning Case 3: +# A gap in sequence number within a window results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -278,12 +295,13 @@ INSERT INTO t1 values (1); SET @@session.gtid_seq_no= 4; INSERT INTO t1 values (2); FLUSH LOGS; -# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 > MYSQLTEST_VARDIR/tmp/out.binlog +# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +FOUND 1 /WARNING/ in out.err DROP TABLE t1; # -# Error Case 7: +# Warning Case 4: # When invoked with just --start-position, a gap in sequence number -# after the provided GTID results in error +# after the provided GTID results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -292,12 +310,13 @@ INSERT INTO t1 values (1); SET @@session.gtid_seq_no= 4; INSERT INTO t1 values (2); FLUSH LOGS; -# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 > MYSQLTEST_VARDIR/tmp/out.binlog +# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +FOUND 1 /WARNING/ in out.err DROP TABLE t1; # -# Error Case 8: +# Warning Case 5: # When invoked with just --stop-position, a gap in sequence number -# before the provided GTID results in error +# before the provided GTID results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -306,12 +325,13 @@ INSERT INTO t1 values (1); SET @@session.gtid_seq_no= 4; INSERT INTO t1 values (2); FLUSH LOGS; -# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --stop-position=0-1-4 > MYSQLTEST_VARDIR/tmp/out.binlog +# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --stop-position=0-1-4 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +FOUND 1 /WARNING/ in out.err DROP TABLE t1; # -# Error Case 9: +# Warning Case 6: # One domain has a sequence number gap but another does not results in -# error +# a warning RESET MASTER; SET @@session.gtid_domain_id= 1; SET @@session.server_id= 2; @@ -324,7 +344,9 @@ CREATE TABLE t1 (a int); INSERT INTO t1 values (1); SET @@session.gtid_seq_no= 4; INSERT INTO t1 values (2); -# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0,1-2-0 --stop-position=0-1-4,1-2-3 > MYSQLTEST_VARDIR/tmp/out.binlog +FLUSH LOGS; +# MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0,1-2-0 --stop-position=0-1-4,1-2-3 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +FOUND 1 /WARNING/ in out.err DROP TABLE t1; DROP TABLE t2; ############################## diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_window.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_window.test index a9014cead1e..dedcfbf14aa 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_window.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_gtid_window.test @@ -40,21 +40,22 @@ # --(start|stop)-position. If the checksums are identical, the test passes. # If the checksums differ, data has been changed and the test fails. # -# Additionally, this test validates the following error scenarios: +# Additionally, this test validates the following error and warning scenarios: # Error Case 1) User provides invalid positions # Error Case 2) User provides GTID ranges with repeated domain ids # Error Case 3) --stop-position is not strictly greater than --start-position -# Error Case 4) A gap in sequence number at the beginning of a window results -# in error -# Error Case 5) A gap in sequence number at the end of a window results in -# error -# Error Case 6) A gap in sequence number within a window results in error -# Error Case 7) When invoked with just --start-position, a gap in sequence -# number after the provided GTID results in error -# Error Case 8) When invoked with just --stop-position, a gap in sequence -# number before the provided GTID results in error -# Error Case 9) One domain has a sequence number gap but another does not -# results in error +# +# Warning Case 1) A gap in sequence number at the beginning of a window results +# in a warning +# Warning Case 2) A gap in sequence number at the end of a window results in +# a warning +# Warning Case 3) A gap in sequence number within a window results in a warning +# Warning Case 4) When invoked with just --start-position, a gap in sequence +# number after the provided GTID results in a warning +# Warning Case 5) When invoked with just --stop-position, a gap in sequence +# number before the provided GTID results in a warning +# Warning Case 6) One domain has a sequence number gap but another does not +# results in a warning # # # References: @@ -141,9 +142,16 @@ RESET MASTER; --error 1 --exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-2,1-2-1 --stop-position=0-1-1,1-2-2 + +--echo ############################## +--echo # Warning Cases +--echo ############################## +--let $log_error_ = $MYSQLTEST_VARDIR/tmp/out.err +--let SEARCH_FILE=$log_error_ + --echo # ---echo # Error Case 4: ---echo # A gap in sequence number at end of window results in error +--echo # Warning Case 1: +--echo # A gap in sequence number at end of window results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -153,14 +161,15 @@ INSERT INTO t1 values (2); SET @@session.gtid_seq_no= 5; INSERT INTO t1 values (3); FLUSH LOGS; ---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 > MYSQLTEST_VARDIR/tmp/out.binlog ---error 1 ---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 > $MYSQLTEST_VARDIR/tmp/out.binlog +--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 2> $log_error_ > $MYSQLTEST_VARDIR/tmp/out.binlog +--let SEARCH_PATTERN=WARNING +--source include/search_pattern_in_file.inc DROP TABLE t1; --echo # ---echo # Error Case 5: ---echo # A gap in sequence number at beginning of window results in error +--echo # Warning Case 2: +--echo # A gap in sequence number at beginning of window results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -168,14 +177,15 @@ CREATE TABLE t1 (a int); SET @@session.gtid_seq_no= 3; INSERT INTO t1 values (1); FLUSH LOGS; ---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 > MYSQLTEST_VARDIR/tmp/out.binlog ---error 1 ---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 > $MYSQLTEST_VARDIR/tmp/out.binlog +--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 > $log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-1 2> $log_error_ > $MYSQLTEST_VARDIR/tmp/out.binlog +--let SEARCH_PATTERN=WARNING +--source include/search_pattern_in_file.inc DROP TABLE t1; --echo # ---echo # Error Case 6: ---echo # A gap in sequence number within a window results in error +--echo # Warning Case 3: +--echo # A gap in sequence number within a window results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -184,15 +194,16 @@ INSERT INTO t1 values (1); SET @@session.gtid_seq_no= 4; INSERT INTO t1 values (2); FLUSH LOGS; ---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 > MYSQLTEST_VARDIR/tmp/out.binlog ---error 1 ---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 > $MYSQLTEST_VARDIR/tmp/out.binlog +--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 --stop-position=0-1-4 2> $log_error_ > $MYSQLTEST_VARDIR/tmp/out.binlog +--let SEARCH_PATTERN=WARNING +--source include/search_pattern_in_file.inc DROP TABLE t1; --echo # ---echo # Error Case 7: +--echo # Warning Case 4: --echo # When invoked with just --start-position, a gap in sequence number ---echo # after the provided GTID results in error +--echo # after the provided GTID results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -201,15 +212,16 @@ INSERT INTO t1 values (1); SET @@session.gtid_seq_no= 4; INSERT INTO t1 values (2); FLUSH LOGS; ---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 > MYSQLTEST_VARDIR/tmp/out.binlog ---error 1 ---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 > $MYSQLTEST_VARDIR/tmp/out.binlog +--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0 2> $log_error_ > $MYSQLTEST_VARDIR/tmp/out.binlog +--let SEARCH_PATTERN=WARNING +--source include/search_pattern_in_file.inc DROP TABLE t1; --echo # ---echo # Error Case 8: +--echo # Warning Case 5: --echo # When invoked with just --stop-position, a gap in sequence number ---echo # before the provided GTID results in error +--echo # before the provided GTID results in a warning RESET MASTER; SET @@session.gtid_domain_id= 0; SET @@session.server_id= 1; @@ -218,15 +230,16 @@ INSERT INTO t1 values (1); SET @@session.gtid_seq_no= 4; INSERT INTO t1 values (2); FLUSH LOGS; ---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --stop-position=0-1-4 > MYSQLTEST_VARDIR/tmp/out.binlog ---error 1 ---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --stop-position=0-1-4 > $MYSQLTEST_VARDIR/tmp/out.binlog +--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --stop-position=0-1-4 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --stop-position=0-1-4 2> $log_error_ > $MYSQLTEST_VARDIR/tmp/out.binlog +--let SEARCH_PATTERN=WARNING +--source include/search_pattern_in_file.inc DROP TABLE t1; --echo # ---echo # Error Case 9: +--echo # Warning Case 6: --echo # One domain has a sequence number gap but another does not results in ---echo # error +--echo # a warning RESET MASTER; SET @@session.gtid_domain_id= 1; SET @@session.server_id= 2; @@ -239,9 +252,11 @@ CREATE TABLE t1 (a int); INSERT INTO t1 values (1); SET @@session.gtid_seq_no= 4; INSERT INTO t1 values (2); ---echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0,1-2-0 --stop-position=0-1-4,1-2-3 > MYSQLTEST_VARDIR/tmp/out.binlog ---error 1 ---exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0,1-2-0 --stop-position=0-1-4,1-2-3 > $MYSQLTEST_VARDIR/tmp/out.binlog +FLUSH LOGS; +--echo # MYSQL_BINLOG MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0,1-2-0 --stop-position=0-1-4,1-2-3 2> log_error_ > MYSQLTEST_VARDIR/tmp/out.binlog +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --start-position=0-1-0,1-2-0 --stop-position=0-1-4,1-2-3 2> $log_error_ > $MYSQLTEST_VARDIR/tmp/out.binlog +--let SEARCH_PATTERN=WARNING +--source include/search_pattern_in_file.inc DROP TABLE t1; DROP TABLE t2; diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index b9105572ba2..56e6cacbc2a 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -3020,7 +3020,8 @@ Window_gtid_event_filter::Window_gtid_event_filter() : m_has_start(FALSE), m_has_stop(FALSE), m_is_active(FALSE), - m_has_passed(FALSE) + m_has_passed(FALSE), + m_warning_flags(0) { // m_start and m_stop do not need initial values if unused } @@ -3034,11 +3035,18 @@ int Window_gtid_event_filter::set_start_gtid(rpl_gtid *start) goto err; } - if (m_has_stop && ((m_stop.domain_id != start->domain_id) || - (start->seq_no >= m_stop.seq_no))) + if (m_has_stop) { - err= 1; - goto err; + DBUG_ASSERT(m_stop.domain_id == start->domain_id); + if (start->seq_no >= m_stop.seq_no) + { + sql_print_error("stop position %d-%d-%llu is not strictly greater than " + "its counterpart start position %d-%d-%llu", + m_stop.domain_id, m_stop.server_id, m_stop.seq_no, + start->domain_id, start->server_id, start->seq_no); + err= 1; + goto err; + } } // Copy values @@ -3047,8 +3055,6 @@ int Window_gtid_event_filter::set_start_gtid(rpl_gtid *start) m_start.server_id= start->server_id; m_start.seq_no= start->seq_no; - last_gtid_seen= m_start; - err: return err; } @@ -3062,11 +3068,18 @@ int Window_gtid_event_filter::set_stop_gtid(rpl_gtid *stop) goto err; } - if (m_has_start && ((m_start.domain_id != stop->domain_id) || - (m_start.seq_no >= stop->seq_no))) + if (m_has_start) { - err= 1; - goto err; + DBUG_ASSERT(m_start.domain_id == stop->domain_id); + if (m_start.seq_no >= stop->seq_no) + { + sql_print_error("stop position %d-%d-%llu is not strictly greater than " + "its counterpart start position %d-%d-%llu", + stop->domain_id, stop->server_id, stop->seq_no, + m_start.domain_id, m_start.server_id, m_start.seq_no); + err= 1; + goto err; + } } // Copy values @@ -3093,16 +3106,11 @@ static inline my_bool is_gtid_at_or_before(rpl_gtid *boundary, test_gtid->seq_no <= boundary->seq_no; } -void Window_gtid_event_filter::assert_gtid_is_expected(rpl_gtid *gtid) +void Window_gtid_event_filter::verify_gtid_is_expected(rpl_gtid *gtid) { - uint64 expect_gtid_seq_no= last_gtid_seen.seq_no + 1; - if (gtid->seq_no != expect_gtid_seq_no) + if (gtid->seq_no != last_gtid_seen.seq_no + 1) { - sql_print_error( - "GTID sequence number is out of order. Got: %llu, but expected: %llu", - gtid->seq_no, expect_gtid_seq_no); - sf_leaking_memory= 1; - exit(1); + m_warning_flags |= WARN_GTID_SEQUENCE_NUMBER_OUT_OF_ORDER; } last_gtid_seen.seq_no++; @@ -3132,14 +3140,18 @@ my_bool Window_gtid_event_filter::exclude(rpl_gtid *gtid) */ m_is_active= TRUE; should_exclude= FALSE; + last_gtid_seen= *gtid; } else if (is_gtid_at_or_after(&m_start, gtid) && (!m_has_stop || is_gtid_at_or_before(&m_stop, gtid))) { - assert_gtid_is_expected(gtid); - m_is_active= TRUE; + /* + Once the window has started, we expect GTIDs to be sequential from here on out + */ + last_gtid_seen= *gtid; + DBUG_PRINT("gtid-event-filter", ("Window: Begin (%d-%d-%llu, %d-%d-%llu]", m_start.domain_id, m_start.server_id, m_start.seq_no, m_stop.domain_id, @@ -3162,7 +3174,7 @@ my_bool Window_gtid_event_filter::exclude(rpl_gtid *gtid) in the results. Additionally check if we are at the end of the window. If no end of the window is provided, go indefinitely */ - assert_gtid_is_expected(gtid); + verify_gtid_is_expected(gtid); should_exclude= FALSE; if (m_has_stop && is_gtid_at_or_after(&m_stop, gtid)) @@ -3185,8 +3197,6 @@ my_bool Window_gtid_event_filter::exclude(rpl_gtid *gtid) } } - last_gtid_seen= *gtid; - return should_exclude; } @@ -3198,6 +3208,15 @@ my_bool Window_gtid_event_filter::has_finished() return last_gtid_seen.seq_no == m_stop.seq_no; } +void Window_gtid_event_filter::write_warnings(FILE *out) +{ + if (m_warning_flags & WARN_GTID_SEQUENCE_NUMBER_OUT_OF_ORDER) + { + fprintf(out, "WARNING: " + "Found out of order GTID sequence number during event processing\n"); + } +} + Id_delegating_gtid_event_filter::Id_delegating_gtid_event_filter() : m_num_explicit_filters(0), m_num_completed_filters(0) { @@ -3323,6 +3342,20 @@ my_bool Id_delegating_gtid_event_filter::has_finished() return m_num_completed_filters == m_num_explicit_filters; } +void Id_delegating_gtid_event_filter::write_warnings(FILE *out) +{ + uint32 i; + for (i = 0; i <= m_filter_id_mask; i++) + { + gtid_filter_element *filter_element= m_filters_by_id[i]; + while(filter_element && filter_element->filter) + { + filter_element->filter->write_warnings(out); + filter_element= filter_element->next; + } + } +} + my_bool Id_delegating_gtid_event_filter::exclude(rpl_gtid *gtid) { gtid_filter_identifier filter_id= get_id_from_gtid(gtid); @@ -3363,10 +3396,16 @@ Domain_gtid_event_filter::find_or_create_window_filter_for_id( wgef= (Window_gtid_event_filter *) filter_element->filter->get_identified_filter(); } + else + { /* - Else: We have an existing filter but it is not of window type so propogate - NULL filter + We have an existing filter but it is not of window type so propogate NULL + filter */ + sql_print_error("cannot subset domain id %d by position, another rule " + "exists on that domain", + domain_id); + } return wgef; } diff --git a/sql/rpl_gtid.h b/sql/rpl_gtid.h index 4c7175dceb2..3e39e5f7823 100644 --- a/sql/rpl_gtid.h +++ b/sql/rpl_gtid.h @@ -422,6 +422,12 @@ public: Returns TRUE when completed, and FALSE when the filter has not finished. */ virtual my_bool has_finished() = 0; + + /* + If any non-fatal issues occurred during filtering, to not pollute the + output with warnings, we wait until after processing to write them. + */ + virtual void write_warnings(FILE *out) = 0; }; /* @@ -439,6 +445,7 @@ public: my_bool exclude(rpl_gtid *gtid) { return FALSE; } uint32 get_filter_type() { return ACCEPT_ALL_GTID_FILTER_TYPE; } my_bool has_finished() { return FALSE; } + void write_warnings(FILE *out) {} }; /* @@ -467,6 +474,7 @@ public: my_bool exclude(rpl_gtid *gtid) { return m_filter->exclude(gtid); } uint32 get_filter_type() { return m_filter->get_filter_type(); } my_bool has_finished() { return m_filter->has_finished(); } + void write_warnings(FILE *out) { return m_filter->write_warnings(out); } protected: gtid_filter_identifier m_filter_id; @@ -497,6 +505,7 @@ public: my_bool exclude(rpl_gtid*); my_bool has_finished(); + void write_warnings(FILE *out); /* Set the GTID that begins this window (exclusive) @@ -517,18 +526,19 @@ public: protected: /* - When processing GTID streams, the order in which they are processed - must be sequential with no gaps between events. - - Errors if the gtid is out of order. - - Note that this only keeps track of GTID order within the window, i.e. if - there is a gap that exists before m_start or after m_stop, this will NOT - throw an error. + When processing GTID streams, the order in which they are processed should + be sequential with no gaps between events. If a gap is found within a + window, warn the user. */ - void assert_gtid_is_expected(rpl_gtid *gtid); + void verify_gtid_is_expected(rpl_gtid *gtid); private: + + enum warning_flags + { + WARN_GTID_SEQUENCE_NUMBER_OUT_OF_ORDER= 0x1 + }; + /* m_has_start : Indicates if a start to this window has been explicitly provided. A window starts immediately if not provided. @@ -563,6 +573,12 @@ private: /* last_gtid_seen: saves the last */ rpl_gtid last_gtid_seen; + + /* + warning_flags: holds flags for any non-fatal issues encountered during + filtering + */ + uint32 m_warning_flags; }; /* @@ -594,6 +610,7 @@ public: my_bool exclude(rpl_gtid *gtid); my_bool has_finished(); + void write_warnings(FILE *out); void set_default_filter(Gtid_event_filter *default_filter); uint32 get_filter_type() { return DELEGATING_GTID_FILTER_TYPE; } |