1--source include/have_tokudb.inc 2--source include/have_debug.inc 3--source include/have_debug_sync.inc 4--source include/master-slave.inc 5 6--connection master 7ALTER TABLE mysql.gtid_slave_pos ENGINE=TokuDB; 8CREATE TABLE t1 (a int PRIMARY KEY, b INT, UNIQUE KEY (b)) ENGINE=TokuDB; 9--save_master_pos 10 11--connection slave 12--sync_with_master 13SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; 14--source include/stop_slave.inc 15SET GLOBAL slave_parallel_threads=10; 16CHANGE MASTER TO master_use_gtid=slave_pos; 17SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; 18SET GLOBAL slave_parallel_mode='optimistic'; 19 20 21--connection master 22 23INSERT INTO t1 VALUES(1,1); 24BEGIN; 25INSERT INTO t1 VALUES(2,2); 26INSERT INTO t1 VALUES(3,3); 27COMMIT; 28 29# Do a bunch of INSERT/DELETE on the same rows, bound to conflict. 30# We will get a lot of rollbacks, probably, but they should be handled without 31# any visible errors. 32 33DELETE FROM t1 WHERE a=2; 34INSERT INTO t1 VALUES (2,2); 35DELETE FROM t1 WHERE a=2; 36INSERT INTO t1 VALUES (2,6); 37DELETE FROM t1 WHERE a=2; 38INSERT INTO t1 VALUES (2,4); 39DELETE FROM t1 WHERE a=2; 40INSERT INTO t1 VALUES (2,5); 41 42DELETE FROM t1 WHERE a=3; 43INSERT INTO t1 VALUES(3,3); 44DELETE FROM t1 WHERE a=1; 45INSERT INTO t1 VALUES(1,4); 46DELETE FROM t1 WHERE a=3; 47INSERT INTO t1 VALUES(3,3); 48 49DELETE FROM t1 WHERE a=2; 50INSERT INTO t1 VALUES (2,6); 51--source include/save_master_gtid.inc 52SELECT * FROM t1 ORDER BY a; 53 54--connection slave 55--source include/start_slave.inc 56--source include/sync_with_master_gtid.inc 57SELECT * FROM t1 ORDER BY a; 58#SHOW STATUS LIKE 'Slave_retried_transactions'; 59 60 61--echo *** Test a bunch of non-transactional/DDL event groups. *** 62 63--connection slave 64--source include/stop_slave.inc 65 66--connection master 67 68INSERT INTO t1 VALUES (4,8); 69INSERT INTO t1 VALUES (5,9); 70CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=TokuDB; 71INSERT INTO t2 VALUES (1); 72CREATE TABLE t3 (a INT PRIMARY KEY) ENGINE=MyISAM; 73ALTER TABLE t2 ADD b INT; 74INSERT INTO t2 VALUES (2,2); 75ALTER TABLE t2 DROP b; 76INSERT INTO t2 VALUES (3); 77ALTER TABLE t2 ADD c INT; 78INSERT INTO t2 VALUES (4,5); 79INSERT INTO t2 VALUES (5,5); 80INSERT INTO t3 VALUES (1); 81UPDATE t2 SET c=NULL WHERE a=4; 82ALTER TABLE t2 ADD UNIQUE (c); 83INSERT INTO t2 VALUES (6,6); 84UPDATE t2 SET c=c+100 WHERE a=2; 85INSERT INTO t3(a) VALUES (2); 86DELETE FROM t3 WHERE a=2; 87INSERT INTO t3(a) VALUES (2); 88DELETE FROM t3 WHERE a=2; 89ALTER TABLE t3 CHANGE a c INT NOT NULL; 90INSERT INTO t3(c) VALUES (2); 91DELETE FROM t3 WHERE c=2; 92INSERT INTO t3 SELECT a+200 FROM t2; 93DELETE FROM t3 WHERE c >= 200; 94INSERT INTO t3 SELECT a+200 FROM t2; 95--source include/save_master_gtid.inc 96SELECT * FROM t1 ORDER BY a; 97SELECT * FROM t2 ORDER BY a; 98SELECT * FROM t3 ORDER BY c; 99 100--connection slave 101--source include/start_slave.inc 102--source include/sync_with_master_gtid.inc 103SELECT * FROM t1 ORDER BY a; 104SELECT * FROM t2 ORDER BY a; 105SELECT * FROM t3 ORDER BY c; 106#SHOW STATUS LIKE 'Slave_retried_transactions'; 107 108 109--echo *** Test @@skip_parallel_replication. *** 110 111--connection slave 112--source include/stop_slave.inc 113--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) 114 115--connection master 116# We do a bunch of conflicting transactions on the master with 117# skip_parallel_replication set to true, and check that we do not 118# get any retries on the slave. 119 120UPDATE t1 SET b=10 WHERE a=3; 121SET SESSION skip_parallel_replication=1; 122UPDATE t1 SET b=20 WHERE a=3; 123UPDATE t1 SET b=30 WHERE a=3; 124UPDATE t1 SET b=50 WHERE a=3; 125UPDATE t1 SET b=80 WHERE a=3; 126UPDATE t1 SET b=130 WHERE a=3; 127UPDATE t1 SET b=210 WHERE a=3; 128UPDATE t1 SET b=340 WHERE a=3; 129UPDATE t1 SET b=550 WHERE a=3; 130UPDATE t1 SET b=890 WHERE a=3; 131SET SESSION skip_parallel_replication=0; 132SELECT * FROM t1 ORDER BY a; 133--source include/save_master_gtid.inc 134 135--connection slave 136--source include/start_slave.inc 137--source include/sync_with_master_gtid.inc 138SELECT * FROM t1 ORDER BY a; 139--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) 140--disable_query_log 141eval SELECT IF($retry1=$retry2, "Ok, no retry", 142 CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", 143 $retry1, " now ", $retry2, ")")) AS status; 144--enable_query_log 145 146 147--echo *** Test that we do not replicate in parallel transactions that had row lock waits on the master *** 148 149--connection slave 150--source include/stop_slave.inc 151--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) 152 153--connection master 154# Setup a bunch of transactions that all needed to wait. 155--connect (m1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) 156--connect (m2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) 157--connect (m3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) 158--connect (m4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) 159--connect (m5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) 160--connect (m6,127.0.0.1,root,,test,$SERVER_MYPORT_1,) 161--connect (m7,127.0.0.1,root,,test,$SERVER_MYPORT_1,) 162--connect (m8,127.0.0.1,root,,test,$SERVER_MYPORT_1,) 163 164--connection default 165BEGIN; UPDATE t1 SET b=b+1 WHERE a=3; 166 167--connection m1 168SET debug_sync='thd_report_wait_for SIGNAL waiting1'; 169send UPDATE t1 SET b=1001 WHERE a=3; 170--connection default 171SET debug_sync='now WAIT_FOR waiting1'; 172 173--connection m2 174BEGIN; 175UPDATE t1 SET b=1002 WHERE a=5; 176SET debug_sync='thd_report_wait_for SIGNAL waiting2'; 177send UPDATE t1 SET b=102 WHERE a=3; 178--connection default 179SET debug_sync='now WAIT_FOR waiting2'; 180 181UPDATE t1 SET b=1000 WHERE a=1; 182--connection m3 183SET debug_sync='thd_report_wait_for SIGNAL waiting3'; 184send UPDATE t1 SET b=1003 WHERE a=5; 185--connection default 186SET debug_sync='now WAIT_FOR waiting3'; 187 188--connection m4 189SET debug_sync='thd_report_wait_for SIGNAL waiting4'; 190send UPDATE t1 SET b=1004 WHERE a=3; 191--connection default 192SET debug_sync='now WAIT_FOR waiting4'; 193 194--connection m5 195SET debug_sync='thd_report_wait_for SIGNAL waiting5'; 196send UPDATE t1 SET b=1005 WHERE a=5; 197--connection default 198SET debug_sync='now WAIT_FOR waiting5'; 199 200--connection m6 201SET debug_sync='thd_report_wait_for SIGNAL waiting6'; 202send UPDATE t1 SET b=1006 WHERE a=1; 203--connection default 204SET debug_sync='now WAIT_FOR waiting6'; 205 206--connection m7 207SET debug_sync='thd_report_wait_for SIGNAL waiting7'; 208send UPDATE t1 SET b=1007 WHERE a=5; 209--connection default 210SET debug_sync='now WAIT_FOR waiting7'; 211 212--connection m8 213SET debug_sync='thd_report_wait_for SIGNAL waiting8'; 214send UPDATE t1 SET b=1008 WHERE a=3; 215--connection default 216SET debug_sync='now WAIT_FOR waiting8'; 217 218--connection default 219COMMIT; 220--connection m1 221REAP; 222--connection m2 223REAP; 224COMMIT; 225--connection m3 226REAP; 227--connection m4 228REAP; 229--connection m5 230REAP; 231--connection m6 232REAP; 233--connection m7 234REAP; 235--connection m8 236REAP; 237--connection default 238SET debug_sync='RESET'; 239 240--source include/save_master_gtid.inc 241# It is not deterministic in which order the parallel conflicting 242# updates will run. Eg. for key a=5, we could get 1003, 1005, or 243# 1007. As long as we get the same on the slave, it is ok. 244--let $master_value= `SELECT GROUP_CONCAT(CONCAT("(", a, ",", b, ")") ORDER BY a, b SEPARATOR "/") FROM t1` 245 246--connection slave 247--source include/start_slave.inc 248--source include/sync_with_master_gtid.inc 249--let $slave_value= `SELECT GROUP_CONCAT(CONCAT("(", a, ",", b, ")") ORDER BY a, b SEPARATOR "/") FROM t1` 250--disable_query_log 251eval SET @master_value="$master_value"; 252eval SET @slave_value="$slave_value"; 253--enable_query_log 254SELECT IF(@master_value=@slave_value, "Slave data matches master", CONCAT("ERROR: Slave had different data '", @slave_value, "' than master's '", @master_value, "'!")) as check_result; 255--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) 256--disable_query_log 257eval SELECT IF($retry1=$retry2, "Ok, no retry", 258 CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", 259 $retry1, " now ", $retry2, ")")) AS status; 260--enable_query_log 261 262 263--echo *** Test that we replicate correctly when using READ COMMITTED and binlog_format=MIXED on the slave *** 264 265--connection slave 266--source include/stop_slave.inc 267SET @old_format= @@GLOBAL.binlog_format; 268# Use MIXED format; we cannot binlog ROW events on slave in STATEMENT format. 269SET GLOBAL binlog_format= MIXED; 270SET @old_isolation= @@GLOBAL.tx_isolation; 271SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; 272# Reset the worker threads to make the new settings take effect. 273SET GLOBAL slave_parallel_threads=0; 274SET GLOBAL slave_parallel_threads=10; 275 276--connection master 277DROP TABLE t1, t2; 278CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=TokuDB; 279CREATE TABLE t2 (a int PRIMARY KEY, b INT) ENGINE=TokuDB; 280INSERT INTO t1 VALUES (1,0), (2,0), (3,0); 281INSERT INTO t2 VALUES (1,0), (2,0); 282INSERT INTO t1 SELECT 4, COUNT(*) FROM t2; 283INSERT INTO t2 SELECT 4, COUNT(*) FROM t1; 284 285INSERT INTO t1 SELECT 5, COUNT(*) FROM t2; 286INSERT INTO t2 SELECT 5, COUNT(*) FROM t1; 287 288INSERT INTO t2 SELECT 6, COUNT(*) FROM t1; 289INSERT INTO t1 SELECT 6, COUNT(*) FROM t2; 290 291INSERT INTO t1 SELECT 7, COUNT(*) FROM t2; 292INSERT INTO t2 SELECT 7, COUNT(*) FROM t1; 293 294INSERT INTO t2 SELECT 8, COUNT(*) FROM t1; 295INSERT INTO t1 SELECT 8, COUNT(*) FROM t2; 296 297INSERT INTO t2 SELECT 9, COUNT(*) FROM t1; 298INSERT INTO t1 SELECT 9, COUNT(*) FROM t2; 299 300INSERT INTO t1 SELECT 10, COUNT(*) FROM t2; 301INSERT INTO t2 SELECT 10, COUNT(*) FROM t1; 302 303SELECT * FROM t1 ORDER BY a; 304SELECT * FROM t2 ORDER BY a; 305--source include/save_master_gtid.inc 306 307--connection slave 308--source include/start_slave.inc 309--source include/sync_with_master_gtid.inc 310SELECT * FROM t1 ORDER BY a; 311SELECT * FROM t2 ORDER BY a; 312 313--source include/stop_slave.inc 314SET GLOBAL binlog_format= @old_format; 315SET GLOBAL tx_isolation= @old_isolation; 316--source include/start_slave.inc 317 318 319--echo *** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** 320 321--connection master 322DROP TABLE t1, t2, t3; 323CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=TokuDB; 324CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=TokuDB; 325CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=MyISAM; 326INSERT INTO t2 VALUES (1,1), (2,1), (3,1), (4,1), (5,1); 327--source include/save_master_gtid.inc 328 329--connection slave 330--source include/sync_with_master_gtid.inc 331--source include/stop_slave.inc 332SET @old_dbug= @@GLOBAL.debug_dbug; 333SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; 334 335--connection master 336# The bug was that ANALYZE TABLE would call 337# wakeup_subsequent_commits() too early, allowing the following 338# transaction in the same group to run ahead and binlog and free the 339# GCO. Then we get wrong binlog order and later access freed GCO, 340# which causes lost wakeup of following GCO and thus replication hang. 341# We injected a small sleep in ANALYZE to make the race easier to hit (this 342# can only cause false negatives in versions with the bug, not false positives, 343# so sleep is ok here. And it's in general not possible to trigger reliably 344# the race with debug_sync, since the bugfix makes the race impossible). 345 346ALTER TABLE t2 COMMENT "123abc"; 347ANALYZE TABLE t2; 348INSERT INTO t1 VALUES (1,2); 349INSERT INTO t1 VALUES (2,2); 350INSERT INTO t1 VALUES (3,2); 351INSERT INTO t1 VALUES (4,2); 352INSERT INTO t3 VALUES (1,3); 353ALTER TABLE t2 COMMENT "hello, world"; 354BEGIN; 355INSERT INTO t1 VALUES (5,4); 356INSERT INTO t1 VALUES (6,4); 357INSERT INTO t1 VALUES (7,4); 358INSERT INTO t1 VALUES (8,4); 359INSERT INTO t1 VALUES (9,4); 360INSERT INTO t1 VALUES (10,4); 361INSERT INTO t1 VALUES (11,4); 362INSERT INTO t1 VALUES (12,4); 363INSERT INTO t1 VALUES (13,4); 364INSERT INTO t1 VALUES (14,4); 365INSERT INTO t1 VALUES (15,4); 366INSERT INTO t1 VALUES (16,4); 367INSERT INTO t1 VALUES (17,4); 368INSERT INTO t1 VALUES (18,4); 369INSERT INTO t1 VALUES (19,4); 370INSERT INTO t1 VALUES (20,4); 371COMMIT; 372INSERT INTO t1 VALUES (21,5); 373INSERT INTO t1 VALUES (22,5); 374 375SELECT * FROM t1 ORDER BY a; 376SELECT * FROM t2 ORDER BY a; 377SELECT * FROM t3 ORDER BY a; 378--source include/save_master_gtid.inc 379 380--connection slave 381--source include/start_slave.inc 382--source include/sync_with_master_gtid.inc 383 384SELECT * FROM t1 ORDER BY a; 385SELECT * FROM t2 ORDER BY a; 386SELECT * FROM t3 ORDER BY a; 387 388--source include/stop_slave.inc 389SET GLOBAL debug_dbug= @old_debug; 390--source include/start_slave.inc 391 392--echo *** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** 393 394--connection slave 395--source include/stop_slave.inc 396SET @old_dbug= @@GLOBAL.debug_dbug; 397# The bug was that record_gtid(), when there is no existing transaction from 398# a DML event being replicated, would commit its own transaction. This wrongly 399# caused wakeup_subsequent_commits(), with similar consequences as MDEV-7888 400# above. We simulate this condition with a small sleep in record_gtid() for 401# a specific ANALYZE that we binlog with server id 100. 402SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; 403 404--connection master 405 406ALTER TABLE t3 COMMENT "DDL statement 1"; 407INSERT INTO t1 VALUES (30,0); 408INSERT INTO t1 VALUES (31,0); 409INSERT INTO t1 VALUES (32,0); 410INSERT INTO t1 VALUES (33,0); 411INSERT INTO t1 VALUES (34,0); 412INSERT INTO t1 VALUES (35,0); 413INSERT INTO t1 VALUES (36,0); 414SET @old_server_id= @@SESSION.server_id; 415SET SESSION server_id= 100; 416ANALYZE TABLE t2; 417SET SESSION server_id= @old_server_id; 418INSERT INTO t1 VALUES (37,0); 419ALTER TABLE t3 COMMENT "DDL statement 2"; 420INSERT INTO t1 VALUES (38,0); 421INSERT INTO t1 VALUES (39,0); 422ALTER TABLE t3 COMMENT "DDL statement 3"; 423 424SELECT * FROM t1 WHERE a >= 30 ORDER BY a; 425 426--source include/save_master_gtid.inc 427 428 429--connection slave 430--source include/start_slave.inc 431--source include/sync_with_master_gtid.inc 432SELECT * FROM t1 WHERE a >= 30 ORDER BY a; 433 434 435--source include/stop_slave.inc 436SET GLOBAL debug_dbug= @old_debug; 437--source include/start_slave.inc 438 439 440--echo *** MDEV-8113: ALTER TABLE causes slave hang in optimistic parallel replication *** 441 442--connection slave 443--source include/stop_slave.inc 444 445--connection master 446ALTER TABLE t2 ADD c INT; 447INSERT INTO t2 (a,b) VALUES (50, 0); 448INSERT INTO t2 (a,b) VALUES (51, 1); 449INSERT INTO t2 (a,b) VALUES (52, 2); 450INSERT INTO t2 (a,b) VALUES (53, 3); 451INSERT INTO t2 (a,b) VALUES (54, 4); 452INSERT INTO t2 (a,b) VALUES (55, 5); 453INSERT INTO t2 (a,b) VALUES (56, 6); 454INSERT INTO t2 (a,b) VALUES (57, 7); 455INSERT INTO t2 (a,b) VALUES (58, 8); 456INSERT INTO t2 (a,b) VALUES (59, 9); 457ALTER TABLE t2 DROP COLUMN c; 458SELECT * FROM t2 WHERE a >= 50 ORDER BY a; 459--source include/save_master_gtid.inc 460 461--connection slave 462--source include/start_slave.inc 463--source include/sync_with_master_gtid.inc 464SELECT * FROM t2 WHERE a >= 50 ORDER BY a; 465 466 467# Clean up. 468 469--connection slave 470--source include/stop_slave.inc 471SET GLOBAL slave_parallel_mode=@old_parallel_mode; 472SET GLOBAL slave_parallel_threads=@old_parallel_threads; 473--source include/start_slave.inc 474 475--connection master 476DROP TABLE t1, t2, t3; 477 478--source include/rpl_end.inc 479