Bug #28781 | InnoDB increments auto-increment value incorrectly with ON DUPLICATE KEY UPDATE | ||
---|---|---|---|
Submitted: | 30 May 2007 17:24 | Modified: | 18 Jun 2010 1:32 |
Reporter: | Todd Farmer (OCA) | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Documentation | Severity: | S2 (Serious) |
Version: | 5.0.42 | OS: | Any |
Assigned to: | Paul DuBois | CPU Architecture: | Any |
Tags: | autoincrement replication, bfsm_2007_06_21 |
[30 May 2007 17:24]
Todd Farmer
[1 Jun 2007 13:23]
Heikki Tuuri
Hmm... quite complex usage: auto-inc and ON DUPLICATE KEY UPDATE.
[7 Jun 2007 14:00]
Heikki Tuuri
Assigning this complex bug to Inaam. I do not even know what ON DUPLICATE KEY UPDATE does! --Heikki
[21 Jun 2007 11:34]
Heikki Tuuri
Sunny sent a patch for this on June 13.
[21 Jul 2007 6:02]
Alan Tam
Where can I access the patch? I've been facing this problem since upgrading to 5.0.42, while 5.0.40 has even more "ON DUPLICATE KEY UPDATE" bugs!
[26 Jul 2007 5:08]
Alan Tam
Hello? Is there anyone who has got the patch?
[26 Jul 2007 5:13]
Todd Farmer
The patch is being merged to the current 5.0 tree and should be available shortly. When the patch is ready, it will be noted in this bug report.
[8 Aug 2007 5:17]
Alan Tam
From my experience dealing with MySQL patches, one developer will first check-in the patch into his/her own repository and then push it to the central bk tree. If this is the case, at least I can look at the patch and patch my own system at my own will. But somehow now I have to left my production data without backup (since all slaves are down) for over a month, because I don't have access to the patch.
[8 Aug 2007 5:26]
Inaam Rana
patch for 5.0
Attachment: 28781.patch (text/x-diff), 1.56 KiB.
[16 Aug 2007 0:54]
Timothy Smith
Queued to 5.0-maint
[20 Aug 2007 10:04]
Bugs System
Pushed into 5.0.48
[20 Aug 2007 10:20]
Bugs System
Pushed into 5.1.22-beta
[24 Aug 2007 9:36]
Jon Stephens
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release. If necessary, you can access the source repository and build the latest available version, including the bug fix. More information about accessing the source trees is available at http://dev.mysql.com/doc/en/installing-source.html Documented bugfix in 5.0.48 and 5.1.22 changelogs.
[4 Sep 2007 17:11]
Bugs System
Pushed into 5.1.23-beta
[7 Dec 2007 12:35]
Susanne Ebrecht
Bug #33025 is set as duplicate of this bug here.
[9 Jan 2008 18:58]
Sveta Smirnova
Bug still exists in current 5.1.23 and 6.0 BK sources. See also bug #24432
[10 Jan 2008 18:31]
Inaam Rana
This is working as designed. The autoinc increment behaviour depends on the value of innodb_autoinc_lock_mode which is documented here http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html User can fall back to old behaviour (i.e.: no gaps) by setting the value of innodb_autoinc_lock_mode = 0. But this means old locking mechanism. For any non zero value of the parameter the performance and scalability is much better but gaps can potentially occur. Perhaps we need to update the documentation to state this fact more explicitly. I have attached results with both values of innodb_autoinc_lock_mode to explain the difference in behaviour. regards, inaam
[10 Jan 2008 18:32]
Inaam Rana
autoinc behaviour with different values of innodb_autoinc_lock_mode
Attachment: autoinc.out (application/octet-stream, text), 4.42 KiB.
[15 Jan 2008 5:19]
Inaam Rana
I am closing this down as 'not a bug'. The behaviour of auto_increment can be controlled through the config parameter (as mentioned earlier) and the gaps in the autoinc values are expected. I'll make sure that we add more to the documentation to clarify this point. regards, inaam
[15 Jan 2008 22:46]
Todd Farmer
I'm changing this status to "Documenting" as this is most assuredly a bug (which is fixed) in 5.0. The reports of it not being fixed in 5.1 may be related to the need provide further documentation of the new innodb_autoinc_lock_mode parameter introduced in 5.1.
[27 Feb 2008 13:31]
Paul DuBois
This turns out to be a documentation problem. INSERT ... ON DUPLICATE KEY UPDATE is a mixed-mode insert, not a simple insert, and thus is subject to the exception described in the docs for "consecutive" lock mode that render it unsafe for statement-based replication. Oracle is providing the corrections to the docs. Reclassifying this report as a documentation bug and assigning to myself.
[27 Feb 2008 13:42]
Paul DuBois
Thank you for your bug report. This issue has been addressed in the documentation. The updated documentation will appear on our website shortly, and will be included in the next release of the relevant products. Changes to documentation: - INSERT ... ON DUPLICATE KEY UPDATE is a mixed-mode insert, not a simple insert. - Modified the description for innodb_autoinc_lock_mode = 1 ("consecutive" mode) as follows (note especially the last para, which is new): "Simply put, the important impact of this lock mode is significantly better scalability. This mode is safe for use with statement-based replication. Further, as with “traditional” lock mode, auto-increment numbers assigned by any given statement are consecutive. In this mode, there is no change in semantics compared to “traditional” mode for any statement that uses auto-increment, with one important exception. [add "important", remove the word "minor"] The exception is for “mixed-mode inserts”, where the user provides explicit values for an AUTO_INCREMENT column for some, but not all, rows in a multiple-row “simple insert.” For such inserts, InnoDB will allocate more auto-increment values than the number of rows to be inserted. However, all values automatically assigned are consecutively generated (and thus higher than) the auto-increment value generated by the most recently executed previous statement. “Excess” numbers are lost. A similar situation exists if you use ON DUPLICATE KEY UPDATE ... in the INSERT statement which is also classified as a "mixed-mode insert". Because InnoDB allocates the autoincrement value before the insert is actually attempted, it cannot know whether an inserted value will be a duplicate of an existing value and thus cannot know if the autoincrement value it generates will be used for a new row or not. Therefore, if you are using statement-based replication, you must avoid ON DUPLICATE KEY UPDATE or use innodb_autoinc_lock_mode = 0 (“traditional” lock mode)."
[9 Mar 2009 4:48]
Roel Van de Paar
Notice bug #41263 which looks very similar.
[23 Mar 2009 15:23]
Susanne Ebrecht
Bug #41263 was set as duplicate of this bug here
[5 May 2010 15:13]
Bugs System
Pushed into 5.1.47 (revid:joro@sun.com-20100505145753-ivlt4hclbrjy8eye) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[6 May 2010 2:58]
Paul DuBois
Push resulted from incorporation of InnoDB tree. No changes pertinent to this bug. Re-closing.
[28 May 2010 6:10]
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:38]
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 7:06]
Bugs System
Pushed into 5.5.5-m3 (revid:alik@sun.com-20100524185725-c8k5q7v60i5nix3t) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[29 May 2010 2:30]
Paul DuBois
Push resulted from incorporation of InnoDB tree. No changes pertinent to this bug. Re-closing.
[17 Jun 2010 12:15]
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 13:02]
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:43]
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)
[6 Sep 2010 15:45]
Mark Callaghan
The default values for MySQL 5.1 reproduce this bug: binlog_format --> STATEMENT innodb_autoinc_lock_mode --> 1 As this bug indicates, many users encounter this problem. Why was this done? Are we expected to read every page of the manual to determine whether it is safe to upgrade to the next MySQL release? Change the InnoDB plugin to use innodb_autoinc_lock_mode=0 as the default value. Log an error message somewhere when the server is run in an unsafe mode. The error log has been spammed for other statements that are deemed unsafe for SBR yet nothing is done in this case.
[10 Sep 2010 8:15]
Andrei Elkin
Mark, per our analysis it's actually replication-safe to mix the two binlog_format --> STATEMENT innodb_autoinc_lock_mode --> 1 The gap due to mode=1 should not make SBR failing anymore after the current bug fixes.
[10 Sep 2010 16:40]
Mark Callaghan
From my understanding of the code I also think it is safe. The comment in the docs scared me though.
[25 Nov 2012 19:56]
Mikhail Gavrilov
Why this bug still not fixed?
[26 Nov 2012 21:22]
James Day
Mikhail, it's not a bug. If you don't want gaps in the autoincrement sequence just set innodb_autoinc_lock_mode = 0. Then you'll get the old way with more contiguous values but more locking that will slow things down, as it did before. We added the different lock modes because autoincrement locking was a common performance problem. But we knew that some applications would want the contiguous values, so we provided the option for those who want that more than they want more speed. Just pick which way you want and set the variable. James Day, MySQL Senior Principal Support Engineer, Oracle
[27 Nov 2012 2:22]
Mikhail Gavrilov
Thanks, James. Yes, I am know about "innodb_autoinc_lock_mode = 0" parameter, but I am hear this is bad for database performance. I am don't understand why so heavy to makes unique index checking before applying "insert ... on duplicate key ..." SQL statement. And not increment auto increment fields if index check failed. Example: create table t1 (a int primary key auto_increment, b int unique, c varchar(20)) engine=innodb; insert t1 (b) values (10),(20),(30); insert t1 (b) values (20) on duplicate key update c='!'; insert t1 (b) values (40); select * from t1;
[27 Nov 2012 9:02]
James Day
Yes, 0 is bad for performance for workloads that do a lot of inserting. It is why we introduced the other values and don't have 0 as the default. But just try it. If you see lots of transactions waiting for autoincrement locks, it's a problem for you. If you don't then it may just be a small speed penalty. Why not wait to allocate the value after checking all of the unique indexes? The server could do that, but would it be too pessimistic? If you think that there will be a duplicate, you should update instead of inserting. Then do an insert if the update fails. So INSERT ... ON DUPLICATE KEY UPDATE is for the case where it is expected that there will not be a duplicate and it is optimistic about that, assuming that will be true. I assume that changing the internal order of index checking was too complicated.
[29 Nov 2012 20:58]
Mikhail Gavrilov
Another example: CREATE TABLE t1 (a INT PRIMARY KEY AUTO_INCREMENT, b INT UNIQUE, c VARCHAR(20)) ENGINE=INNODB; INSERT t1 (b) VALUES (10),(20),(30); INSERT t1 (b) VALUES (20) ON DUPLICATE KEY UPDATE c='!'; INSERT t1 (b) VALUES (40); SELECT * FROM t1; INSERT t1 (a) VALUES (5) ON DUPLICATE KEY UPDATE c='!'; INSERT t1 (b) VALUES (50); SELECT * FROM t1; Describe that PRIMARY KEY not have this issue. This means the check PRIMARY KEY before AUTO INCREMENT worked. Why can't do the same thing for UNIQUE KEY's?