polardbxengine/mysql-test/suite/group_replication/t/gr_start_stop_behaviour.test

352 lines
14 KiB
Plaintext

################################################################################
# Verify that
#
# 1) START/STOP GROUP_REPLICATION commands are not allowed inside a
# transaction
#
# 2) START/STOP GROUP_REPLICATION command is not allowed from the session
# if it acquired a lock on a table (using LOCK TABLES command)
#
# 3) START/STOP GROUP_REPLICATION commands do not do implicit commits
#
# Test:
# 0. The test requires two servers: M1 and M2.
# 1. After starting the group replication, grep the error log to check that NOTE is generated
# 2. With both the members ONLINE. Create a table on M1.
# 3. Initiate a transaction on M1 and try stop GR in the middle of the transaction
# - Check that STOP GR throws ER_LOCK_OR_ACTIVE_TRANSACTION
# - Check that the failure did not utilize any GTID values
# - Check that the failure did not committed any ongoing transaction
# - COMMIT on M1 (UUID_M1:1). Check data is available in table on M1.
# - Check data is available in table on M2.
# 4. Stop GR while GTID_NEXT is specified on M1.
# - Check that STOP GR is succesful.
# - Check GTID_OWNED is non-empty.
# - COMMIT and set GTID_NEXT to AUTOMATIC . Check GTID_OWNED is empty.
# - Check GTID_EXECUTED on M1.
# 5. Initiate a transaction on M1 and try start GR in the middle of the transaction
# - Check that START GR throws ER_LOCK_OR_ACTIVE_TRANSACTION
# - Check that the failure did not utilize any GTID values
# - Check that the failure did not committed any ongoing transaction
# - COMMIT on M1 (UUID_M1:1). Check data is available in table on M1.
# - Clean server by doing RESET MASTER
# 6. Initiate a transaction on M1 (session 1) and try to start GR from session 2
# - From session 1, INSERT a tuple into table that does not have primary key
# i.e., GR incompatible DML
# - From session 2, START GROUP_REPLICATION
# - Try to commit session1's transaction, check that COMMIT fails in before_commit hook
# because there are no writeset for the transaction
#
# 7. Start GR on M1 while GTID_NEXT is specified.
# - Check GTID_OWNED is non-empty.
# - COMMIT and set GTID_NEXT to AUTOMATIC on M1. Check GTID_OWNED is empty.
# - Check GTID_EXECUTED on M1.
# 8. Acquire LOCK on table using LOCK TABLE and try to stop group replication
# - On M2, Session 1, LOCK table t1.
# - On M1, Insert a tuple into t1
# - Let the Insert reach applier thread on M2 and wait till it is trying acquire lock on t1
# - Check that STOP GR on session 1 fails with error ER_LOCK_OR_ACTIVE_TRANSACTION
# - Unlock the tables to proceed with next test case
# 9. Acquire LOCK on table using LOCK TABLE and try to start group replication
# - STOP GR to test the case
# - Lock table t1
# - Check that START GR fails with error ER_LOCK_OR_ACTIVE_TRANSACTION
# - Unlock the tables and START GR and proceed to the next step
# 10. Clean up.
################################################################################
--source include/big_test.inc
--source include/have_group_replication_plugin.inc
--source include/group_replication.inc
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
SET SESSION sql_log_bin= 0;
--source include/gtid_utils.inc
SET SESSION sql_log_bin= 1;
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
SET SESSION sql_log_bin= 0;
--source include/gtid_utils.inc
SET SESSION sql_log_bin= 1;
--echo
--echo ############################################################
--echo # 1. Create a table on the group.
--echo ############################################################
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
--source include/rpl_sync.inc
--echo
--echo ############################################################
--echo # 2. Try to stop Group Replication in the middle of a ongoing
--echo # transaction. It should throw error
--echo # ER_LOCK_OR_ACTIVE_TRANSACTION
--echo ############################################################
BEGIN;
INSERT INTO t1 VALUES (2);
--error ER_LOCK_OR_ACTIVE_TRANSACTION
STOP GROUP_REPLICATION;
--let $assert_text= GTID_EXECUTED must contain 3 group transactions
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-3")
--source include/assert.inc
--let $rpl_connection_name= server_1
--source include/rpl_connection.inc
--let $assert_text= There is no value 2 in table t1
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1 WHERE t1.c1 = 2, count, 1] = 0
--source include/assert.inc
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
COMMIT;
--source include/rpl_sync.inc
--let $assert_text= There is a value 2 in table t1 on server1
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1 WHERE t1.c1 = 2, count, 1] = 1
--source include/assert.inc
--let $assert_text= GTID_EXECUTED must contain 4 group transactions
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-4")
--source include/assert.inc
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
--let $assert_text= There is a value 2 in table t1 on server2
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1 WHERE t1.c1 = 2, count, 1] = 1
--source include/assert.inc
--let $assert_text= GTID_EXECUTED must contain 4 group transactions
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-4")
--source include/assert.inc
--echo
--echo ############################################################
--echo # 3. Stop Group Replication while GTID_NEXT is specified
--echo # and check that GTID is not used by STOP GROUP_REPLICATION
--echo # to prove that STOP GROUP_REPLICATION does not create any
--echo # implicit commits.
--echo ############################################################
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
SET GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1';
--source include/stop_group_replication.inc
--let $assert_text= GTID_EXECUTED must contain 4 group transactions
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-4")
--source include/assert.inc
--let $assert_text= GTID_OWNED is still set since aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1 transaction was not committed
--let $assert_cond= "[SELECT @@SESSION.GTID_OWNED]" <> ""
--source include/assert.inc
COMMIT;
SET GTID_NEXT= AUTOMATIC;
--let $assert_text= GTID_OWNED is empty after committing aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1
--let $assert_cond= "[SELECT @@SESSION.GTID_OWNED]" = ""
--source include/assert.inc
--let $assert_text= GTID_EXECUTED must contain 4 group transactions and 1 local transaction
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-4,aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1")
--source include/assert.inc
--echo
--echo ############################################################
--echo # 4. Try to Start Group Replication in the middle of a ongoing
--echo # transaction. It should throw error
--echo # ER_LOCK_OR_ACTIVE_TRANSACTION
--echo ############################################################
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
BEGIN;
INSERT INTO t1 VALUES (4);
--error ER_LOCK_OR_ACTIVE_TRANSACTION
START GROUP_REPLICATION;
--let $assert_text= GTID_EXECUTED must still contain 4 group transactions and 1 local transaction
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-4,aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1")
--source include/assert.inc
# We need to check on a different connection to do not see
# ongoing transaction on server2 (not committed) data.
--let $rpl_connection_name= server_2
--source include/rpl_connection.inc
--let $assert_text= There is no value 4 in table t1
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1 WHERE t1.c1 = 4, count, 1] = 0
--source include/assert.inc
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
COMMIT;
--let $assert_text= There is a value 4 in table t1 on server1
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1 WHERE t1.c1 = 4, count, 1] = 1
--source include/assert.inc
--let $server1_uuid= query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
--let $assert_text= GTID_EXECUTED must contain 4 group transactions and 2 local transaction
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-4,aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1,$server1_uuid:1")
--source include/assert.inc
# Clean server since it has more transactions than the group.
DROP TABLE t1;
RESET MASTER;
--echo
--echo ##################################################################
--echo # 5. Try to start Group Replication while there are ongoing
--echo # transaction in parallel that does not have any GR compatible
--echo # DMLs (no write set that goes to certification). It should be
--echo # commit hook error.
--echo ##################################################################
# Create a table with no primary key locally for testing the scenario
SET SESSION sql_log_bin= 0;
CALL mtr.add_suppression("Failed to extract the set of items written");
CALL mtr.add_suppression("Run function 'before_commit' in plugin 'group_replication' failed");
CREATE TABLE t_without_primary_key(i INT);
SET SESSION sql_log_bin= 1;
BEGIN;
# No error as the group replication is not started
INSERT INTO t_without_primary_key VALUES (1);
# From a different session, execute start group replication.
--let $rpl_connection_name= server_1
--source include/rpl_connection.inc
--source include/start_group_replication.inc
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
# There are no DMLs in the transaction that needs to be certified
# This situation is an error in Group Replication.
--error ER_RUN_HOOK_ERROR
COMMIT;
SET SESSION sql_log_bin= 0;
DROP TABLE t_without_primary_key;
SET SESSION sql_log_bin= 1;
--echo
--echo ############################################################
--echo # 6. Start Group Replication while GTID_NEXT is specified.
--echo ############################################################
# Stop group replication to get ready to test the next scenario.
--source include/stop_group_replication.inc
# Clean server since it has more transactions than the group.
DROP TABLE t1;
RESET MASTER;
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
SET GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1';
--source include/start_group_replication.inc
--let $assert_text= GTID_EXECUTED must contain 6 group transactions
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-6")
--source include/assert.inc
--let $assert_text= GTID_OWNED is still set since ongoing transaction was not committed
--let $assert_cond= "[SELECT @@SESSION.GTID_OWNED]" <> ""
--source include/assert.inc
COMMIT;
SET GTID_NEXT= AUTOMATIC;
--let $assert_text= GTID_OWNED is empty after committing aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1
--let $assert_cond= "[SELECT @@SESSION.GTID_OWNED]" = ""
--source include/assert.inc
--let $assert_text= GTID_EXECUTED must contain 6 group transactions and 1 local transaction
--let $assert_cond= GTID_IS_EQUAL(@@GLOBAL.GTID_EXECUTED,"$group_replication_group_name:1-6,aaaaaaaa-aaaa-aaaa-aaaa-bbbbbbbbbbbb:1")
--source include/assert.inc
--echo
--echo #################################################################
--echo # 7. Verify that if a session is in lock_table_mode (exclusively
--echo # acquired a lock on a table), stop group replication command
--echo # is not allowed from the session.
--echo #################################################################
# Acquire LOCK on table t1 in server2
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
LOCK table t1 WRITE;
# Execute a DML on server1
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
INSERT INTO t1 values (6);
# Check that applier thread is waiting to acquire lock on t1
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist WHERE info='Waiting for table metadata lock';
--source include/wait_condition.inc
# STOP GROUP_REPLICATION after acquiring exclusive lock in the session
# should be blocked (could lead to deadlock between client thread
# and applier thread)
--error ER_LOCK_OR_ACTIVE_TRANSACTION
STOP GROUP_REPLICATION;
UNLOCK tables;
--echo
--echo #################################################################
--echo # 8. Verify that if a session is in lock_table_mode (exclusively
--echo # acquired a lock on a table), start group replication command
--echo # is not allowed from the session.
--echo #################################################################
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
# Stop group replication to get ready to test the next scenario.
--source include/stop_group_replication.inc
# Acquire LOCK on table t1 in server2
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
LOCK table t1 WRITE;
# START GROUP_REPLICATION after acquiring exclusive lock in the session
# should be blocked (this command will try to convert the server
# into read_only mode and it will hang there until MDL lock acquired
# is released)
--error ER_LOCK_OR_ACTIVE_TRANSACTION
START GROUP_REPLICATION;
# Clean up for the test case
UNLOCK tables;
--source include/start_group_replication.inc
--echo
--echo ############################################################
--echo # 9. Clean up
--echo ############################################################
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
DROP TABLE t1;
--let $rpl_connection_name= server1
--source include/rpl_connection.inc
SET SESSION sql_log_bin= 0;
--source include/gtid_utils_end.inc
SET SESSION sql_log_bin= 1;
--let $rpl_connection_name= server2
--source include/rpl_connection.inc
SET SESSION sql_log_bin= 0;
--source include/gtid_utils_end.inc
SET SESSION sql_log_bin= 1;
--source include/group_replication_end.inc