Bug #121467 Replica SQL thread stops with ER_DUP_ENTRY when HASH_SCAN replays an Update_rows event that rotates unique key values
Submitted: 9 Oct 11:49 Modified: 9 Oct 11:56
Reporter: ximin liang (OCA) Email Updates:
Status: Open Impact on me:
None 
Category:MySQL Server: Replication Severity:S2 (Serious)
Version:26.7.10 OS:Any
Assigned to: CPU Architecture:Any

[9 Oct 11:49] ximin liang
Description:
On a replica using row-based replication, the applier aborts with

Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY;
Duplicate entry '101-1' for key 'unique_key_t.c1'

How to repeat:
Setup a source/replica pair with row-based replication (no special configuration is needed — 8.0 defaults include HASH_SCAN; `binlog_format = ROW`). On the **source**:

```sql
CREATE TABLE unique_key_t (
  c1 INT NOT NULL,
  c2 INT DEFAULT NULL,
  UNIQUE KEY c1 (c1, c2)
) ENGINE = InnoDB;

-- 1) First batch, then the rotating update
INSERT INTO unique_key_t VALUES (1,NULL),(1,1),(2,NULL),(2,2);
INSERT INTO unique_key_t VALUES (1,NULL),(2,NULL);
UPDATE unique_key_t SET c1 = c1 + 100;   -- OK on source and replica

-- 2) Second batch (adds the rows that make the key order differ from the
--    DB_ROW_ID order), then the same rotating update
INSERT INTO unique_key_t VALUES (1,NULL),(1,1),(2,NULL),(2,2);
INSERT INTO unique_key_t VALUES (1,NULL),(2,NULL);
UPDATE unique_key_t SET c1 = c1 + 100;   -- OK on source, FAILS on replica
```

Observed on the replica:

```sql
SHOW SLAVE STATUS\G
-- Slave_SQL_Running: No
-- Last_Errno: 1062
-- Last_Error: Could not execute Update_rows event on table test.unique_key_t;
--             Duplicate entry '101-1' for key 'unique_key_t.c1',
--             Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; ...
START SLAVE SQL_THREAD;   -- fails again at the same event position
```

Expected: the replica applies the event and its content matches the source (`diff_tables` compatible).

Notes for test development:

* Before the fix, `Slave_rows_last_search_algorithm_used` (debug builds only) reports `HASH_SCAN` for the failing `Update_rows` event.
* The first `UPDATE` in the script is only there to shape the physical row order; a test can also be written with variants that make the event order differ from both the clustered and any secondary key order, e.g.

```sql
CREATE TABLE t (c1 INT NOT NULL, c2 INT NULL, c3 INT, UNIQUE KEY uk(c1,c2), KEY k(c3)) ENGINE=InnoDB;
INSERT INTO t VALUES (101,1,9),(1,1,0);
UPDATE t SET c1 = c1 + 100;             -- driving key k(c3) => (1,1,0) is applied first, still 1062
```

```sql
CREATE TABLE t (c1 INT NOT NULL, c2 INT NULL, UNIQUE KEY uk(c1,c2)) ENGINE=InnoDB;
INSERT INTO t VALUES (1,1),(2,1),(3,1);
UPDATE t SET c1 = c1 + 1 ORDER BY c1 DESC;   -- 1062 as well
```
[9 Oct 11:56] ximin liang
https://github.com/mysql/mysql-server/pull/834

here is my suggested fix