Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
10.5.15, 10.4(EOL), 10.5, 10.6, 10.7(EOL), 10.8(EOL), 10.9(EOL), 10.10(EOL)
-
None
-
Linux 5.10.0-14-amd64, Debian 11.5
Description
(Also reported here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1015293)
Using the MySQL interface, these statements:
DROP TABLE IF EXISTS t; |
CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); |
INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); |
INSERT INTO t VALUES ('Hrecvx_0004mm-00',2) ON DUPLICATE KEY UPDATE n = VALUES (n); |
SELECT * FROM t; |
produce this output:
s n
Hrecvx_0004ln-00 2
Hrecvx_0004mm-00 1
So the latter "INSERT" updates the wrong row.
This happens whether the first column is "BLOB" or "TEXT", but only
with specific values. (In my actual use case with ~1 million rows,
it happened a few dozen times, which might be consistent e.g. with
collisions of a 32 bit hash or so.)
Likewise, these statements:
DROP TABLE IF EXISTS t; |
CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); |
INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); |
REPLACE INTO t VALUES ('Hrecvx_0004mm-00',2); |
SELECT * FROM t; |
give the error:
ERROR 1062 (23000) at line 4: Duplicate entry 'Hrecvx_0004mm-00' for key 's'
In my understanding, this error should actually be impossible with
"REPLACE INTO".
It might be the same issue, i.e. it tries to delete the wrong row
before inserting the new one, so it's still duplicate.
Attachments
Issue Links
- is duplicated by
-
MDEV-30588 Failed to update duplicate data when running insert... on duplicate key update.
-
- Closed
-
- relates to
-
MDEV-371 Unique indexes for blobs
-
- Closed
-
-
MDEV-17395 REPLACE/INSERT ODKU: support WITHOUT OVERLAPS
-
- Stalled
-
-
MDEV-18748 REPLACE doesn't work with unique blobs on MyISAM table
-
- Closed
-
-
MDEV-31093 "ON DUPLICATE KEY UPDATE" saves wrong data to the database
-
- Open
-
- split to
-
MDEV-34091 Refactor write_record and generalize the code with replication
-
- Stalled
-
Activity
Link |
This issue relates to |
Link |
This issue relates to |
Affects Version/s | 10.4 [ 22408 ] | |
Affects Version/s | 10.5 [ 23123 ] | |
Affects Version/s | 10.6 [ 24028 ] | |
Affects Version/s | 10.7 [ 24805 ] | |
Affects Version/s | 10.8 [ 26121 ] | |
Affects Version/s | 10.9 [ 26905 ] | |
Affects Version/s | 10.10 [ 27530 ] |
Fix Version/s | 10.4 [ 22408 ] | |
Fix Version/s | 10.5 [ 23123 ] | |
Fix Version/s | 10.6 [ 24028 ] | |
Fix Version/s | 10.7 [ 24805 ] | |
Fix Version/s | 10.8 [ 26121 ] | |
Fix Version/s | 10.9 [ 26905 ] |
Assignee | Oleksandr Byelkin [ sanja ] |
Status | Open [ 1 ] | Confirmed [ 10101 ] |
Priority | Major [ 3 ] | Critical [ 2 ] |
Description |
(Also reported here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1015293)
Using the MySQL interface, these statements: DROP TABLE IF EXISTS t; CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); INSERT INTO t VALUES ('Hrecvx_0004mm-00',2) ON DUPLICATE KEY UPDATE n = VALUES (n); SELECT * FROM t; produce this output: s n Hrecvx_0004ln-00 2 Hrecvx_0004mm-00 1 So the latter "INSERT" updates the wrong row. This happens whether the first column is "BLOB" or "TEXT", but only with specific values. (In my actual use case with ~1 million rows, it happened a few dozen times, which might be consistent e.g. with collisions of a 32 bit hash or so.) Likewise, these statements: DROP TABLE IF EXISTS t; CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); REPLACE INTO t VALUES ('Hrecvx_0004mm-00',2); SELECT * FROM t; give the error: ERROR 1062 (23000) at line 4: Duplicate entry 'Hrecvx_0004mm-00' for key 's' In my understanding, this error should actually be impossible with "REPLACE INTO". It might be the same issue, i.e. it tries to delete the wrong row before inserting the new one, so it's still duplicate. |
(Also reported here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1015293)
Using the MySQL interface, these statements: {code:sql} DROP TABLE IF EXISTS t; CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); INSERT INTO t VALUES ('Hrecvx_0004mm-00',2) ON DUPLICATE KEY UPDATE n = VALUES (n); SELECT * FROM t; {code} produce this output: s n Hrecvx_0004ln-00 2 Hrecvx_0004mm-00 1 So the latter "INSERT" updates the wrong row. This happens whether the first column is "BLOB" or "TEXT", but only with specific values. (In my actual use case with ~1 million rows, it happened a few dozen times, which might be consistent e.g. with collisions of a 32 bit hash or so.) Likewise, these statements: DROP TABLE IF EXISTS t; CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); REPLACE INTO t VALUES ('Hrecvx_0004mm-00',2); SELECT * FROM t; give the error: ERROR 1062 (23000) at line 4: Duplicate entry 'Hrecvx_0004mm-00' for key 's' In my understanding, this error should actually be impossible with "REPLACE INTO". It might be the same issue, i.e. it tries to delete the wrong row before inserting the new one, so it's still duplicate. |
Description |
(Also reported here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1015293)
Using the MySQL interface, these statements: {code:sql} DROP TABLE IF EXISTS t; CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); INSERT INTO t VALUES ('Hrecvx_0004mm-00',2) ON DUPLICATE KEY UPDATE n = VALUES (n); SELECT * FROM t; {code} produce this output: s n Hrecvx_0004ln-00 2 Hrecvx_0004mm-00 1 So the latter "INSERT" updates the wrong row. This happens whether the first column is "BLOB" or "TEXT", but only with specific values. (In my actual use case with ~1 million rows, it happened a few dozen times, which might be consistent e.g. with collisions of a 32 bit hash or so.) Likewise, these statements: DROP TABLE IF EXISTS t; CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); REPLACE INTO t VALUES ('Hrecvx_0004mm-00',2); SELECT * FROM t; give the error: ERROR 1062 (23000) at line 4: Duplicate entry 'Hrecvx_0004mm-00' for key 's' In my understanding, this error should actually be impossible with "REPLACE INTO". It might be the same issue, i.e. it tries to delete the wrong row before inserting the new one, so it's still duplicate. |
(Also reported here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1015293)
Using the MySQL interface, these statements: {code:sql} DROP TABLE IF EXISTS t; CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); INSERT INTO t VALUES ('Hrecvx_0004mm-00',2) ON DUPLICATE KEY UPDATE n = VALUES (n); SELECT * FROM t; {code} produce this output: s n Hrecvx_0004ln-00 2 Hrecvx_0004mm-00 1 So the latter "INSERT" updates the wrong row. This happens whether the first column is "BLOB" or "TEXT", but only with specific values. (In my actual use case with ~1 million rows, it happened a few dozen times, which might be consistent e.g. with collisions of a 32 bit hash or so.) Likewise, these statements: {code:sql} DROP TABLE IF EXISTS t; CREATE TABLE t (s BLOB, n INT, UNIQUE (s)); INSERT INTO t VALUES ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); REPLACE INTO t VALUES ('Hrecvx_0004mm-00',2); SELECT * FROM t; {code} give the error: ERROR 1062 (23000) at line 4: Duplicate entry 'Hrecvx_0004mm-00' for key 's' In my understanding, this error should actually be impossible with "REPLACE INTO". It might be the same issue, i.e. it tries to delete the wrong row before inserting the new one, so it's still duplicate. |
Assignee | Oleksandr Byelkin [ sanja ] | Alexander Barkov [ bar ] |
Link |
This issue relates to |
Assignee | Alexander Barkov [ bar ] | Nikita Malyavin [ nikitamalyavin ] |
Status | Confirmed [ 10101 ] | In Progress [ 3 ] |
Link | This issue relates to MDEV-17395 [ MDEV-17395 ] |
Status | In Progress [ 3 ] | Stalled [ 10000 ] |
Comment |
[ Thanks [~bar] for the pointers, the bug with IDEMPOTENT replication was found with long uniques, which uses the same logic as REPLACE, and even contains the copy-paste from there. I guess it was made so to allocate and reuse the key buffer memory on the stack, saving from extra malloc. I think our priority now is to minimize stack usage vs extra mallocs, so it's not the point anymore.
I made some refactoring and extracted common code. Also moved handler's RND search initialization to {{Write_rows_log_event::do_before_row_operations}}. This fixed many long unique bugs in relplication and optimized the use a little bit. https://github.com/MariaDB/server/commit/703e73e221a42638f2f05379124b35c57482da93 One more refactoring should be done to generalize handler initialization (and de-initialization) across REPLACE, LOAD DATA, IDEMPOTENT replication, and improve memory usage. ] |
Link |
This issue is duplicated by |
Fix Version/s | 10.7 [ 24805 ] |
Link | This issue relates to MDEV-31093 [ MDEV-31093 ] |
Fix Version/s | 10.8 [ 26121 ] |
Fix Version/s | 10.9 [ 26905 ] |
Status | Stalled [ 10000 ] | In Progress [ 3 ] |
Status | In Progress [ 3 ] | Stalled [ 10000 ] |
Status | Stalled [ 10000 ] | In Progress [ 3 ] |
Status | In Progress [ 3 ] | In Testing [ 10301 ] |
Status | In Testing [ 10301 ] | Stalled [ 10000 ] |
Assignee | Nikita Malyavin [ nikitamalyavin ] | Sergei Golubchik [ serg ] |
Status | Stalled [ 10000 ] | In Review [ 10002 ] |
Assignee | Sergei Golubchik [ serg ] | Nikita Malyavin [ nikitamalyavin ] |
Status | In Review [ 10002 ] | Stalled [ 10000 ] |
Link | This issue split to MDEV-34091 [ MDEV-34091 ] |
Fix Version/s | 10.5.25 [ 29626 ] | |
Fix Version/s | 10.4 [ 22408 ] | |
Fix Version/s | 10.5 [ 23123 ] | |
Fix Version/s | 10.6 [ 24028 ] | |
Resolution | Fixed [ 1 ] | |
Status | Stalled [ 10000 ] | Closed [ 6 ] |
Fix Version/s | 10.6.18 [ 29627 ] | |
Fix Version/s | 10.11.8 [ 29630 ] | |
Fix Version/s | 11.0.6 [ 29628 ] | |
Fix Version/s | 11.1.5 [ 29629 ] | |
Fix Version/s | 11.2.4 [ 29631 ] | |
Fix Version/s | 11.4.2 [ 29633 ] |
Thanks for the report! I repeated as described on 10.4-10.11, InnoDB. Probably caused by
MDEV-371--source include/have_innodb.inc
10.4 0d586d62e5326053383
CURRENT_TEST: main.1_my
mysqltest: At line 9: query 'REPLACE INTO t VALUES ('Hrecvx_0004mm-00',2)' failed: 1062: Duplicate entry 'Hrecvx_0004mm-00' for key 's'
SELECT * FROM t;
s n
Hrecvx_0004ln-00 2
Hrecvx_0004mm-00 1