Bug #47453 | InnoDB incorrectly changes TIMESTAMP columns when JOINed during an UPDATE | ||
---|---|---|---|
Submitted: | 19 Sep 2009 13:46 | Modified: | 18 Jun 2010 1:28 |
Reporter: | Peter Waltner | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: DML | Severity: | S2 (Serious) |
Version: | 5.1.30, 5.1.45, 5.5.2-m2 | OS: | Any |
Assigned to: | Georgi Kodinov | CPU Architecture: | Any |
Tags: | innodb, join, timestamp, UPDATE |
[19 Sep 2009 13:46]
Peter Waltner
[19 Sep 2009 14:49]
Peter Waltner
Concise example of Bug #47453
Attachment: BUG_47453_Example_1.sql (application/octet-stream, text), 1.51 KiB.
[19 Sep 2009 14:57]
Peter Waltner
My apologies. The fix I suggested above does not work and the suggestion that the bug is related to bug #43617 is now unfounded. Here are the "fixes" I have been able to figure out. 1) Problem only exists with InnoDB tables. Use MyISAM tables and the problem goes away. This is not a good fix since if you specified InnoDB tables, you probably need them. 2) If you include "SET timestamp=timestamp", where timestamp is a column with TIMESTAMP(14) or something like that, then MySQL will not change the timestamp field. Therefore, MySQL now reports the correct number of updates on the joined INNODB tables, however, this is not a good fix since your updated fields have an incorrect timestamp since we are forcing the old timestamp to be used after update. 3) There is probably a convoluted SQL statement to get the desired behavior when doing an UPDATED of INNODB tables with a TIMESTAMP column of: a) updating the timestamp only when the row is updated b) reporting the correct number of updated rows c) having the timestamp reflect when the row was changed. but I have not had the time to work that one out yet.
[19 Sep 2009 15:29]
Peter Waltner
A workaround by protecting the UPDATE with the addition to the WHERE clause.
Attachment: BUG_47453_Workaround_1.sql (application/octet-stream, text), 1.98 KiB.
[19 Sep 2009 15:36]
Peter Waltner
The workaround posted in the attached file above gets around the immediate concern by adding an additional constraint to the WHERE clause. However, notice that the expected behavior of UPDATE is to match and not change if we are attempting to update a row to an already existing value. This workaround violates this expected behavior of UPDATE, but may solve the more immediate issue of InnoDB updating TIMESTAMP columns even when the row is otherwise unchanged after the UPDATE.
[19 Sep 2009 15:42]
Peter Waltner
Results from the workaround posted above. Note that it is important to wait >1s as documented in the workaround example.
Attachment: BUG_47453_Workaround_1_output.txt (text/plain), 4.82 KiB.
[21 Sep 2009 6:39]
Sveta Smirnova
Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://dev.mysql.com/doc/ and the instructions on how to report a bug at http://bugs.mysql.com/how-to-report.php Please read at http://dev.mysql.com/doc/refman/5.1/en/timestamp.html about default value for first TIMESTAMP field in the table: In a CREATE TABLE statement, the first TIMESTAMP column can be declared in any of the following ways: ... * With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
[17 Mar 2010 11:14]
Andrii Nikitin
another testcase
Attachment: bug47453.sql (application/octet-stream, text), 3.00 KiB.
[17 Mar 2010 11:29]
Andrii Nikitin
This bug silently makes Slave out of sync in replication from 5.0 to 5.1 (Because on 5.0 Master TIMESTAMP is not updated). Also it silently makes Slave out of sync in STATEMENT 5.1 replication if tables use different engines on master and slave (InnoDB->MyISAM or MyISAM->InnoDB) Even more problems if ON UPDATE triggers exists in examples above. Please find one more testcase with identical conclusions (test47453.sql): 1. Bug is InnoDB related (not MyISAM) 2. "Changed:" is not zero only if TIMESTAMP column present in table. 3. Bug has timing issues (in immediate update "Changed:" is reported zero) 4. 2) and 3) above make me think that root cause is related to detection if TIMESTAMP field updated. Please note that fixing this bug most probably will make problems in replication from older 5.1 versions (so TIMESTAMP will be changed and triggers will be executed on Master, but not on Slave where bug is fixed).
[19 Mar 2010 7:47]
Andrii Nikitin
Here is the the smallest testcase, (but I advise review all other testcases because they demonstrate complex conditions for the problem). CREATE TABLE linkedTable (testTableId INT) ENGINE = INNODB; CREATE TABLE testTable (id INT, data CHAR(50), timestamp TIMESTAMP(14) ) ENGINE = INNODB; INSERT INTO linkedTable (testTableId) VALUES (1); INSERT INTO testTable (id,data) VALUES (1,'original data'); select * from linkedTable; select sleep(1); UPDATE linkedTable JOIN testTable ON testTableId=id SET data='original data' WHERE id=1; select * from linkedTable;
[13 Apr 2010 7:14]
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/105464 3452 Georgi Kodinov 2010-04-13 Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when JOINed during an UPDATE Extended the fix for bug 29310 to multi-table update: When a table is being updated it has two set of fields - fields required for checks of conditions and fields to be updated. A storage engine is allowed not to retrieve columns marked for update. Due to this fact records can't be compared to see whether the data has been changed or not. This makes the server always update records independently of data change. Now when an auto-updatable timestamp field is present and server sees that a table handle isn't going to retrieve write-only fields then all of such fields are marked as to be read to force the handler to retrieve them.
[20 Apr 2010 13:00]
Martin Hansson
Please change 'set' in the first sentence to 'sets'. Otherwise, it looks good to go.
[28 Apr 2010 12:56]
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/106817 3452 Georgi Kodinov 2010-04-28 Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when JOINed during an UPDATE Extended the fix for bug 29310 to multi-table update: When a table is being updated it has two set of fields - fields required for checks of conditions and fields to be updated. A storage engine is allowed not to retrieve columns marked for update. Due to this fact records can't be compared to see whether the data has been changed or not. This makes the server always update records independently of data change. Now when an auto-updatable timestamp field is present and server sees that a table handle isn't going to retrieve write-only fields then all of such fields are marked as to be read to force the handler to retrieve them.
[28 Apr 2010 12:57]
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/106818 3360 Georgi Kodinov 2010-04-28 Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when JOINed during an UPDATE Extended the fix for bug 29310 to multi-table update: When a table is being updated it has two set of fields - fields required for checks of conditions and fields to be updated. A storage engine is allowed not to retrieve columns marked for update. Due to this fact records can't be compared to see whether the data has been changed or not. This makes the server always update records independently of data change. Now when an auto-updatable timestamp field is present and server sees that a table handle isn't going to retrieve write-only fields then all of such fields are marked as to be read to force the handler to retrieve them.
[5 May 2010 15:24]
Bugs System
Pushed into 5.1.47 (revid:joro@sun.com-20100505145753-ivlt4hclbrjy8eye) (version source revid:joro@sun.com-20100428125554-sympdx16ghfmlh7a) (merge vers: 5.1.47) (pib:16)
[13 May 2010 0:29]
Paul DuBois
Noted in 5.1.47 changelogs. For updates to InnoDB tables, TIMESTAMP columns could be updated even when no values actually changed.
[28 May 2010 5:58]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100524190136-egaq7e8zgkwb9aqi) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (pib:16)
[28 May 2010 6:27]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100524190941-nuudpx60if25wsvx) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[28 May 2010 6:54]
Bugs System
Pushed into 5.5.5-m3 (revid:alik@sun.com-20100524185725-c8k5q7v60i5nix3t) (version source revid:alexey.kopytov@sun.com-20100429203306-tg0wz4y2xyx8edrl) (merge vers: 5.5.5-m3) (pib:16)
[29 May 2010 2:28]
Paul DuBois
Noted in 5.5.5, 6.0.14 changelogs.
[17 Jun 2010 12:01]
Bugs System
Pushed into 5.1.47-ndb-7.0.16 (revid:martin.skold@mysql.com-20100617114014-bva0dy24yyd67697) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[17 Jun 2010 12:41]
Bugs System
Pushed into 5.1.47-ndb-6.2.19 (revid:martin.skold@mysql.com-20100617115448-idrbic6gbki37h1c) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[17 Jun 2010 13:28]
Bugs System
Pushed into 5.1.47-ndb-6.3.35 (revid:martin.skold@mysql.com-20100617114611-61aqbb52j752y116) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)