File: gr_xa_commit_failure_after_rotate.test

package info (click to toggle)
mysql-8.0 8.0.43-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,273,924 kB
  • sloc: cpp: 4,684,605; ansic: 412,450; pascal: 108,398; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; sh: 24,181; python: 21,816; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,076; makefile: 2,194; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (256 lines) | stat: -rw-r--r-- 9,137 bytes parent folder | download
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# ==== Purpose ====
#
# This script tests server behavior when a crash occurs during the
# execution of `XA COMMIT`, on a GR primary, after binary log has been
# rotated (`XA PREPARED` is no longer in the latest binary log file).
#
# ==== Requirements ====
#
# Pre-conditions:
# PC1. GR single-primary topology with 3 servers.
#
# After server restart:
# R1. The `XA PREPARE` statement shouldn't be found in the binlog.
# R2. The `XA COMMIT` statement shouldn't be found in the binlog.
# R3. There shouldn't be any changes to GTID_EXECUTED.
# R4. There should be one pending XA transactions visible with `XA
#     RECOVER`.
# R5. There should still be one pending XA transaction visible with `XA
#     RECOVER`, on crashed server, if server is restarted after the
#     crash-recovery.
#
# ==== Implementation ====
#
# 1. Setup scenario: setup GR, create table and insert some records.
# 2. Start and execute an XA transaction containing an insert until before
#    `XA COMMIT`.
# 3. Take the `GTID_EXECUTED` state.
# 4. Rotate and purge binary logs.
# 5. Crash the primary during `XA COMMIT` execution, before commiting in the
#    TC.
# 6. Restart server 1 (former primary) and check:
#    a. Error log for messages stating that recovery process found one
#       transaction needing recovery.
#    b. The `XA PREPARE` and `XA COMMIT` aren't found in the binary log.
#    c. The GTID_EXECUTED variable wasn't updated.
#    d. There is one pending XA transaction listed in the output of `XA
#       RECOVER`.
#    e. There aren't changes to the table.
# 7. On server 2, check:
#    a. The `XA PREPARE` is and the `XA COMMIT` isn't present in the binary
#       log
#    b. There is one pending XA transaction listed in the output of `XA
#       RECOVER`.
#    c. There aren't changes to the table.
# 8. Restart server 1 and check that the transaction is still in preared
#    state, meaning, the recovery process moved the transaction to
#    `PERSISTED_IN_TC` and that state was persisted.
# 9. Re-join server 1 (former primary) to the group.
# 10. On server 1, check state after distributed recovery:
#     a. The `XA PREPARE` is not found in the binary log.
#     b. There is one pending XA transaction listed in the output of `XA
#        RECOVER`.
# 11. Commit the transaction on primary.
# 12. Check table was updated on server 1.
#
# ==== References ====
#
# WL#11300: Crash-safe XA + binary log
#
# Related tests:
#   see extra/xa_crash_safe_tests/setup.inc
#
--source include/not_valgrind.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_group_replication_plugin.inc
--let $rpl_group_replication_single_primary_mode =1
--let $rpl_skip_group_replication_start = 1
--let $rpl_server_count = 3
--source include/group_replication.inc

# 1. Setup scenario: setup GR, create table and insert some records.
#
--let $rpl_connection_name = server1
--source include/rpl_connection.inc
--let $xid_data = xid1
--let $xid = `SELECT CONCAT("X'", LOWER(HEX('$xid_data')), "',X'',1")`
--source extra/xa_crash_safe_tests/setup.inc

# 2. Start and execute an XA transaction containing an insert until before
#    `XA COMMIT`.
#
--connect(con1, localhost, root,,)
--connection con1
--eval XA START $xid
INSERT INTO t1 VALUES (1);
--eval XA END $xid
--eval XA PREPARE $xid

# 3. Take the `GTID_EXECUTED` state.
#
--let $rpl_connection_name = server1
--source include/rpl_connection.inc
--source include/rpl_sync.inc
--let $before_gtid_executed = `SELECT @@GLOBAL.gtid_executed`

# 4. Rotate and purge binary logs.
#
FLUSH LOGS;
--replace_result $binlog_file BINLOG_FILE
--eval PURGE BINARY LOGS TO '$binlog_file'
--source include/save_binlog_position.inc

# 5. Crash the primary during `XA COMMIT` execution, before commiting in the
#    TC.
#
--let $auxiliary_connection = server1
--let $statement_connection = con1
--let $statement = XA COMMIT $xid
--let $sync_point = before_commit_xa_trx
--source include/execute_to_conditional_timestamp_sync_point.inc
--source include/kill_mysqld.inc
--source extra/xa_crash_safe_tests/cleanup_connection.inc

--let $rpl_connection_name = server2
--source include/rpl_connection.inc
--let $group_replication_number_of_members = 2
--source include/gr_wait_for_number_of_members.inc

