Mats, hello.
The patch looks good. I have couple of question though.
> #At file:///home/bzr/bugs/b40004-5.1-5.1.29-rc/
>
> 2771 Mats Kindahl 2008-10-20
> 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.
>
I think we are able to specify situations more precise.
The facts are: HA_ERR_RECORD_DELETED emits from in MyISAM only,
and a table should not have neither PK nor indexes.
If it sounds to you correct then should not we re-write about the situations?
> 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,
that's ok
> or change the error code to HA_ERR_KEY_NOT_FOUND, in the event
> that a key lookup is attempted.
It looks strange as the bug synopsis implies no key lookup at all.
I see your conversion HA_ERR_RECORD_DELETED -> HA_ERR_KEY_NOT_FOUND
which is principally fine with me but don't see a real case for doing
it.
Could you please explain?
> 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/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-03 20:04:07 +0000
> +++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test 2008-10-20 18:50:08 +0000
> @@ -471,3 +471,94 @@ source include/diff_tables.inc;
> connection master;
> drop table t1;
> 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;
>
> === 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-03 20:04:07 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result 2008-10-20 18:50:08 +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-03 20:04:07 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result 2008-10-20 18:50:08 +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/r/rpl_row_basic_7ndb.result'
> --- a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result 2008-09-03 20:52:54 +0000
> +++ b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result 2008-10-20 18:50:08 +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:21:17 +0000
> +++ b/sql/log_event.cc 2008-10-20 18:50:08 +0000
> @@ -7203,6 +7203,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);
> +
Just for your deliberation:
the position for assert looks better to be in the default branch of
the switch-case.
> table->in_use = old_thd;
> switch (error)
> {
> @@ -7218,11 +7221,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.
> */
Could be moved into the default case together with the assert above.
> 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:
> @@ -7231,7 +7236,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)
> @@ -7254,7 +7258,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));
>
> @@ -8269,6 +8272,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);
> }
> @@ -8301,7 +8306,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);
> }
> @@ -8574,6 +8581,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);
> @@ -8633,6 +8642,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;
> @@ -8690,8 +8701,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();
> @@ -8722,14 +8736,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);
> @@ -8759,7 +8781,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-05-12 17:50:53 +0000
> +++ b/sql/log_event_old.cc 2008-10-20 18:50:08 +0000
> @@ -556,6 +556,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);
> }
> @@ -582,6 +585,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);
> }
> @@ -787,11 +793,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);
> }
> }
>
> @@ -812,6 +821,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);
> @@ -819,8 +829,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)
> @@ -1680,6 +1696,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)
> {
> @@ -2100,6 +2119,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);
> }
> @@ -2132,7 +2153,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);
> }
> @@ -2288,6 +2311,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);
> @@ -2347,6 +2372,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);
> @@ -2404,8 +2431,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();
> @@ -2436,14 +2466,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);
>
>
> --
> MySQL Code Commits Mailing List
> For list archives: http://lists.mysql.com/commits
> To unsubscribe: http://lists.mysql.com/commits?unsub=1
>
cheers,
Andrei