Details
-
Bug
-
Status: In Review (View Workflow)
-
Critical
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.0, 13.1, 13.2
Description
Likely cause: the fix for MDEV-36115, commit c1492f3d077e47a015c6e4c5dcd2107b803ac3f4, in ha_partition::update_row(). This is a regression.
Since that fix, when an UPDATE cannot write a row to its new partition, the server looks up the duplicate key in the old partition.
CS 11.4.6 at revision ef966af801afc2a07222b5df65dddd52c77431dd, which does not have that fix, gives ERROR 1062 and names the right key in all three checks.
--source include/have_partition.inc
|
CREATE TABLE t1 (id INT PRIMARY KEY, a INT) ENGINE=MyISAM PARTITION BY HASH (id) PARTITIONS 4; |
INSERT INTO t1 VALUES (1, 1), (2, 2); |
--error 0,ER_DUP_ENTRY,ER_DUP_KEY
|
UPDATE t1 SET id = 2 WHERE id = 1; |
if ($mysql_errno != 1062) |
{
|
--die An UPDATE on MyISAM that moves a row to another partition and meets a duplicate key gives error $mysql_errno, not 1062 ER_DUP_ENTRY |
}
|
CREATE TABLE t2 (id INT PRIMARY KEY, a INT) ENGINE=Aria PARTITION BY HASH (id) PARTITIONS 4; |
INSERT INTO t2 VALUES (1, 1), (2, 2); |
--error 0,ER_DUP_ENTRY,ER_DUP_KEY
|
UPDATE t2 SET id = 2 WHERE id = 1; |
if ($mysql_errno != 1062) |
{
|
--die An UPDATE on Aria that moves a row to another partition and meets a duplicate key gives error $mysql_errno, not 1062 ER_DUP_ENTRY |
}
|
CREATE TABLE t3 (a INT, b INT, c INT, PRIMARY KEY (a, b), UNIQUE KEY uc (a, c)) ENGINE=MyISAM PARTITION BY HASH (a) PARTITIONS 4; |
INSERT INTO t3 VALUES (1, 1, 1), (2, 2, 1); |
--error 0,ER_DUP_ENTRY,ER_DUP_KEY
|
INSERT INTO t3 VALUES (1, 1, 9) ON DUPLICATE KEY UPDATE a = 2; |
GET DIAGNOSTICS CONDITION 1 @m = MESSAGE_TEXT;
|
--let $ok= query_get_value(SELECT @m LIKE '%for key ''uc''%' AS ok, ok, 1)
|
if (!$ok) |
{
|
--die An INSERT ... ON DUPLICATE KEY UPDATE on MyISAM that moves a row to another partition and meets a duplicate on key uc does not name key uc |
}
|
DROP TABLE t1, t2, t3; |
Leads to:
|
CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Optimized, Clang 22.1.8-20260622) Build 05/10/2026 |
mysqltest: At line 8: An UPDATE on MyISAM that moves a row to another partition and meets a duplicate key gives error 1022, not 1062 ER_DUP_ENTRY
|
MyISAM gives ERROR 1022 (23000): Can't write; duplicate key in table 't1', and Aria gives the same for t2. InnoDB, and a table without partitioning, give ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'. An UPDATE that meets a duplicate in the same partition gives ERROR 1062 on all engines. Debug builds give the same result.
With a second UNIQUE key, the third check gives ERROR 1062 (23000): Duplicate entry '2-1' for key 'PRIMARY'. No row has the PRIMARY KEY value (2, 1). The duplicate is on key uc.
The fix for MDEV-36817 changed only InnoDB. MyISAM and Aria still give ERROR 1022, as seen in MDEV-36937.
|
MySQL, the MyISAM statements of the testcase |
+--------+---------------------------------------+------------------------------------+
|
| MySQL | UPDATE t1 | INSERT ... ON DUPLICATE KEY UPDATE |
|
+--------+---------------------------------------+------------------------------------+
|
| 5.5.62 | Duplicate entry '2' for key 'PRIMARY' | Duplicate entry '2-1' for key 'uc' |
|
| 5.6.51 | Duplicate entry '2' for key 'PRIMARY' | Duplicate entry '2-1' for key 'uc' |
|
| 5.7.44 | Duplicate entry '2' for key 'PRIMARY' | Duplicate entry '2-1' for key 'uc' |
|
+--------+---------------------------------------+------------------------------------+
|
MySQL 8.0.36 and 9.1.0 do not partition a MyISAM table.
|
From the code it seems that ha_partition::update_row() returns on the write error before it sets m_last_part to the new partition. info(HA_STATUS_ERRKEY) and print_error() then ask the old partition for the key number. MyISAM and Aria keep that number in the handle of each partition. The old partition has no duplicate, or it has the key of an earlier error, as in the third check. InnoDB keeps the key number in the transaction, so any partition gives the right key.
Attachments
Issue Links
- is caused by
-
MDEV-36115 Assertion InnoDB searching row in wrong partition for multiple system versioned DELETE with same timestamp and same multistatement transaction
-
- Closed
-
- relates to
-
MDEV-36817 Server crashes in do_mark_index_columns instead of ER_DUP_ENTRY on partitioned table
-
- Closed
-
-
MDEV-36937 SIGSEGV in do_mark_index_columns on UPDATE w/ UNIQUE index
-
- Closed
-