Commit 1fb00f37 authored by Kristian Nielsen's avatar Kristian Nielsen

MDEV-33303: slave_parallel_mode=optimistic should not report the mode's specific temporary errors

An earlier patch for MDEV-13577 fixed the most common instances of this, but
missed one case for tables without primary key when the scan reaches the end
of the table. This patch adds similar code to handle this case, converting
the error to HA_ERR_RECORD_CHANGED when doing optimistic parallel apply.
Signed-off-by: default avatarKristian Nielsen <knielsen@knielsen-hq.org>
parent 55cea0c2
...@@ -339,6 +339,28 @@ connection server_1; ...@@ -339,6 +339,28 @@ connection server_1;
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
DROP function foo; DROP function foo;
connection server_2; connection server_2;
connection server_2;
include/stop_slave.inc
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
SET GLOBAL slave_parallel_threads=4;
connection server_1;
CREATE TABLE t1 (a INT, b VARCHAR(123)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, 'asdf');
UPDATE t1 SET b='zxf1' WHERE a=1;
UPDATE t1 SET b='\n' WHERE a=1;
connection server_2;
SET @old_dbug=@@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug="+d,write_row_inject_sleep_before_ha_write_row";
include/start_slave.inc
connection server_1;
connection server_2;
connection server_1;
DROP TABLE t1;
connection server_2;
include/stop_slave.inc
SET GLOBAL debug_dbug=@old_dbug;
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
include/start_slave.inc
connection server_1; connection server_1;
CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES(100, 100); INSERT INTO t1 VALUES(100, 100);
......
...@@ -410,6 +410,44 @@ DROP function foo; ...@@ -410,6 +410,44 @@ DROP function foo;
--sync_slave_with_master server_2 --sync_slave_with_master server_2
#
# MDEV-33303: slave_parallel_mode=optimistic should not report the mode's
# specific temporary errors.
#
--connection server_2
--source include/stop_slave.inc
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
SET GLOBAL slave_parallel_threads=4;
--connection server_1
# The problem occurred in the code path for row-based updates in tables
# with no primary/unique key, where a scan is needed.
CREATE TABLE t1 (a INT, b VARCHAR(123)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, 'asdf');
UPDATE t1 SET b='zxf1' WHERE a=1;
UPDATE t1 SET b='\n' WHERE a=1;
--connection server_2
# Inject a small sleep in the code that makes the race easier to hit.
SET @old_dbug=@@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug="+d,write_row_inject_sleep_before_ha_write_row";
--source include/start_slave.inc
--connection server_1
# Here, we would get errors in the slave's error log:
# [ERROR] mariadbd: Can't find record in 't1'
--sync_slave_with_master server_2
--connection server_1
DROP TABLE t1;
--sync_slave_with_master server_2
--source include/stop_slave.inc
SET GLOBAL debug_dbug=@old_dbug;
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
--source include/start_slave.inc
# #
# MDEV-12746 rpl.rpl_parallel_optimistic_nobinlog fails committing out of order at retry # MDEV-12746 rpl.rpl_parallel_optimistic_nobinlog fails committing out of order at retry
# #
......
...@@ -7401,6 +7401,8 @@ Rows_log_event::write_row(rpl_group_info *rgi, ...@@ -7401,6 +7401,8 @@ Rows_log_event::write_row(rpl_group_info *rgi,
TODO: Add safety measures against infinite looping. TODO: Add safety measures against infinite looping.
*/ */
DBUG_EXECUTE_IF("write_row_inject_sleep_before_ha_write_row",
my_sleep(20000););
if (table->s->sequence) if (table->s->sequence)
error= update_sequence(); error= update_sequence();
else while (unlikely(error= table->file->ha_write_row(table->record[0]))) else while (unlikely(error= table->file->ha_write_row(table->record[0])))
...@@ -7898,6 +7900,12 @@ static int row_not_found_error(rpl_group_info *rgi) ...@@ -7898,6 +7900,12 @@ static int row_not_found_error(rpl_group_info *rgi)
? HA_ERR_KEY_NOT_FOUND : HA_ERR_RECORD_CHANGED; ? HA_ERR_KEY_NOT_FOUND : HA_ERR_RECORD_CHANGED;
} }
static int end_of_file_error(rpl_group_info *rgi)
{
return rgi->speculation != rpl_group_info::SPECULATE_OPTIMISTIC
? HA_ERR_END_OF_FILE : HA_ERR_RECORD_CHANGED;
}
/** /**
Locate the current row in event's table. Locate the current row in event's table.
...@@ -8145,6 +8153,8 @@ int Rows_log_event::find_row(rpl_group_info *rgi) ...@@ -8145,6 +8153,8 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
while ((error= table->file->ha_index_next(table->record[0]))) while ((error= table->file->ha_index_next(table->record[0])))
{ {
DBUG_PRINT("info",("no record matching the given row found")); DBUG_PRINT("info",("no record matching the given row found"));
if (error == HA_ERR_END_OF_FILE)
error= end_of_file_error(rgi);
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
table->file->ha_index_end(); table->file->ha_index_end();
goto end; goto end;
...@@ -8181,6 +8191,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi) ...@@ -8181,6 +8191,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
break; break;
case HA_ERR_END_OF_FILE: case HA_ERR_END_OF_FILE:
error= end_of_file_error(rgi);
DBUG_PRINT("info", ("Record not found")); DBUG_PRINT("info", ("Record not found"));
table->file->ha_rnd_end(); table->file->ha_rnd_end();
goto end; goto end;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment