summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/galera/t/galera_nonPK_and_PA.test
blob: 8a5173f576bcc3ef3b90e8ebe280bd3578390bf4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#
# This test is a modified version of Gabor Orosz (GOro) test in jira tracker:
# https://jira.mariadb.org/browse/MDEV-25551
#
# The underlying problem with MDEV-25551 turned out to be that
# transactions having changes for tables with no primary key, 
# were not safe to apply in parallel. This is due to excessive locking
# in innodb side, and even non related row modifications could end up
# in lock conflict during applying.
#
# The test creates a table with no primary key definition and executes two
# transactions (in node1) modifying separate rows in the table. In node2
# first applier is paused before commit phase, and second transaction is
# then submitted to see if it can interfere with the first transaciton.
# The fix for MDEV-25551 has disabled parallel applying for tables with no PK,
# and in the test applying of the send trasnaction should not even start, before
# the fisrt trkansaction is released from the sync point.
# The test also verifies that certification depedency status reflects the fact
# that the two transactions depend on each other.
#
# The test has two scenarios where both UPDATE and DELETE statements are verified
# to disable parallel applying
#

--source include/galera_cluster.inc
--source include/have_debug_sync.inc
--source include/galera_have_debug_sync.inc


# Setup

CREATE TABLE t1 (f1 VARCHAR(32) NOT NULL) ENGINE=InnoDB;
INSERT INTO t1 (f1) VALUES ('0e66c5227a8a');
INSERT INTO t1 (f1) VALUES ('c6c112992c9');

CREATE TABLE t2 (i int primary key);

--connection node_2
SET SESSION wsrep_sync_wait = 0;
--let $wait_condition = SELECT COUNT(*)=2 FROM t1;
--source include/wait_condition.inc

# Ensure that we have enough applier threads to process transactions in parallel
SET GLOBAL wsrep_slave_threads = 2;

--echo ***************************************************************
--echo scenario 1,  conflicting UPDATE
--echo ***************************************************************

# Set up a synchronization point to catch the first transaction
--let $galera_sync_point = commit_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc

--connection node_1
# Invoke the first transaction
START TRANSACTION;
UPDATE t1 SET f1='5ffceebfada' WHERE t1.f1 = 'c6c112992c9';
COMMIT;

--connection node_2
# Wait for the first transaction to apply until commit phase
--let $galera_sync_point = commit_monitor_slave_enter_sync
--source include/galera_wait_sync_point.inc

# remember status for received replication counter and certification dependency distance
--let $expected_wsrep_received = `SELECT VARIABLE_VALUE+1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_received'`
--let $cert_deps_distance = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cert_deps_distance'`

--connection node_1
# Invoke the second transaction
START TRANSACTION;
UPDATE t1 SET f1='4ffceebfcdc' WHERE t1.f1 = '0e66c5227a8a';
COMMIT;

# sleep is probably obsolete here, but it is good to give the latter update time to
# proceed in applying in node 2. In buggy version the update will start applying
# and cause conflict there.
--sleep 5

--connection node_2
# Wait for the second transaction to appear in repliaction queue
--let $wait_condition = SELECT VARIABLE_VALUE= $expected_wsrep_received FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_received';
--source include/wait_condition.inc

# verify that certification dependency distance has dropped
--disable_query_log
--eval  SELECT  VARIABLE_VALUE < $cert_deps_distance as 'distance' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cert_deps_distance'
--enable_query_log

# if deps distance dropped, it is indirect evidence that parallel applying was not approved

# Let the first transaction to proceed
--let $galera_sync_point = commit_monitor_slave_enter_sync
--source include/galera_signal_sync_point.inc

# second applier should now hit sync point
--let $galera_sync_point = commit_monitor_slave_enter_sync
--source include/galera_wait_sync_point.inc
--source include/galera_signal_sync_point.inc
--source include/galera_clear_sync_point.inc


--echo ***************************************************************
--echo scenario 2,  conflicting DELETE
--echo ***************************************************************

# Set up a synchronization point to catch the first transaction
--let $galera_sync_point = commit_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc

--connection node_1
# Invoke the first transaction, mix this with insert to table having PK
START TRANSACTION;
INSERT INTO t2 VALUES (1);
DELETE FROM t1 WHERE f1='5ffceebfada';
COMMIT;

--connection node_2
# Wait for the first transaction to apply until commit phase
--let $galera_sync_point = commit_monitor_slave_enter_sync
--source include/galera_wait_sync_point.inc

# remember status for received replication counter and certification dependency distance
--let $expected_wsrep_received = `SELECT VARIABLE_VALUE+1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_received'`
--let $cert_deps_distance = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cert_deps_distance'`

--connection node_1
# Invoke the second transaction, again mix this with insert to table having PK
START TRANSACTION;
INSERT INTO t2 VALUES (2);
DELETE FROM t1 WHERE f1='4ffceebfcdc';
COMMIT;

# sleep is probably obsolete here, but it is good to give the latter update time to
# proceed in applying in node 2. In buggy version the update will start applying
# and cause conflict there.
--sleep 5

--connection node_2
# Wait for the second transaction to appear in repliaction queue
--let $wait_condition = SELECT VARIABLE_VALUE= $expected_wsrep_received FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_received';
--source include/wait_condition.inc

# verify that certification dependency distance has dropped
--disable_query_log
--eval  SELECT  VARIABLE_VALUE < $cert_deps_distance as 'distance' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cert_deps_distance'
--enable_query_log

# if deps distance dropped, it is indirect evidence that parallel applying was not approved

# Let the first transaction to proceed
--let $galera_sync_point = commit_monitor_slave_enter_sync
--source include/galera_signal_sync_point.inc

# second applier should now hit sync point
--let $galera_sync_point = commit_monitor_slave_enter_sync
--source include/galera_wait_sync_point.inc
--source include/galera_signal_sync_point.inc
--source include/galera_clear_sync_point.inc

# Teardown
--connection node_1
SET GLOBAL wsrep_slave_threads = DEFAULT;

DROP TABLE t1;
DROP TABLE t2;
--connection node_2
SET GLOBAL wsrep_slave_threads = DEFAULT;