Skip to content

Commit 1fb00f3

Browse files
committed
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: Kristian Nielsen <knielsen@knielsen-hq.org>
1 parent 55cea0c commit 1fb00f3

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

mysql-test/suite/rpl/r/rpl_parallel_retry.result

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,28 @@ connection server_1;
339339
DROP TABLE t1, t2, t3, t4;
340340
DROP function foo;
341341
connection server_2;
342+
connection server_2;
343+
include/stop_slave.inc
344+
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
345+
SET GLOBAL slave_parallel_threads=4;
346+
connection server_1;
347+
CREATE TABLE t1 (a INT, b VARCHAR(123)) ENGINE=InnoDB;
348+
INSERT INTO t1 VALUES(1, 'asdf');
349+
UPDATE t1 SET b='zxf1' WHERE a=1;
350+
UPDATE t1 SET b='\n' WHERE a=1;
351+
connection server_2;
352+
SET @old_dbug=@@GLOBAL.debug_dbug;
353+
SET GLOBAL debug_dbug="+d,write_row_inject_sleep_before_ha_write_row";
354+
include/start_slave.inc
355+
connection server_1;
356+
connection server_2;
357+
connection server_1;
358+
DROP TABLE t1;
359+
connection server_2;
360+
include/stop_slave.inc
361+
SET GLOBAL debug_dbug=@old_dbug;
362+
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
363+
include/start_slave.inc
342364
connection server_1;
343365
CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB;
344366
INSERT INTO t1 VALUES(100, 100);

mysql-test/suite/rpl/t/rpl_parallel_retry.test

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,44 @@ DROP function foo;
410410

411411
--sync_slave_with_master server_2
412412

413+
#
414+
# MDEV-33303: slave_parallel_mode=optimistic should not report the mode's
415+
# specific temporary errors.
416+
#
417+
418+
--connection server_2
419+
--source include/stop_slave.inc
420+
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
421+
SET GLOBAL slave_parallel_threads=4;
422+
423+
--connection server_1
424+
# The problem occurred in the code path for row-based updates in tables
425+
# with no primary/unique key, where a scan is needed.
426+
CREATE TABLE t1 (a INT, b VARCHAR(123)) ENGINE=InnoDB;
427+
INSERT INTO t1 VALUES(1, 'asdf');
428+
UPDATE t1 SET b='zxf1' WHERE a=1;
429+
UPDATE t1 SET b='\n' WHERE a=1;
430+
431+
--connection server_2
432+
# Inject a small sleep in the code that makes the race easier to hit.
433+
SET @old_dbug=@@GLOBAL.debug_dbug;
434+
SET GLOBAL debug_dbug="+d,write_row_inject_sleep_before_ha_write_row";
435+
--source include/start_slave.inc
436+
437+
--connection server_1
438+
# Here, we would get errors in the slave's error log:
439+
# [ERROR] mariadbd: Can't find record in 't1'
440+
--sync_slave_with_master server_2
441+
442+
--connection server_1
443+
DROP TABLE t1;
444+
--sync_slave_with_master server_2
445+
--source include/stop_slave.inc
446+
SET GLOBAL debug_dbug=@old_dbug;
447+
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
448+
--source include/start_slave.inc
449+
450+
413451
#
414452
# MDEV-12746 rpl.rpl_parallel_optimistic_nobinlog fails committing out of order at retry
415453
#

sql/log_event_server.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7401,6 +7401,8 @@ Rows_log_event::write_row(rpl_group_info *rgi,
74017401
TODO: Add safety measures against infinite looping.
74027402
*/
74037403

7404+
DBUG_EXECUTE_IF("write_row_inject_sleep_before_ha_write_row",
7405+
my_sleep(20000););
74047406
if (table->s->sequence)
74057407
error= update_sequence();
74067408
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)
78987900
? HA_ERR_KEY_NOT_FOUND : HA_ERR_RECORD_CHANGED;
78997901
}
79007902

7903+
static int end_of_file_error(rpl_group_info *rgi)
7904+
{
7905+
return rgi->speculation != rpl_group_info::SPECULATE_OPTIMISTIC
7906+
? HA_ERR_END_OF_FILE : HA_ERR_RECORD_CHANGED;
7907+
}
7908+
79017909
/**
79027910
Locate the current row in event's table.
79037911
@@ -8145,6 +8153,8 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
81458153
while ((error= table->file->ha_index_next(table->record[0])))
81468154
{
81478155
DBUG_PRINT("info",("no record matching the given row found"));
8156+
if (error == HA_ERR_END_OF_FILE)
8157+
error= end_of_file_error(rgi);
81488158
table->file->print_error(error, MYF(0));
81498159
table->file->ha_index_end();
81508160
goto end;
@@ -8181,6 +8191,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
81818191
break;
81828192

81838193
case HA_ERR_END_OF_FILE:
8194+
error= end_of_file_error(rgi);
81848195
DBUG_PRINT("info", ("Record not found"));
81858196
table->file->ha_rnd_end();
81868197
goto end;

0 commit comments

Comments
 (0)