Bug #40007 Replication failure with RBR + no PK + 2 indexed fields
Submitted: 13 Oct 2008 15:22 Modified: 21 Mar 2009 15:33
Reporter: Philip Stoev Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server: Row Based Replication ( RBR ) Severity:S2 (Serious)
Version:6.0-rbr OS:Any
Assigned to: Luis Soares CPU Architecture:Any

[13 Oct 2008 15:22] Philip Stoev
Description:
When executing an UPDATE against a table that contains several indexed fields, row-based replication will break:

081013 18:19:22 [ERROR] Slave SQL: Could not execute Update_rows event on table test.table1_myisam; Can't find record in 'table1_myisam', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log master-bin.000001, end_log_pos 663, Error_code: 1032
081013 18:19:22 [ERROR] Slave: Can't find record in 'table1_myisam' Error_code: 1032
081013 18:19:22 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'master-bin.000001' position 506

The example below uses a bit field and an int field, however the same issue has been observed with two integer fields. All storage engines appear to be affected.

How to repeat:
--source include/master-slave.inc

SET binlog_format = 'row';

CREATE TABLE table1_myisam (
        `bit_key` bit,
        `int_key` int,
        key (`bit_key` ),
        key (`int_key` )
);

INSERT IGNORE INTO table1_myisam VALUES ('1', '-2146992385');
UPDATE `table1_myisam` SET `bit_key` = 0 WHERE `bit_key` = 1;

--save_master_pos
--connection slave
--sync_with_master
[13 Oct 2008 15:55] MySQL Verification Team
Sveta,
Same as 40001/04 bugs. Thanks.
[13 Oct 2008 20:56] Sveta Smirnova
Thank you for the report.

Verified as described.
[20 Oct 2008 12:10] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/56576

2771 Mats Kindahl	2008-10-15
      Bug #40007: Replication failure with RBR + no PK + 2 indexed fields 
      
      Unable to reproduce failure, but adding test case according to report
      to avoid regressions.
[22 Oct 2008 16:23] Sveta Smirnova
Confirmed INT field is affected as well. Repeatable only with 6.0
[21 Mar 2009 15:33] Luis Soares
I used the following for reproducing the bug behavior as described in the bug report. (I used two integer fields).

--source include/master-slave.inc
--source include/have_binlog_format_row.inc

CREATE TABLE table1_myisam ( `int_key1` int, `int_key` int, key (`int_key1` ), key (`int_key` ));

INSERT IGNORE INTO table1_myisam VALUES ('1', '2');
UPDATE `table1_myisam` SET `int_key1` = 0 WHERE `int_key1` = 1;

sync_slave_with_master;

Using gdb and stepping into the Rows_log_event::find_row method I found the following:

[After unpack_current_row]

(gdb) call bitmap_is_set(&m_cols, 0)
$1 = 1
(gdb) call bitmap_is_set(&m_cols, 1)
$2 = 0
(gdb) call table->field[0]->ptr
$3 = (uchar *) 0x9aca3a1 "\001"
(gdb) call table->field[1]->ptr
$4 = (uchar *) 0x9aca3a5 ""

Remark: Note how the second field (table->field[1]->ptr), from the replicated row, is set to "".

Stepping further, I found that the record fetched from the storage engine is:

[Before record_compare]

(gdb)  call table->field[0]->ptr
$5 = (uchar *) 0x9aca3a1 "\001"
(gdb)  call table->field[1]->ptr
$6 = (uchar *) 0x9aca3a5 "\002"

Remark: Note how the second field from the row fetched from the slave SE is filled with a value.

Consequently the comparison of these two records will fail because the row fetched has more data than the unpacked row.

[return value from record_compare]

>>> result= cmp_record(table,record[1]);

(gdb) p result
$1 = true

Finally, the proposed patch for BUG#40045 seems to fix this.
[21 Mar 2009 15:35] Luis Soares
Facing the above analysis this bug seems to be a DUPLICATE of BUG#40045.
Closing as duplicate.