Bug #57373 | Multi update+InnoDB reports ER_KEY_NOT_FOUND if a table is updated twice | ||
---|---|---|---|
Submitted: | 11 Oct 2010 14:14 | Modified: | 2 Mar 2011 15:25 |
Reporter: | Matthias Leich | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: DML | Severity: | S3 (Non-critical) |
Version: | 5.1, 5.5 | OS: | Any |
Assigned to: | Jørgen Løland | CPU Architecture: | Any |
Tags: | RQG |
[11 Oct 2010 14:14]
Matthias Leich
[11 Oct 2010 14:20]
Matthias Leich
The same problem could be observed with mysql-5.5 revno: 3088 2010-10-02 (5.5.7-rc-debug-log)
[18 Oct 2010 13:52]
Konstantin Osipov
A multi-update bug. Need the core file.
[2 Nov 2010 15:43]
Jon Olav Hauglid
MTR test case: CREATE TABLE t1(pk INT, PRIMARY KEY (pk)) engine=innodb; INSERT INTO t1 VALUES (0); UPDATE t1 AS A, t1 AS B SET A.pk = 1, B.pk = 2;
[4 Nov 2010 8:57]
Jon Olav Hauglid
With the test case above, the bug is repeatable in 5.1 as well.
[6 Jan 2011 9:01]
Jørgen Løland
Same cause as BUG#55385: The first update ("SET A.pk = 1") moves a record to another partition, the second update ("B.pk = 2") therefore fails to find the record in the partition it expects it to be.
[17 Jan 2011 9:26]
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/128909 3256 Jorgen Loland 2011-01-17 Bug#55385: UPDATE statement throws an error, but still updates the table entries Bug#57373: Multi update+InnoDB reports ER_KEY_NOT_FOUND if a table is updated twice Partitioning fails if multi-update updates the same partitioned table twice and the partitioning key is updated. This is because updates on the first table may move records from one partition to another, and update on the second table will fail to locate the records to update due to this. In InnoDB (BUG#57373), the result was that updates on the first table were performed. The transaction was then aborted once updates on the second table failed to locate records. Error ER_KEY_NOT_FOUND was returned. Problem: unneccessary work was performed (update + abort) and misleading error message returned. In MyISAM (BUG#55385), the result was that updates on the first table were performed. The transaction was then stopped once updates on the second table failed to locate records. Error "Got error 134 from storage engine" was returned. However, since MyISAM is unable to abort, the updates on the first table were still in effect. Problem: misleading error message and half-performed transaction. The fix is to chech if multi-table update will a) update the same partition twice, and b) at least one of these will update the partitioning key and thereby risk moving records to another partition. If this is the case, a meaningful error message is issued before any update work has been done. @ mysql-test/r/partition.result Add test for bugs 55385 and 57373. @ mysql-test/t/partition.test Add test for bugs 55385 and 57373. @ sql/share/errmsg-utf8.txt New error message for multi-table update where the same partition is updated twice. @ sql/sql_update.cc Check if multi-table update is about to update the same partitioned table twice and issue error.
[2 Mar 2011 15:25]
Paul DuBois
Noted in 5.5.11, 5.6.2 changelogs. If a multiple-table update updated a row through two aliases and the first update physically moved the row, the second update failed to locate the row. This resulted in different errors depending on storage engine, although these errors did not accurately describe the problem: * MyISAM: Got error 134 from storage engine * InnoDB: Can't find record in 'tbl' For MyISAM, which is nontransactional, the update executed first was performed but the second was not. In addition, for two equal multiple-table update statements, one could succeed and the other fail depending on whether the record actually moved, which is inconsistent. Now such an update returns an error if it will update a table through multiple aliases, and perform an update that may physically more the row in at least one of these aliases. CHANGESET - http://lists.mysql.com/commits/131836