# 6. Restart server 1 (former primary) and check:
#
--let $restart_parameters = restart:--group_replication_local_address=$_group_replication_local_address --group_replication_group_seeds=$_group_replication_group_seeds --group_replication_group_name=$_group_replication_group_name --group_replication_start_on_boot=OFF --group_replication_single_primary_mode=TRUE --group_replication_enforce_update_everywhere_checks=FALSE
--replace_result $_group_replication_local_address GROUP_REPLICATION_LOCAL_ADDRESS $_group_replication_group_seeds GROUP_REPLICATION_GROUP_SEEDS $_group_replication_group_name GROUP_REPLICATION_GROUP_NAME
--source include/start_mysqld.inc
--let $rpl_server_number = 1
--source include/rpl_reconnect.inc

--let $rpl_connection_name = server1
--source include/rpl_connection.inc

# 6.a. Error log for messages stating that recovery process found one
#       transaction needing recovery.
#
--let $assert_select = Successfully prepared 1 XA transaction
--source extra/xa_crash_safe_tests/assert_recovery_message.inc

# 6.b. The `XA PREPARE` and `XA COMMIT` aren't found in the binary log.
#
--let $event_sequence = $empty_event_sequence
--source include/assert_binlog_events.inc

# 6.c. The GTID_EXECUTED variable wasn't updated.
#
--let $after_gtid_executed = `SELECT @@GLOBAL.gtid_executed`
--let $assert_text = GTID_EXECUTED has not been updated
--let $assert_cond = "$before_gtid_executed" = "$after_gtid_executed"
--source include/assert.inc

# 6.d. There is one pending XA transaction listed in the output of `XA
#       RECOVER`.
#
--let $expected_prepared_xa_count = 1
--source extra/xa_crash_safe_tests/assert_xa_recover.inc

# 6.e. There aren't changes to the table.
#
--let $expected_row_count = 1
--source extra/xa_crash_safe_tests/assert_row_count.inc

# 7. On server 2, check:
#
--let $rpl_connection_name = server2
--source include/rpl_connection.inc

# 7.a. The `XA PREPARE` is and the `XA COMMIT` isn't present in the binary
#      log.
#
--let $binlog_file = `SELECT @binlog_file`
--let $binlog_position = `SELECT @binlog_position`
--let $event_sequence = $view_change # Gtid # $xa_start_end # XA_prepare/XA PREPARE $xid
--source include/assert_binlog_events.inc

# 7.b. There is one pending XA transaction listed in the output of `XA
#       RECOVER`.
#
--let $expected_prepared_xa_count = 1
--source extra/xa_crash_safe_tests/assert_xa_recover.inc

# 7.c. There aren't changes to the table.
#
--let $expected_row_count = 1
--source extra/xa_crash_safe_tests/assert_row_count.inc

# 8. Restart server 1 and check that the transaction is still in preared
#    state, meaning, the recovery process moved the transaction to
#    `PERSISTED_IN_TC` and that state was persisted.
#
--let $rpl_connection_name = server1
--source include/rpl_connection.inc

--let $allow_rpl_inited = 1
--replace_result $_group_replication_local_address GROUP_REPLICATION_LOCAL_ADDRESS $_group_replication_group_seeds GROUP_REPLICATION_GROUP_SEEDS $_group_replication_group_name GROUP_REPLICATION_GROUP_NAME
--source include/restart_mysqld.inc
--let $rpl_server_number = 1
--source include/rpl_reconnect.inc

--let $expected_prepared_xa_count = 1
--source extra/xa_crash_safe_tests/assert_xa_recover.inc

# 9. Re-join server 1 (former primary) to the group.
#
--let $rpl_connection_name = server1
--source include/rpl_connection.inc
--source include/save_binlog_position.inc
--let $group_replication_group_name = $_group_replication_group_name
--source include/start_group_replication.inc

--let $rpl_connection_name = server2
--source include/rpl_connection.inc
--let $group_replication_number_of_members = 3
--source include/gr_wait_for_number_of_members.inc

# 10. On server 1, check state after distributed recovery:
#
--let $rpl_connection_name = server1
--source include/rpl_connection.inc

# 10.a. The `XA PREPARE` is not found in the binary log.
#
--let $event_sequence = $view_change
--source include/assert_binlog_events.inc

# 10.b. There is one pending XA transaction listed in the output of `XA
#       RECOVER`.
#
--let $expected_prepared_xa_count = 1
--source extra/xa_crash_safe_tests/assert_xa_recover.inc

# 11. Commit the transaction on primary.
#
--source include/gr_find_a_primary.inc
--connection $group_replication_primary_connection_out_var
--eval XA COMMIT $xid

--source include/rpl_sync.inc

--let $rpl_connection_name = server1
--source include/rpl_connection.inc

# 12. Check table was updated on server 1.
#
--let $expected_row_count = 2
--source extra/xa_crash_safe_tests/assert_row_count.inc

--connection $group_replication_primary_connection_out_var

DROP TABLE t1;

--let $rpl_connection_name = server2
--source include/rpl_connection.inc
--source include/restore_sysvars.inc
--let $rpl_connection_name = server3
--source include/rpl_connection.inc
--source include/restore_sysvars.inc

--source include/group_replication_end.inc