################################################################################ # Bug#25681518 - CLEANUP PROCEDURE FOR MEMORY ENGINE TABLES BREAKS GTID # REPLICA # # Memory table's data will be lost after server restarts. To keep the data # consistency between master and slave, it just binlogs # 'DELETE FROM `db`.`table_name`' when the memory table is locked first time. # So DELETE statement could be binlogged in many statements. # # Because it was not handled correctly, it caused below problems: ## - COM_FIELD_LIST # it didn't flush binlog cache to binlog file. So the DELETEs were not # binlogged in COM_FIELD_LIST, it was binlogged with next statement together. # # - CREATE TABLE ... LIKE memory_table # - CREATE TABLE ... SELECT memory_table # They were binlogged like: # GTID_log_event # DELETE FROM memory_table # CREATE TABLE ... LIKE memory_table | CREATE TABLE ... SELECT memory_table # # Both statements shared the same gtid event. That was not correct. # # - DELETE was binlogged without BEGIN and COMMIT # It caused some DML binlogged without BEGIN and COMMIT. For example: # INSERT INTO myisam_t1 SELECT * FROM memory_table # it was binlogged as: # GTID_log_event # DELETE FROM memory_table # INSERT INTO myisam_t1 SELECT * FROM memory_table # # The test cases in this file will verify some cases that can be run only when # gtid mode is on. # # See rpl_no_gtid_delete_memory_table_after_start_server.test for the tests with # gtid_mode=off. ################################################################################ --source include/have_gtid.inc --let $rpl_gtid_utils= 1 --source include/master-slave.inc CREATE DATABASE db1; CREATE DATABASE db2; CREATE TABLE t1(c1 INT); CREATE TABLE t2(c1 INT); CREATE TABLE mem_t1(c1 INT PRIMARY KEY) ENGINE = MEMORY; CREATE TABLE mem_t2(c1 INT PRIMARY KEY) ENGINE = MEMORY; CREATE TABLE db1.mem_t1(c1 INT PRIMARY KEY) ENGINE = MEMORY; CREATE TABLE db1.mem_t2(c1 INT PRIMARY KEY) ENGINE = MEMORY; CREATE TABLE db2.mem_t1(c1 INT PRIMARY KEY) ENGINE = MEMORY; CREATE TABLE db2.mem_t2(c1 INT PRIMARY KEY) ENGINE = MEMORY; CREATE TABLE db2.mem_t3(c1 INT PRIMARY KEY) ENGINE = MEMORY; CREATE TABLE db2.mem_t4(c1 INT PRIMARY KEY) ENGINE = MEMORY; CREATE TABLE db2.mem_t5(c1 INT PRIMARY KEY) ENGINE = MEMORY; --delimiter | CREATE TRIGGER tr1 AFTER INSERT ON t2 FOR EACH ROW BEGIN INSERT INTO t1 SELECT * FROM db2.mem_t3; END | --delimiter ; INSERT INTO db1.mem_t1 VALUES(1),(2),(3); INSERT INTO db1.mem_t2 VALUES(1),(2),(3); INSERT INTO db2.mem_t1 VALUES(1),(2),(3); INSERT INTO db2.mem_t2 VALUES(1),(2),(3); INSERT INTO db2.mem_t3 VALUES(1),(2),(3); INSERT INTO db2.mem_t4 VALUES(1),(2),(3); INSERT INTO db2.mem_t5 VALUES(1),(2),(3); --source include/sync_slave_sql_with_master.inc --source include/stop_slave_io.inc --source include/rpl_connection_master.inc # Restart the master server --let $rpl_server_number=1 --source include/rpl_restart_server.inc --source include/rpl_reconnect.inc # Restart slave threads --source include/rpl_connection_slave.inc --source include/start_slave_io.inc --source include/sync_slave_sql.inc --echo # --echo # Test case 1: verify DELETE FROM mem_xx can be binlogged correctly --echo # in CREATE TABLE ... LIKE --source include/rpl_connection_master.inc --source include/gtid_step_reset.inc --source include/save_binlog_position.inc CREATE TABLE t3 LIKE db2.mem_t1; --let $gtid_step_count= 2 --source include/gtid_step_assert.inc --let $limit= 0,4 --let $event_sequence= Gtid # Query/.*BEGIN # Query/.*DELETE.* # Query/.*COMMIT --source include/assert_binlog_events.inc --source include/sync_slave_sql_with_master.inc # DELETE FROM mem_xx have been applied the tables should be empty. SELECT * FROM db2.mem_t1; --echo # --echo # Test case 2: verify DELETE FROM mem_xx can be binlogged correctly --echo # in DML --source include/rpl_connection_master.inc --source include/gtid_step_reset.inc --source include/save_binlog_position.inc # mem_t3 is empty, the UNION makes sure that a row event is binlogged. INSERT INTO t3 SELECT * FROM db2.mem_t2 UNION SELECT 10; --let $gtid_step_count= 2 --source include/gtid_step_assert.inc --let $limit= 0,4 --let $event_sequence= Gtid # Query/.*BEGIN # Query/.*DELETE.* # Query/.*COMMIT --source include/assert_binlog_events.inc --source include/sync_slave_sql_with_master.inc # DELETE FROM mem_xx have been applied the tables should be empty. SELECT * FROM db2.mem_t2; --echo # --echo # Test case 3: verify DELETE FROM mem_xx can be binlogged correctly --echo # in a trigger --source include/rpl_connection_master.inc --source include/gtid_step_reset.inc --source include/save_binlog_position.inc INSERT INTO t2 VALUES(11); --let $gtid_step_count= 2 --source include/gtid_step_assert.inc --source include/assert_binlog_events.inc --source include/sync_slave_sql_with_master.inc # DELETE FROM mem_xx have been applied the tables should be empty. SELECT * FROM db2.mem_t3; --echo # --echo # Test case 4: Verify DELETE FROM mem_xx can be binlog correctly --echo # when ALTER the memory table. --source include/rpl_connection_master.inc --source include/gtid_step_reset.inc --source include/save_binlog_position.inc ALTER TABLE db2.mem_t4 ADD COLUMN c2 INT; --let $gtid_step_count= 2 --source include/gtid_step_assert.inc --source include/assert_binlog_events.inc --source include/sync_slave_sql_with_master.inc # DELETE FROM mem_xx have been applied the tables should be empty. SELECT * FROM db2.mem_t4; --echo # --echo # Test case 5: Verify DELETE FROM mem_xx can be binlog correctly --echo # when DROP the memory table. --source include/rpl_connection_master.inc --source include/gtid_step_reset.inc DROP TABLE db2.mem_t5; --let $gtid_step_count= 1 --source include/gtid_step_assert.inc --source include/sync_slave_sql_with_master.inc --source include/rpl_connection_master.inc DROP TABLE t1, t2, t3, mem_t1, mem_t2; DROP DATABASE db1; DROP DATABASE db2; --source include/rpl_end.inc