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
|