Commit 2019f172 authored by Mats Kindahl's avatar Mats Kindahl

Bug #40004 Replication failure with no PK + no indexes

In certain situations, a scan of the table will return the error
code HA_ERR_RECORD_DELETED, and this error code is not 
correctly caught in the Rows_log_event::find_row() function, which
causes an error to be returned for this case.

This patch fixes the problem by adding code to either ignore the
record and continuing with the next one, the the event of a table
scan, or change the error code to HA_ERR_KEY_NOT_FOUND, in the event
that a key lookup is attempted.
parent 0c20c0f1
...@@ -471,3 +471,94 @@ source include/diff_tables.inc; ...@@ -471,3 +471,94 @@ source include/diff_tables.inc;
connection master; connection master;
drop table t1; drop table t1;
sync_slave_with_master; sync_slave_with_master;
#
# BUG#40004: Replication failure with no PK + no indexes
#
connection master;
eval CREATE TABLE t1 (a int) ENGINE=$type;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
connection master;
drop table t1;
sync_slave_with_master;
#
# Bug #39752: Replication failure on RBR + MyISAM + no PK
#
connection master;
--disable_warnings
eval CREATE TABLE t1 (a bit) ENGINE=$type;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
--enable_warnings
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
connection master;
drop table t1;
sync_slave_with_master;
...@@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY' ...@@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
INSERT INTO t1 VALUES (4); INSERT INTO t1 VALUES (4);
Comparing tables master:test.t1 and slave:test.t1 Comparing tables master:test.t1 and slave:test.t1
drop table t1; drop table t1;
CREATE TABLE t1 (a int) ENGINE='MYISAM' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a bit) ENGINE='MYISAM' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
...@@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY' ...@@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
INSERT INTO t1 VALUES (4); INSERT INTO t1 VALUES (4);
Comparing tables master:test.t1 and slave:test.t1 Comparing tables master:test.t1 and slave:test.t1
drop table t1; drop table t1;
CREATE TABLE t1 (a int) ENGINE='INNODB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a bit) ENGINE='INNODB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
...@@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY' ...@@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
INSERT INTO t1 VALUES (4); INSERT INTO t1 VALUES (4);
Comparing tables master:test.t1 and slave:test.t1 Comparing tables master:test.t1 and slave:test.t1
drop table t1; drop table t1;
CREATE TABLE t1 (a int) ENGINE='NDB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a bit) ENGINE='NDB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
...@@ -7203,6 +7203,9 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -7203,6 +7203,9 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
error= do_exec_row(rli); error= do_exec_row(rli);
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
table->in_use = old_thd; table->in_use = old_thd;
switch (error) switch (error)
{ {
...@@ -7218,11 +7221,13 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -7218,11 +7221,13 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
case HA_ERR_TABLE_DEF_CHANGED: case HA_ERR_TABLE_DEF_CHANGED:
case HA_ERR_CANNOT_ADD_FOREIGN: case HA_ERR_CANNOT_ADD_FOREIGN:
which are not included into to the list. which are not included into to the list.
Note that HA_ERR_RECORD_DELETED is not in the list since
do_exec_row() should not return that error code.
*/ */
case HA_ERR_RECORD_CHANGED: case HA_ERR_RECORD_CHANGED:
case HA_ERR_RECORD_DELETED:
case HA_ERR_KEY_NOT_FOUND: case HA_ERR_KEY_NOT_FOUND:
case HA_ERR_END_OF_FILE: case HA_ERR_END_OF_FILE:
case HA_ERR_FOUND_DUPP_KEY: case HA_ERR_FOUND_DUPP_KEY:
...@@ -7231,7 +7236,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -7231,7 +7236,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
case HA_ERR_NO_REFERENCED_ROW: case HA_ERR_NO_REFERENCED_ROW:
case HA_ERR_ROW_IS_REFERENCED: case HA_ERR_ROW_IS_REFERENCED:
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
{ {
if (global_system_variables.log_warnings) if (global_system_variables.log_warnings)
...@@ -7254,7 +7258,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -7254,7 +7258,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
m_curr_row_end. m_curr_row_end.
*/ */
DBUG_PRINT("info", ("error: %d", error));
DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu", DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
(ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end)); (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
...@@ -8269,6 +8272,8 @@ Rows_log_event::write_row(const Relay_log_info *const rli, ...@@ -8269,6 +8272,8 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
if (error) if (error)
{ {
DBUG_PRINT("info",("rnd_pos() returns error %d",error)); DBUG_PRINT("info",("rnd_pos() returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -8301,7 +8306,9 @@ Rows_log_event::write_row(const Relay_log_info *const rli, ...@@ -8301,7 +8306,9 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
HA_READ_KEY_EXACT); HA_READ_KEY_EXACT);
if (error) if (error)
{ {
DBUG_PRINT("info",("index_read_idx() returns error %d",error)); DBUG_PRINT("info",("index_read_idx() returns %s", HA_ERR(error)));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -8574,6 +8581,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli) ...@@ -8574,6 +8581,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
if (error) if (error)
{ {
DBUG_PRINT("info",("rnd_pos returns error %d",error)); DBUG_PRINT("info",("rnd_pos returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
} }
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -8633,6 +8642,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli) ...@@ -8633,6 +8642,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
HA_READ_KEY_EXACT))) HA_READ_KEY_EXACT)))
{ {
DBUG_PRINT("info",("no record matching the key found in the table")); DBUG_PRINT("info",("no record matching the key found in the table"));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
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 err; goto err;
...@@ -8690,8 +8701,11 @@ int Rows_log_event::find_row(const Relay_log_info *rli) ...@@ -8690,8 +8701,11 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
256U - (1U << table->s->last_null_bit_pos); 256U - (1U << table->s->last_null_bit_pos);
} }
if ((error= table->file->index_next(table->record[0]))) while ((error= table->file->index_next(table->record[0])))
{ {
/* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
continue;
DBUG_PRINT("info",("no record matching the given row found")); DBUG_PRINT("info",("no record matching the given row found"));
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
table->file->ha_index_end(); table->file->ha_index_end();
...@@ -8722,14 +8736,22 @@ int Rows_log_event::find_row(const Relay_log_info *rli) ...@@ -8722,14 +8736,22 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
/* Continue until we find the right record or have made a full loop */ /* Continue until we find the right record or have made a full loop */
do do
{ {
restart_rnd_next:
error= table->file->rnd_next(table->record[0]); error= table->file->rnd_next(table->record[0]);
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
switch (error) { switch (error) {
case 0: case 0:
case HA_ERR_RECORD_DELETED:
break; break;
/*
If the record was deleted, we pick the next one without doing
any comparisons.
*/
case HA_ERR_RECORD_DELETED:
goto restart_rnd_next;
case HA_ERR_END_OF_FILE: case HA_ERR_END_OF_FILE:
if (++restart_count < 2) if (++restart_count < 2)
table->file->ha_rnd_init(1); table->file->ha_rnd_init(1);
...@@ -8759,7 +8781,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli) ...@@ -8759,7 +8781,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
DBUG_DUMP("record found", table->record[0], table->s->reclength); DBUG_DUMP("record found", table->record[0], table->s->reclength);
table->file->ha_rnd_end(); table->file->ha_rnd_end();
DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0); DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0);
goto err; goto err;
} }
ok: ok:
......
...@@ -556,6 +556,9 @@ replace_record(THD *thd, TABLE *table, ...@@ -556,6 +556,9 @@ replace_record(THD *thd, TABLE *table,
error= table->file->rnd_pos(table->record[1], table->file->dup_ref); error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
if (error) if (error)
{ {
DBUG_PRINT("info",("rnd_pos() returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -582,6 +585,9 @@ replace_record(THD *thd, TABLE *table, ...@@ -582,6 +585,9 @@ replace_record(THD *thd, TABLE *table,
HA_READ_KEY_EXACT); HA_READ_KEY_EXACT);
if (error) if (error)
{ {
DBUG_PRINT("info", ("index_read_idx() returns error %d", error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -787,11 +793,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key) ...@@ -787,11 +793,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
256U - (1U << table->s->last_null_bit_pos); 256U - (1U << table->s->last_null_bit_pos);
} }
if ((error= table->file->index_next(table->record[1]))) while ((error= table->file->index_next(table->record[1])))
{ {
table->file->print_error(error, MYF(0)); /* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
continue;
table->file->print_error(error, MYF(0));
table->file->ha_index_end(); table->file->ha_index_end();
DBUG_RETURN(error); DBUG_RETURN(error);
} }
} }
...@@ -812,6 +821,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key) ...@@ -812,6 +821,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
/* Continue until we find the right record or have made a full loop */ /* Continue until we find the right record or have made a full loop */
do do
{ {
restart_rnd_next:
error= table->file->rnd_next(table->record[1]); error= table->file->rnd_next(table->record[1]);
DBUG_DUMP("record[0]", table->record[0], table->s->reclength); DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
...@@ -819,8 +829,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key) ...@@ -819,8 +829,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
switch (error) { switch (error) {
case 0: case 0:
break;
/*
If the record was deleted, we pick the next one without doing
any comparisons.
*/
case HA_ERR_RECORD_DELETED: case HA_ERR_RECORD_DELETED:
break; goto restart_rnd_next;
case HA_ERR_END_OF_FILE: case HA_ERR_END_OF_FILE:
if (++restart_count < 2) if (++restart_count < 2)
...@@ -1680,6 +1696,9 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -1680,6 +1696,9 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
error= do_exec_row(rli); error= do_exec_row(rli);
DBUG_PRINT("info", ("error: %d", error));
DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
table->in_use = old_thd; table->in_use = old_thd;
switch (error) switch (error)
{ {
...@@ -2100,6 +2119,8 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, ...@@ -2100,6 +2119,8 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli,
if (error) if (error)
{ {
DBUG_PRINT("info",("rnd_pos() returns error %d",error)); DBUG_PRINT("info",("rnd_pos() returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -2132,7 +2153,9 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli, ...@@ -2132,7 +2153,9 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli,
HA_READ_KEY_EXACT); HA_READ_KEY_EXACT);
if (error) if (error)
{ {
DBUG_PRINT("info",("index_read_idx() returns error %d",error)); DBUG_PRINT("info",("index_read_idx() returns error %d", error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -2288,6 +2311,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) ...@@ -2288,6 +2311,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
if (error) if (error)
{ {
DBUG_PRINT("info",("rnd_pos returns error %d",error)); DBUG_PRINT("info",("rnd_pos returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
} }
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -2347,6 +2372,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) ...@@ -2347,6 +2372,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
HA_READ_KEY_EXACT))) HA_READ_KEY_EXACT)))
{ {
DBUG_PRINT("info",("no record matching the key found in the table")); DBUG_PRINT("info",("no record matching the key found in the table"));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
table->file->ha_index_end(); table->file->ha_index_end();
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -2404,8 +2431,11 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) ...@@ -2404,8 +2431,11 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
256U - (1U << table->s->last_null_bit_pos); 256U - (1U << table->s->last_null_bit_pos);
} }
if ((error= table->file->index_next(table->record[0]))) while ((error= table->file->index_next(table->record[0])))
{ {
/* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
continue;
DBUG_PRINT("info",("no record matching the given row found")); DBUG_PRINT("info",("no record matching the given row found"));
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
table->file->ha_index_end(); table->file->ha_index_end();
...@@ -2436,14 +2466,17 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) ...@@ -2436,14 +2466,17 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
/* Continue until we find the right record or have made a full loop */ /* Continue until we find the right record or have made a full loop */
do do
{ {
restart_rnd_next:
error= table->file->rnd_next(table->record[0]); error= table->file->rnd_next(table->record[0]);
switch (error) { switch (error) {
case 0: case 0:
case HA_ERR_RECORD_DELETED:
break; break;
case HA_ERR_RECORD_DELETED:
goto restart_rnd_next;
case HA_ERR_END_OF_FILE: case HA_ERR_END_OF_FILE:
if (++restart_count < 2) if (++restart_count < 2)
table->file->ha_rnd_init(1); table->file->ha_rnd_init(1);
......
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