From: Date: October 30 2008 10:56am Subject: bzr commit into mysql-6.0 branch (mats:2882) Bug#40004 List-Archive: http://lists.mysql.com/commits/57426 X-Bug: 40004 Message-Id: <20081030095634.2E161469FF0@romeo> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/bzr/merges/merge-6.0-5.1.29-rc/ 2882 Mats Kindahl 2008-10-30 [merge] Merging BUG#40004 into 6.0-5.1.29-rc modified: mysql-test/extra/rpl_tests/rpl_row_basic.test mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result mysql-test/suite/rpl_ndb_big/r/rpl_row_basic_7ndb.result sql/log_event.cc sql/log_event_old.cc === modified file 'mysql-test/extra/rpl_tests/rpl_row_basic.test' --- a/mysql-test/extra/rpl_tests/rpl_row_basic.test 2008-09-05 13:39:08 +0000 +++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test 2008-10-30 09:55:50 +0000 @@ -471,3 +471,102 @@ source include/diff_tables.inc; connection master; drop table t1; sync_slave_with_master; + +# +# BUG#40004: Replication failure with no PK + no indexes +# + +# The test cases are taken from the bug report. It is difficult to +# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go +# with the test cases we have. + +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 +# + +# The test cases are taken from the bug report. It is difficult to +# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go +# with the test cases we have. + +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; === modified file 'mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result' --- a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result 2008-09-05 13:39:08 +0000 +++ b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result 2008-10-30 09:55:50 +0000 @@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for ke INSERT INTO t1 VALUES (4); Comparing tables master:test.t1 and slave:test.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; === modified file 'mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result' --- a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result 2008-09-05 13:39:08 +0000 +++ b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result 2008-10-30 09:55:50 +0000 @@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for ke INSERT INTO t1 VALUES (4); Comparing tables master:test.t1 and slave:test.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; === modified file 'mysql-test/suite/rpl_ndb_big/r/rpl_row_basic_7ndb.result' --- a/mysql-test/suite/rpl_ndb_big/r/rpl_row_basic_7ndb.result 2008-09-11 08:01:28 +0000 +++ b/mysql-test/suite/rpl_ndb_big/r/rpl_row_basic_7ndb.result 2008-10-30 09:55:50 +0000 @@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for ke INSERT INTO t1 VALUES (4); Comparing tables master:test.t1 and slave:test.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; === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2008-10-07 13:49:24 +0000 +++ b/sql/log_event.cc 2008-10-30 09:55:50 +0000 @@ -7244,6 +7244,9 @@ int Rows_log_event::do_apply_event(Relay 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; switch (error) { @@ -7259,11 +7262,13 @@ int Rows_log_event::do_apply_event(Relay case HA_ERR_TABLE_DEF_CHANGED: case HA_ERR_CANNOT_ADD_FOREIGN: - + 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_DELETED: case HA_ERR_KEY_NOT_FOUND: case HA_ERR_END_OF_FILE: case HA_ERR_FOUND_DUPP_KEY: @@ -7272,7 +7277,6 @@ int Rows_log_event::do_apply_event(Relay case HA_ERR_NO_REFERENCED_ROW: 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 (global_system_variables.log_warnings) @@ -7295,7 +7299,6 @@ int Rows_log_event::do_apply_event(Relay 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", (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end)); @@ -8332,6 +8335,8 @@ Rows_log_event::write_row(const Relay_lo 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)); DBUG_RETURN(error); } @@ -8364,7 +8369,9 @@ Rows_log_event::write_row(const Relay_lo HA_READ_KEY_EXACT); 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)); DBUG_RETURN(error); } @@ -8651,6 +8658,8 @@ int Rows_log_event::find_row(const Relay 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)); } DBUG_RETURN(error); @@ -8704,6 +8713,8 @@ int Rows_log_event::find_row(const Relay HA_READ_KEY_EXACT))) { 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->ha_index_end(); goto err; @@ -8761,8 +8772,11 @@ int Rows_log_event::find_row(const Relay 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")); table->file->print_error(error, MYF(0)); table->file->ha_index_end(); @@ -8793,14 +8807,22 @@ int Rows_log_event::find_row(const Relay /* Continue until we find the right record or have made a full loop */ do { + restart_rnd_next: error= table->file->rnd_next(table->record[0]); + DBUG_PRINT("info", ("error: %s", HA_ERR(error))); switch (error) { case 0: - case HA_ERR_RECORD_DELETED: 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: if (++restart_count < 2) table->file->ha_rnd_init(1); @@ -8830,7 +8852,7 @@ int Rows_log_event::find_row(const Relay DBUG_DUMP("record found", table->record[0], table->s->reclength); 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; } ok: === modified file 'sql/log_event_old.cc' --- a/sql/log_event_old.cc 2008-08-08 01:33:43 +0000 +++ b/sql/log_event_old.cc 2008-10-30 09:55:50 +0000 @@ -547,6 +547,9 @@ replace_record(THD *thd, TABLE *table, error= table->file->rnd_pos(table->record[1], table->file->dup_ref); 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)); DBUG_RETURN(error); } @@ -573,6 +576,9 @@ replace_record(THD *thd, TABLE *table, HA_READ_KEY_EXACT); 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)); DBUG_RETURN(error); } @@ -774,11 +780,14 @@ static int find_and_fetch_row(TABLE *tab 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(); - DBUG_RETURN(error); + DBUG_RETURN(error); } } @@ -799,6 +808,7 @@ static int find_and_fetch_row(TABLE *tab /* Continue until we find the right record or have made a full loop */ do { + restart_rnd_next: error= table->file->rnd_next(table->record[1]); DBUG_DUMP("record[0]", table->record[0], table->s->reclength); @@ -806,8 +816,14 @@ static int find_and_fetch_row(TABLE *tab switch (error) { case 0: + break; + + /* + If the record was deleted, we pick the next one without doing + any comparisons. + */ case HA_ERR_RECORD_DELETED: - break; + goto restart_rnd_next; case HA_ERR_END_OF_FILE: if (++restart_count < 2) @@ -1665,6 +1681,9 @@ int Old_rows_log_event::do_apply_event(R error= do_exec_row(rli); + DBUG_PRINT("info", ("error: %d", error)); + DBUG_ASSERT(error != HA_ERR_RECORD_DELETED); + table->in_use = old_thd; switch (error) { @@ -2078,6 +2097,8 @@ Old_rows_log_event::write_row(const Rela 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)); DBUG_RETURN(error); } @@ -2110,7 +2131,9 @@ Old_rows_log_event::write_row(const Rela HA_READ_KEY_EXACT); 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)); DBUG_RETURN(error); } @@ -2267,6 +2290,8 @@ int Old_rows_log_event::find_row(const R 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)); } DBUG_RETURN(error); @@ -2320,6 +2345,8 @@ int Old_rows_log_event::find_row(const R HA_READ_KEY_EXACT))) { 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->ha_index_end(); DBUG_RETURN(error); @@ -2377,8 +2404,11 @@ int Old_rows_log_event::find_row(const R 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")); table->file->print_error(error, MYF(0)); table->file->ha_index_end(); @@ -2409,14 +2439,17 @@ int Old_rows_log_event::find_row(const R /* Continue until we find the right record or have made a full loop */ do { + restart_rnd_next: error= table->file->rnd_next(table->record[0]); switch (error) { case 0: - case HA_ERR_RECORD_DELETED: break; + case HA_ERR_RECORD_DELETED: + goto restart_rnd_next; + case HA_ERR_END_OF_FILE: if (++restart_count < 2) table->file->ha_rnd_init(1);