mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
eb75edfb2b
This makes it clear that the error code has nothing to do with errno. mysql-test/include/mtr_warnings.sql: Fixed suppression for new slave error messages mysql-test/lib/My/Test.pm: Use 'send' instead of 'print' to avoid errors about "wrong class ... back attempt" mysql-test/lib/v1/mtr_report.pl: Fixed suppression for new slave error messages mysql-test/mysql-test-run.pl: Fixed suppression for new slave error messages Removed warning from perl 5.16.2 about arrays mysql-test/r/flush_read_lock.result: Fixed suppression for new slave error messages sql/rpl_reporting.cc: Instead of writing "Errcode" to the log for Slave errors, use "Internal MariaDB error code"
180 lines
5.6 KiB
Text
180 lines
5.6 KiB
Text
# ==== Purpose ====
|
|
#
|
|
# Test that slave behaves well in some conflict situations. The
|
|
# following are tested:
|
|
#
|
|
# - The slave SQL thread sees an 'INSERT' of a row with a key that
|
|
# already exists in the table;
|
|
#
|
|
# - The slave SQL thread sees a 'DELETE' of a row that does not
|
|
# exist in the table.
|
|
#
|
|
# In statement-logging mode, the first conflict type causes the slave
|
|
# to stop with an error and the second conflict is ignored.
|
|
#
|
|
# In row-logging mode, the slave behavior depends the value of
|
|
# @@slave_exec_mode on the slave: if @@slave_exec_mode is IDEMPOTENT,
|
|
# the slave should ignore the conflicting statement and continue
|
|
# normally. If @@slave_exec_mode is STRICT, the slave should stop
|
|
# with an error.
|
|
#
|
|
# This test was previously named rpl_stm_mystery22/rpl_row_mystery22.
|
|
#
|
|
#
|
|
# ==== Method ====
|
|
#
|
|
# Create a table on master and slave, insert a row on slave, and
|
|
# insert the same row on master.
|
|
#
|
|
# Create a table on master and slave, insert a row on master with
|
|
# binlogging turned off, and remove the row on master with binlogging
|
|
# turned on.
|
|
#
|
|
#
|
|
# ==== Related bugs ====
|
|
#
|
|
# BUG#31552: Replication breaks when deleting rows from out-of-sync table without PK
|
|
# BUG#31609: Not all RBR slave errors reported as errors
|
|
#
|
|
# Bug in this test case:
|
|
# BUG#37718: rpl.rpl_stm_mystery22 fails sporadically on pushbuild
|
|
#
|
|
#
|
|
# ==== Usage ====
|
|
#
|
|
# This file assumes the following:
|
|
#
|
|
# - The test language variable $slave_is_idempotent is set to 1 if the
|
|
# slave is expected to stop on duplicate key errors (i.e., if the
|
|
# binlog is in statement mode or
|
|
# @@global.slave_exec_mode=STRICT). It is set to 0 otherwise.
|
|
#
|
|
# - Replication has been initialized by include/master-slave.inc
|
|
#
|
|
# - The test adds a suppression for the following warning:
|
|
# Slave: Can't find record in 't1' error.* 1032
|
|
|
|
|
|
--echo ==== Initialize ====
|
|
|
|
--echo [on master]
|
|
connection master;
|
|
CREATE TABLE t1(a INT PRIMARY KEY);
|
|
--echo [on slave]
|
|
sync_slave_with_master;
|
|
|
|
|
|
--echo ==== Test: SQL thread sees 'INSERT' of existing key ====
|
|
|
|
--echo ---- Prepare slave so that it will get duplicate key error ----
|
|
# This row will be in the way of the row inserted by master.
|
|
INSERT INTO t1 VALUES (1);
|
|
|
|
--echo ---- Insert rows on master ----
|
|
--echo [on master]
|
|
connection master;
|
|
# Insert the same row on master
|
|
INSERT INTO t1 VALUES (1);
|
|
save_master_pos;
|
|
SELECT * FROM t1;
|
|
|
|
--echo [on slave]
|
|
connection slave;
|
|
|
|
# If we are statement-logging or if slave_exec_mode=STRICT, we now
|
|
# expect to see an error on the slave. Otherwise (i.e., we are
|
|
# row-logging and slave_exec_mode=IDEMPOTENT), we expect that the
|
|
# duplicate row is ignored by the slave and replication continues.
|
|
if (`SELECT @@global.binlog_format != 'ROW' OR @@global.slave_exec_mode = 'STRICT'`) {
|
|
--echo ---- Wait until slave stops with an error ----
|
|
# Wait until the slave tries to run the query, fails with duplicate
|
|
# key error, and stops the SQL thread.
|
|
let $slave_sql_errno= 1062; # ER_DUP_ENTRY
|
|
source include/wait_for_slave_sql_error.inc;
|
|
|
|
--let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1)
|
|
--replace_regex /end_log_pos [0-9]+/end_log_pos END_LOG_POS/
|
|
--disable_query_log
|
|
--eval SELECT "$err" as 'Last_SQL_Error (expected "duplicate key" error)'
|
|
--enable_query_log
|
|
call mtr.add_suppression("Slave SQL.*Duplicate entry .1. for key .PRIMARY.* error.* 1062");
|
|
|
|
SELECT * FROM t1;
|
|
|
|
--echo ---- Resolve the conflict on the slave and restart SQL thread ----
|
|
DELETE FROM t1 WHERE a = 1;
|
|
START SLAVE SQL_THREAD;
|
|
source include/wait_for_slave_sql_to_start.inc;
|
|
}
|
|
|
|
--echo ---- Sync slave and verify that there is no error ----
|
|
sync_with_master;
|
|
let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
|
|
--echo Last_SQL_Error = '$err' (expected no error)
|
|
SELECT * FROM t1;
|
|
|
|
|
|
--echo ==== Test: SQL thread sees 'DELETE' of non-existing row ====
|
|
|
|
--echo ---- On master, insert two rows, the second with binlogging off ----
|
|
--echo [on master]
|
|
connection master;
|
|
DELETE FROM t1;
|
|
INSERT INTO t1 VALUES (1);
|
|
|
|
--echo [on slave]
|
|
sync_slave_with_master;
|
|
DELETE FROM t1 WHERE a = 1;
|
|
|
|
--echo ---- On master, remove the row that does not exist on slave ----
|
|
--echo [on master]
|
|
connection master;
|
|
DELETE FROM t1 WHERE a = 1;
|
|
SELECT * FROM t1;
|
|
save_master_pos;
|
|
|
|
--echo [on slave]
|
|
connection slave;
|
|
|
|
# If we are row-logging and slave_exec_mode is STRICT, we now expect
|
|
# an error since the row to delete does not exist on slave. Otherwise
|
|
# (i.e., either we are statement-logging or slave_exec_mode is
|
|
# IDEMPOTENT), the absence of the row to delete is ignored and
|
|
# replication continues.
|
|
if (`SELECT @@global.binlog_format = 'ROW' AND @@global.slave_exec_mode = 'STRICT'`) {
|
|
--echo ---- Wait until slave stops with an error ----
|
|
call mtr.add_suppression("Slave SQL.*Can.t find record in .t1., error.* 1032");
|
|
let $slave_sql_errno= 1032; # ER_KEY_NOT_FOUND
|
|
source include/wait_for_slave_sql_error.inc;
|
|
|
|
--let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1)
|
|
--replace_regex /end_log_pos [0-9]+/end_log_pos END_LOG_POS/
|
|
--disable_query_log
|
|
--eval SELECT "$err" as 'Last_SQL_Error (expected "duplicate key" error)'
|
|
--enable_query_log
|
|
|
|
SELECT * FROM t1;
|
|
|
|
--echo ---- Resolve the conflict on the slave and restart SQL thread ----
|
|
INSERT INTO t1 VALUES (1);
|
|
START SLAVE SQL_THREAD;
|
|
source include/wait_for_slave_sql_to_start.inc;
|
|
}
|
|
|
|
--echo ---- Sync slave and verify that there is no error ----
|
|
# The slave should sync ok, and SHOW SLAVE STATUS should give no
|
|
# error.
|
|
sync_with_master;
|
|
let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
|
|
--echo Last_SQL_Error = $err (expected no error)
|
|
SELECT * FROM t1;
|
|
|
|
|
|
--echo ==== Clean up ====
|
|
|
|
--echo [on master]
|
|
connection master;
|
|
DROP TABLE t1;
|
|
|
|
--echo [on slave]
|
|
--sync_slave_with_master
|