List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:October 30 2008 9:56am
Subject:bzr commit into mysql-6.0 branch (mats:2882) Bug#40004
View as plain text  
#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);

Thread
bzr commit into mysql-6.0 branch (mats:2882) Bug#40004Mats Kindahl30 Oct