MINI MINI MANI MO
###############################################################################
# This test does validates two requirements on Group Replication Single Primary
# mode:
# 1) Validate that when a new primary is elected, the conflict detection (which
# is disabled on single primary mode) is enabled until the new primary apply
# all relay logs.
# Points: 1 to 10
# 2) Validate that there are no fake foreign keys conflicts on Group
# Replication while it is operating in single primary mode.
# Points: 11 to 20
###############################################################################
--source include/big_test.inc
--source include/have_debug_sync.inc
--source ../inc/have_group_replication_plugin.inc
--let $rpl_skip_group_replication_start= 1
--let $rpl_group_replication_single_primary_mode=1
--let $rpl_server_count= 3
--source ../inc/group_replication.inc
--echo
--echo ############################################################
--echo # 1. Bootstrap start GR on server1 (Primary).
--echo # Start GR on server2 and server3 (Secondaries).
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
--let $server1_uuid= `SELECT @@server_uuid`
--source ../inc/start_and_bootstrap_group_replication.inc
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
--let $server2_uuid= `SELECT @@server_uuid`
# next primary should be server2 in step5, so setting member weight as 70
# higher then default member_weight value of 50.
--eval SET GLOBAL group_replication_member_weight= 70
--source include/start_group_replication.inc
--let $rpl_connection_name= server3
--source include/rpl_connection.inc
--source include/start_group_replication.inc
# Make sure server1 is the primary
--let $assert_text= Verify group_replication_primary_member is SERVER_UUID
--let $assert_cond= "[SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= \'group_replication_primary_member\', VARIABLE_VALUE, 1]" = "$server1_uuid"
--source include/assert.inc
--echo
--echo ############################################################
--echo # 2. Create a table on group.
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT, KEY(c2));
--source include/rpl_sync.inc
--echo
--echo ############################################################
--echo # 3. Stop applier on server2 in order to transaction TX to
--echo # be delayed.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
--source ../inc/gr_stop_applier_sql_thread.inc
--echo
--echo ############################################################
--echo # 4. Execute transaction TX on server1.
--echo # It will be executed on server1 and server3 but will be
--echo # delayed on server2.
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
INSERT INTO t1 VALUES (1,1);
# Wait until TX is received on server2.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
--let $wait_condition= SELECT received_transaction_set="$group_replication_group_name:1-5" FROM performance_schema.replication_connection_status WHERE channel_name="group_replication_applier"
--source include/wait_condition.inc
# Wait until TX is applied on server3.
--let $rpl_connection_name= server3
--source include/rpl_connection.inc
--let $wait_condition= SELECT @@GLOBAL.GTID_EXECUTED = "$group_replication_group_name:1-5"
--source include/wait_condition.inc
--echo
--echo ############################################################
--echo # 5. Stop GR on server1, this will trigger a new primary election.
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
--source include/stop_group_replication.inc
# The rest of the test depends that server2 is the new primary.
# If that requirement is not met, the test skips it self.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
# server1 is stopped, so only server2 and 3 should be in the group
--let $group_replication_number_of_members= 2
--source ../inc/gr_wait_for_number_of_members.inc
# Make sure server2 is the primary now
--let $assert_text= Verify group_replication_primary_member is SERVER_UUID
--let $assert_cond= "[SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= \'group_replication_primary_member\', VARIABLE_VALUE, 1]" = "$server2_uuid"
--source include/assert.inc
--echo
--echo ############################################################
--echo # 6. Since the new primary is server2 and it has relay logs
--echo # to apply, the conflict detection will be enabled on all
--echo # members and transaction TY will conflict with TX.
--error ER_TRANSACTION_ROLLBACK_DURING_COMMIT
INSERT INTO t1 VALUES (1,1);
--echo
--echo ############################################################
--echo # 7. Start applier on server2 in order to transaction TX to
--echo # be applied (and wait until it is applied).
--source ../inc/gr_start_applier_sql_thread.inc
--let $wait_condition= SELECT @@GLOBAL.GTID_EXECUTED = "$group_replication_group_name:1-5"
--source include/wait_condition.inc
--error ER_DUP_ENTRY
INSERT INTO t1 VALUES (1,1);
--echo
--echo ############################################################
--echo # 8. On future transactions, the new primary will detect that
--echo # it did applied all relay logs and will inform the group
--echo # that conflict detection can be disabled.
# The Single_primary_message::SINGLE_PRIMARY_QUEUE_APPLIED_MESSAGE
# will be send before the next transaction is certified.
# We have the following flow:
# Steps 1 to 7:
# a) server1 leaves the group, server2 is elected as new primary.
# All members will enable conflict detection during the view
# install.
# b) TY is executed, it is rollback since it does conflict with TX.
# c) Applier is started on server2. We wait until all relay log is
# applied.
# d) To validate that, we try to insert again, we hit a ER_DUP_ENTRY.
# Step 8:
# e) We execute "INSERT INTO t1 VALUES (2,2);", server2 detects that
# had applied the relay log and sends a message to all members
# informing that.
# Then checks conflicts on "INSERT INTO t1 VALUES (2,2);"
# f) The message informing that server2 did apply relay log is
# delivered, all members disable conflict detection.
# g) We execute "INSERT INTO t1 VALUES (3,3);", just to ensure that
# certification queue increases and then we can safely wait until
# it decreases to empty.
INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
# Wait that no messages are waiting on certification queue to be
# sure that all single_primary_message was already handled.
--let $wait_condition= SELECT count_transactions_in_queue=0 FROM performance_schema.replication_group_member_stats
--source include/wait_condition.inc
--echo
--echo ############################################################
--echo # 9. Rejoin server1 to the group.
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
--source include/start_group_replication.inc
--echo
--echo ############################################################
--echo # 10. Check data consistency.
--source include/rpl_sync.inc
--let $diff_tables= server1:test.t1, server2:test.t1, server3:test.t1
--source include/diff_tables.inc
--echo
--echo ############################################################
--echo # 11. Create one more table with foreign keys to validate
--echo # that there are no fake foreign keys conflicts on Group
--echo # Replication while it is operating in single primary mode.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
CREATE TABLE t2 (c1 INT PRIMARY KEY, c2 INT, FOREIGN KEY (c2) REFERENCES t1(c2));
--echo
--echo ############################################################
--echo # 12. Set a debug sync before broadcast message to group.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
SET @debug_save= @@GLOBAL.DEBUG;
SET @@GLOBAL.DEBUG='d,group_replication_before_message_broadcast';
--echo
--echo ############################################################
--echo # 13. Commit transaction T1 that will be blocked before broadcast.
--let $rpl_connection_name= server_2
--source include/rpl_connection.inc
BEGIN;
INSERT INTO t2 VALUES (1,1);
--send COMMIT
--echo
--echo ############################################################
--echo # 14. Wait until transaction T1 reaches the
--echo # group_replication_before_message_broadcast debug sync point.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
--let $wait_condition=SELECT COUNT(*)=1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE State = 'debug sync point: now'
--source include/wait_condition.inc
--echo
--echo ############################################################
--echo # 15. Commit transaction T2 that will be blocked before broadcast.
--let $rpl_connection_name= server_2_1
--source include/rpl_connection.inc
BEGIN;
INSERT INTO t2 VALUES (2,1);
--send COMMIT
--echo
--echo ############################################################
--echo # 16. Wait until both transactions reach the
--echo # group_replication_before_message_broadcast debug sync point.
--echo # Signal both transactions to resume the its path.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
--let $wait_condition=SELECT COUNT(*)=2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE State = 'debug sync point: now'
--source include/wait_condition.inc
SET DEBUG_SYNC='now SIGNAL waiting';
SET DEBUG_SYNC='now SIGNAL waiting';
SET @@GLOBAL.DEBUG= @debug_save;
--echo
--echo ############################################################
--echo # 17. Fetch outcome of transaction T1.
--let $rpl_connection_name= server_2
--source include/rpl_connection.inc
--disable_warnings
--reap
--enable_warnings
--echo
--echo ############################################################
--echo # 18. Fetch outcome of transaction T2.
--let $rpl_connection_name= server_2_1
--source include/rpl_connection.inc
--disable_warnings
--reap
--enable_warnings
--echo
--echo ############################################################
--echo # 19. Check data consistency.
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
--source include/rpl_sync.inc
--let $assert_text= Table t2 contains one row with c1=1
--let $assert_cond= [SELECT COUNT(*) AS count FROM t2 WHERE t2.c1=1, count, 1] = 1
--source include/assert.inc
--let $assert_text= Table t2 contains one row with c1=2
--let $assert_cond= [SELECT COUNT(*) AS count FROM t2 WHERE t2.c1=2, count, 1] = 1
--source include/assert.inc
--let $diff_tables= server1:test.t1, server2:test.t1, server3:test.t1
--source include/diff_tables.inc
--let $diff_tables= server1:test.t2, server2:test.t2, server3:test.t2
--source include/diff_tables.inc
--echo
--echo ############################################################
--echo # 20. Clean up.
DROP TABLE t2;
DROP TABLE t1;
SET GLOBAL group_replication_member_weight= DEFAULT;
--source ../inc/group_replication_end.inc
OHA YOOOO