1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bug#31702 (Missing row on slave causes assertion failure under row-based replication):

When replicating an update pair (before image, after image) under row-based
replication, and the before image is not found on the slave, the after image
was not discared, and was hence read as a before image for the next row.
Eventually, this lead to an after image being read outside the block of rows
in the event, causing an assertion to fire.

This patch fixes this by reading the after image in the event that the row
was not found on the slave, adds some extra debug assertion to catch future
errors earlier, and also adds a few non-debug checks to prevent reading
outside the block of the event.


include/my_base.h:
  Adding error code HA_ERR_CORRUPT_EVENT.
mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result:
  Result change.
mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test:
  Adding test to try to use row-based replication to replicate an
  update of a row that doesn't exist on the slave. We should get
  an apropriate error and the slave should stop.
sql/log_event.cc:
  Adding debug printouts. Adding code to Update_rows_log_event::do_exec_row()
  so that the after image is read (and ignored) in the event of an error in
  finding the row. This is necessary so that the second pair of images is
  read correctly for the next update pair.
  
  Changing logic for ignoring errors to not include update events, since
  a "key not found" error or a "record changed" error is not idempotent
  for updates, just for deletes and inserts.
sql/log_event.h:
  Adding debug assertions to check that row reading is within the events block of rows.
This commit is contained in:
unknown
2007-10-20 18:19:55 +02:00
parent 3f284594be
commit 0b1c0f3173
5 changed files with 117 additions and 10 deletions

View File

@ -223,3 +223,40 @@ connection master;
drop table t1,t2;
sync_slave_with_master;
#
# BUG#31702: Missing row on slave causes assertion failure under
# row-based replication
#
disable_query_log;
source include/master-slave-reset.inc;
enable_query_log;
--echo **** On Master ****
connection master;
SET SESSION BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT PRIMARY KEY, b SET('master','slave'));
INSERT INTO t1 VALUES (1,'master,slave'), (2,'master,slave');
--echo **** On Slave ****
sync_slave_with_master;
UPDATE t1 SET a = 5, b = 'slave' WHERE a = 1;
SELECT * FROM t1 ORDER BY a;
--echo **** On Master ****
connection master;
UPDATE t1 SET a = 5, b = 'master' WHERE a = 1;
save_master_pos;
SELECT * FROM t1 ORDER BY a;
--echo **** On Slave ****
connection slave;
source include/wait_for_slave_sql_error.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
--echo **** On Master ****
connection master;
DROP TABLE t1;