Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
10.3.0, 10.2.6, 10.2(EOL)
-
Debian
Description
Using INSERT ... ON DUPLICATE KEY UPDATE on a table which has a field in a foreign key linked to a PRIMARY field, throw a foreign key error even this field is not updated.
To reproduce :
create database test; |
use test; |
|
CREATE TABLE `v` ( |
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, |
PRIMARY KEY (`id`) |
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; |
|
INSERT v values (1); |
|
CREATE TABLE `vp` ( |
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, |
`v_id` int(10) unsigned NOT NULL, |
`p_id` int(10) unsigned NOT NULL, |
`ppp` varchar(255) NOT NULL, |
PRIMARY KEY (`id`), |
UNIQUE KEY `IDX_vp_uniq` (`v_id`,`p_id`), |
KEY `FK_vp_v` (`v_id`), |
CONSTRAINT `FK_vp_v` FOREIGN KEY (`v_id`) REFERENCES `v` (`id`) ON DELETE CASCADE ON UPDATE CASCADE |
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; |
|
INSERT vp VALUES (12, 1, 100, 'text12'); |
|
set sql_mode=''; |
|
INSERT INTO `vp` (`id`,`ppp`) VALUES (12, 'test12-2') ON DUPLICATE KEY UPDATE `ppp` = VALUES(`ppp`); |
Result:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`vp`, CONSTRAINT `FK_vp_v` FOREIGN KEY (`v_id`) REFERENCES `v` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
|
I can reproduce it on MariaDB 10.2.6 and 10.3.0.
There is no error on 10.1.24.
Thanks
Attachments
Issue Links
- causes
-
MDEV-15042 INSERT ON DUPLICATE KEY UPDATE produces error 1032 (Can't find record)
-
- Closed
-
- includes
-
MDEV-14390 INSERT .. ON DUPLICATE KEY UPDATE does not update
-
- Closed
-
- relates to
-
MDEV-17073 INSERT…ON DUPLICATE KEY UPDATE became more deadlock-prone
-
- Closed
-
-
MDEV-17614 INSERT on dup key update is replication unsafe
-
- Closed
-
-
MDEV-9663 InnoDB assertion failure: *cursor->index->name == TEMP_INDEX_PREFIX, or !cursor->index->is_committed()
-
- Closed
-
marko Found the offending changes on 5.7. There is actually two of them:
Author: Annamalai Gurusami <annamalai.gurusami@oracle.com> Mon Feb 24 10:30:03 2014
Committer: Annamalai Gurusami <annamalai.gurusami@oracle.com> Mon Feb 24 10:30:03 2014
Bug #17604730 ASSERTION: *CURSOR->INDEX->NAME == TEMP_INDEX_PREFIX
Problem:
When INSERT ... ON DUPLICATE UPDATE or REPLACE statements are used, then
after encountering a DB_DUPLICATE_KEY error, we continue to process all
the unique secondary indexes to place the necessary gap locks. The
problem is in the following scenario:
1. The table has one primary index, one unique secondary index and
one non-unique secondary index.
2. The INSERT ... ON DUPLICATE UPDATE ... is executed on the table.
3. Insert into the clustered index reported DB_DUPLICATE_KEY. This
error information is saved. We proceed to take gap locks in all
unique secondary indexes.
4. Insert into the unique secondary index reported DB_LOCK_WAIT.
5. Step 4 is repeated from a higher layer row_ins(). When this is
done, the earlier error information saved in step 3 is lost.
6. Next instead of taking just gap locks or skipping non-unique
secondary indexes, because of loss of information regarding the
error already saved, an actual insert is performed on the non-unique
secondary index. This triggers the assert.
Solution:
Save the error information in a non-local location so that it is not lost.
rb#4723 approved by Kevin.
Author: Marko Mäkelä <marko.makela@oracle.com> Tue Nov 27 11:12:13 2012
Committer: Marko Mäkelä <marko.makela@oracle.com> Tue Nov 27 11:12:13 2012
Bug#15920445 INNODB REPORTS ER_DUP_KEY BEFORE CREATE UNIQUE INDEX COMPLETED
There is a phase during online secondary index creation where the index has
been internally completed inside InnoDB, but does not 'officially' exist yet.
We used to report ER_DUP_KEY in these situations, like this:
ERROR 23000: Can't write; duplicate key in table 't1'
What we should do is to let the 'offending' operation complete, but report an
error to the
ALTER TABLE t1 ADD UNIQUE KEY (c2):
ERROR HY000: Index c2 is corrupted
(This misleading error message should be fixed separately:
Bug#15920713 CREATE UNIQUE INDEX REPORTS ER_INDEX_CORRUPT INSTEAD OF DUPLICATE)
row_ins_sec_index_entry_low(): flag the index corrupted instead of
reporting a duplicate, in case the index has not been published yet.
rb:1614 approved by Jimmy Yang
Problem is that we found the duplicate key error on primary key but then also we found DB_NO_REFERENCED_ROW as search for v_id value 0 fails from index IDX_vp_uniq. This leads wrong error code returned from row_ins().