Bug #40007 Replication failure with RBR + no PK + 2 indexed fields
Submitted: 13 Oct 2008 17:22 Modified: 21 Mar 16:33
Reporter: Philip Stoev
Status: Duplicate
Category:Server: RBR Severity:S2 (Serious)
Version:6.0-rbr OS:Any
Assigned to: Luís Soares Target Version:6.0-beta
Triage: Triaged: D2 (Serious)

[13 Oct 2008 17: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 17:55] Miguel Solorzano
Sveta,
Same as 40001/04 bugs. Thanks.
[13 Oct 2008 22:56] Sveta Smirnova
Thank you for the report.

Verified as described.
[20 Oct 2008 14: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 18:23] Sveta Smirnova
Confirmed INT field is affected as well. Repeatable only with 6.0
[21 Mar 16:33] Luís 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 16:35] Luís Soares
Facing the above analysis this bug seems to be a DUPLICATE of BUG#40045.
Closing as duplicate.