mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
586c0c0ef6
Problem: The following statements can cause the slave to go out of sync if logged in statement format: INSERT IGNORE...SELECT INSERT ... SELECT ... ON DUPLICATE KEY UPDATE REPLACE ... SELECT UPDATE IGNORE : CREATE ... IGNORE SELECT CREATE ... REPLACE SELECT Background: Since the order of the rows returned by the SELECT statement or otherwise may differ on master and slave, therefore the above statements may cuase the salve to go out of sync with the master. Fix: Issue a warning when statements like the above are exectued and the bin-logging format is statement. If the logging format is mixed, use row based logging. Marking a statement as unsafe has been done in the sql/sql_parse.cc instead of sql/sql_yacc.cc, because while parsing for a token has been done we cannot be sure if the parsing of the other tokens has been done as well. Six new warning messages has been added for each unsafe statement. binlog.binlog_unsafe.test has been updated to incoporate these additional unsafe statments. ****** BUG#11758262 - 50439: MARK INSERT...SEL...ON DUP KEY UPD,REPLACE...SEL,CREATE...[IGN|REPL] SEL Problem: The following statements can cause the slave to go out of sync if logged in statement format: INSERT IGNORE...SELECT INSERT ... SELECT ... ON DUPLICATE KEY UPDATE REPLACE ... SELECT UPDATE IGNORE : CREATE ... IGNORE SELECT CREATE ... REPLACE SELECT Background: Since the order of the rows returned by the SELECT statement or otherwise may differ on master and slave, therefore the above statements may cuase the salve to go out of sync with the master. Fix: Issue a warning when statements like the above are exectued and the bin-logging format is statement. If the logging format is mixed, use row based logging. Marking a statement as unsafe has been done in the sql/sql_parse.cc instead of sql/sql_yacc.cc, because while parsing for a token has been done we cannot be sure if the parsing of the other tokens has been done as well. Six new warning messages has been added for each unsafe statement. binlog.binlog_unsafe.test has been updated to incoporate these additional unsafe statments. mysql-test/extra/rpl_tests/rpl_insert_duplicate.test: Test removed: Added the test to rpl.rpl_insert_ignore.test ****** Test removed: the test is redundant as the same is being tested in rpl.rpl_insert_ignore. mysql-test/extra/rpl_tests/rpl_insert_id.test: Warnings disabled for the unsafe statements. mysql-test/extra/rpl_tests/rpl_insert_ignore.test: 1. Disabled warnings while for unsafe statements 2. As INSERT...IGNORE is an unsafe statement, an insert ignore not changing any rows, will not be logged in the binary log, in the ROW and MIXED modes. It will however be logged in STATEMENT mode. mysql-test/r/commit_1innodb.result: updated result file ****** updated result file mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Updated result file. mysql-test/suite/binlog/r/binlog_unsafe.result: updated result file mysql-test/suite/binlog/t/binlog_unsafe.test: added tests for the statements marked as unsafe. mysql-test/suite/rpl/r/rpl_insert_duplicate.result: File Removed :Result file of rpl_insert_duplicate, which has been removed. mysql-test/suite/rpl/r/rpl_insert_ignore.result: Added the content of rpl.rpl_insert_duplicate here. mysql-test/suite/rpl/r/rpl_insert_select.result: Result file removed as the corresponding test has beenn removed. mysql-test/suite/rpl/r/rpl_known_bugs_detection.result: Updated result file. mysql-test/suite/rpl/t/rpl_insert_duplicate.test: File Removed: this was a wrapper for rpl.rpl_insert_duplicate.test, which has been removed. mysql-test/suite/rpl/t/rpl_insert_select.test: File Removed: This test became redundant after this fix, This test showed how INSERT IGNORE...SELECT break replication, which has been handled in this fix. mysql-test/suite/rpl/t/rpl_known_bugs_detection.test: Since all the tests are statement based bugs are being tested, having mixed format forces the event to be written in row format. When the statement and causes the test to fail as certain known bugs do not occur when the even is logged in row format. sql/share/errmsg-utf8.txt: added 6 new Warning messages. ****** added 6 new Warning messages. sql/sql_lex.cc: Added 6 new error Identifier [ER_BINLOG_STMT_UNSAFEE_*] sql/sql_lex.h: Added 6 new BINLOG_STMT_UNSAFE_* enums to identify the type of unsafe statement dealt with in this bug. ****** Added 6 new BINLOG_STMT_UNSAFE_* enums to identify the type of unsafe statement dealt with in this bug. sql/sql_parse.cc: added check for specific queries and marked them as unsafe. ****** added check for specific queries and marked them as unsafe.
121 lines
4.6 KiB
Text
121 lines
4.6 KiB
Text
# Testcase for BUG#6287 "Slave skips auto_increment values in Replication with InnoDB"
|
|
# The bug was that if on master, INSERT IGNORE ignored some
|
|
# rows, and the table was InnoDB with auto_inc column, then on slave
|
|
# some rows received an auto_inc bigger than on master.
|
|
# Slave needs to be started with --innodb to store table in InnoDB.
|
|
# Same test for MyISAM (which had no bug).
|
|
|
|
--connection master
|
|
eval CREATE TABLE t1 (
|
|
a int unsigned not null auto_increment primary key,
|
|
b int unsigned,
|
|
unique (b)
|
|
) ENGINE=$engine_type;
|
|
|
|
eval CREATE TABLE t2 (
|
|
a int unsigned, # to force INSERT SELECT to have a certain order
|
|
b int unsigned
|
|
) ENGINE=$engine_type;
|
|
|
|
|
|
INSERT INTO t1 VALUES (NULL, 1);
|
|
INSERT INTO t1 VALUES (NULL, 2);
|
|
INSERT INTO t1 VALUES (NULL, 3);
|
|
INSERT INTO t1 VALUES (NULL, 4);
|
|
|
|
# An alternation of values which will conflict in t1 and will not.
|
|
|
|
INSERT INTO t2 VALUES (1, 1);
|
|
INSERT INTO t2 VALUES (2, 2);
|
|
INSERT INTO t2 VALUES (3, 5);
|
|
INSERT INTO t2 VALUES (4, 3);
|
|
INSERT INTO t2 VALUES (5, 4);
|
|
INSERT INTO t2 VALUES (6, 6);
|
|
--disable_warnings ONCE
|
|
INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
|
|
--let $assert_cond= COUNT(*) = 6 FROM t1
|
|
--let $assert_text= Count of elements in t1 should be 6.
|
|
--source include/assert.inc
|
|
|
|
# Compare master and slave
|
|
--sync_slave_with_master
|
|
--let $diff_tables= master:test.t1 , slave:test.t1
|
|
--source include/diff_tables.inc
|
|
|
|
# BUG#59338 Inconsistency in binlog for statements that don't change any rows STATEMENT SBR
|
|
# An insert ignore that does not update anything must be written to the binary log in SBR
|
|
# and MIXED modes. We check this property by counting occurrences in t1 before and after
|
|
# the insert and comparing the binlog positions. The count should be the same in both points
|
|
# and the statement should be in the binary log.
|
|
--connection master
|
|
--let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1)
|
|
--let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1)
|
|
--let $statement_file=INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a
|
|
--disable_warnings ONCE
|
|
--eval $statement_file
|
|
|
|
--let $assert_cond= COUNT(*) = 6 FROM t1
|
|
--let $assert_text= Count of elements in t1 should be 6.
|
|
--source include/assert.inc
|
|
|
|
if (`SELECT @@BINLOG_FORMAT != 'STATEMENT'`)
|
|
{
|
|
--let $binlog_position_cmp= =
|
|
--let $assert_cond= [SHOW MASTER STATUS, Position, 1] $binlog_position_cmp $binlog_start
|
|
--let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.
|
|
}
|
|
if (`SELECT @@BINLOG_FORMAT = 'STATEMENT'`)
|
|
{
|
|
--let $assert_cond= \'[\'SHOW BINLOG EVENTS IN "$binlog_file" FROM $binlog_start LIMIT 2, 1\', Info, 1]\' LIKE \'%$statement_file\'
|
|
--let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.
|
|
}
|
|
|
|
--source include/assert.inc
|
|
|
|
# An insert duplicate that does not update anything must be written to the binary
|
|
# log in SBR and MIXED modes. We check this property by summing a before and after
|
|
# the update and comparing the binlog positions. The sum should be the same at both
|
|
# points and the statement should be in the binary log.
|
|
--disable_warnings
|
|
DROP TABLE t1;
|
|
DROP TABLE t2;
|
|
--enable_warnings
|
|
eval CREATE TABLE t1 (
|
|
a INT UNSIGNED NOT NULL PRIMARY KEY
|
|
) ENGINE=$engine_type;
|
|
|
|
eval CREATE TABLE t2 (
|
|
a INT UNSIGNED
|
|
) ENGINE=$engine_type;
|
|
|
|
INSERT INTO t1 VALUES (1);
|
|
INSERT INTO t2 VALUES (1);
|
|
|
|
--let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1)
|
|
--let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1)
|
|
--let $statement_file=INSERT INTO t1 SELECT t2.a FROM t2 ORDER BY t2.a ON DUPLICATE KEY UPDATE t1.a= t1.a
|
|
--disable_warnings ONCE
|
|
--eval $statement_file
|
|
|
|
--let $assert_cond= SUM(a) = 1 FROM t1
|
|
--let $assert_text= Sum of elements in t1 should be 1.
|
|
--source include/assert.inc
|
|
|
|
if (`SELECT @@BINLOG_FORMAT != 'STATEMENT'`)
|
|
{
|
|
--let $binlog_position_cmp= =
|
|
--let $assert_cond= [SHOW MASTER STATUS, Position, 1] $binlog_position_cmp $binlog_start
|
|
--let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.
|
|
}
|
|
if (`SELECT @@BINLOG_FORMAT = 'STATEMENT'`)
|
|
{
|
|
--let $assert_cond= \'[\'SHOW BINLOG EVENTS IN "$binlog_file" FROM $binlog_start LIMIT 1, 1\', Info, 1]\' LIKE \'%$statement_file\'
|
|
--let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged.
|
|
}
|
|
--source include/assert.inc
|
|
|
|
|
|
# Clean up
|
|
--connection master
|
|
drop table t1, t2;
|
|
--sync_slave_with_master
|