List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:October 28 2008 12:18pm
Subject:Re: bzr commit into mysql-5.1 branch (mats:2771) Bug#40004
View as plain text  
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
Thread
bzr commit into mysql-5.1 branch (mats:2771) Bug#40004Mats Kindahl20 Oct
  • Re: bzr commit into mysql-5.1 branch (mats:2771) Bug#40004Andrei Elkin28 Oct
    • Re: bzr commit into mysql-5.1 branch (mats:2771) Bug#40004Mats Kindahl28 Oct