3
# Test that slave behaves well in some conflict situations. The
4
# following are tested:
6
# - The slave SQL thread sees an 'INSERT' of a row with a key that
7
# already exists in the table;
9
# - The slave SQL thread sees a 'DELETE' of a row that does not
12
# In statement-logging mode, the first conflict type causes the slave
13
# to stop with an error and the second conflict is ignored.
15
# In row-logging mode, the slave behavior depends the value of
16
# @@slave_exec_mode on the slave: if @@slave_exec_mode is IDEMPOTENT,
17
# the slave should ignore the conflicting statement and continue
18
# normally. If @@slave_exec_mode is STRICT, the slave should stop
21
# This test was previously named rpl_stm_mystery22/rpl_row_mystery22.
26
# Create a table on master and slave, insert a row on slave, and
27
# insert the same row on master.
29
# Create a table on master and slave, insert a row on master with
30
# binlogging turned off, and remove the row on master with binlogging
34
# ==== Related bugs ====
36
# BUG#31552: Replication breaks when deleting rows from out-of-sync table without PK
37
# BUG#31609: Not all RBR slave errors reported as errors
39
# Bug in this test case:
40
# BUG#37718: rpl.rpl_stm_mystery22 fails sporadically on pushbuild
45
# This file assumes the following:
47
# - The test language variable $slave_is_idempotent is set to 1 if the
48
# slave is expected to stop on duplicate key errors (i.e., if the
49
# binlog is in statement mode or
50
# @@global.slave_exec_mode=STRICT). It is set to 0 otherwise.
52
# - Replication has been initialized by include/master-slave.inc
54
# - The test adds a suppression for the following warning:
55
# Slave: Can't find record in 't1' Error_code: 1032
58
--echo ==== Initialize ====
62
CREATE TABLE t1(a INT PRIMARY KEY);
64
sync_slave_with_master;
67
--echo ==== Test: SQL thread sees 'INSERT' of existing key ====
69
--echo ---- Prepare slave so that it will get duplicate key error ----
70
# This row will be in the way of the row inserted by master.
71
INSERT INTO t1 VALUES (1);
73
--echo ---- Insert rows on master ----
76
# Insert the same row on master
77
INSERT INTO t1 VALUES (1);
84
# If we are statement-logging or if slave_exec_mode=STRICT, we now
85
# expect to see an error on the slave. Otherwise (i.e., we are
86
# row-logging and slave_exec_mode=IDEMPOTENT), we expect that the
87
# duplicate row is ignored by the slave and replication continues.
88
if (`SELECT @@global.binlog_format != 'ROW' OR @@global.slave_exec_mode = 'STRICT'`) {
89
--echo ---- Wait until slave stops with an error ----
90
# Wait until the slave tries to run the query, fails with duplicate
91
# key error, and stops the SQL thread.
92
let $slave_sql_errno= 1062; # ER_DUP_ENTRY
93
source include/wait_for_slave_sql_error.inc;
94
let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
95
--echo Last_SQL_Error = $err (expected "duplicate key" error)
98
--echo ---- Resolve the conflict on the slave and restart SQL thread ----
99
DELETE FROM t1 WHERE a = 1;
100
START SLAVE SQL_THREAD;
101
source include/wait_for_slave_sql_to_start.inc;
104
--echo ---- Sync slave and verify that there is no error ----
106
let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
107
--echo Last_SQL_Error = '$err' (expected no error)
111
--echo ==== Test: SQL thread sees 'DELETE' of non-existing row ====
113
--echo ---- On master, insert two rows, the second with binlogging off ----
117
INSERT INTO t1 VALUES (1);
120
sync_slave_with_master;
121
DELETE FROM t1 WHERE a = 1;
123
--echo ---- On master, remove the row that does not exist on slave ----
126
DELETE FROM t1 WHERE a = 1;
133
# If we are row-logging and slave_exec_mode is STRICT, we now expect
134
# an error since the row to delete does not exist on slave. Otherwise
135
# (i.e., either we are statement-logging or slave_exec_mode is
136
# IDEMPOTENT), the absence of the row to delete is ignored and
137
# replication continues.
138
if (`SELECT @@global.binlog_format = 'ROW' AND @@global.slave_exec_mode = 'STRICT'`) {
139
--echo ---- Wait until slave stops with an error ----
140
let $slave_sql_errno= 1032; # ER_KEY_NOT_FOUND
141
source include/wait_for_slave_sql_error.inc;
142
let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
143
--echo Last_SQL_Error = $err (expected "can't find record" error)
146
--echo ---- Resolve the conflict on the slave and restart SQL thread ----
147
INSERT INTO t1 VALUES (1);
148
START SLAVE SQL_THREAD;
149
source include/wait_for_slave_sql_to_start.inc;
152
--echo ---- Sync slave and verify that there is no error ----
153
# The slave should sync ok, and SHOW SLAVE STATUS should give no
156
let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
157
--echo Last_SQL_Error = $err (expected no error)
161
--echo ==== Clean up ====
168
sync_slave_with_master;