Commit fef8e27a authored by Timothy Smith's avatar Timothy Smith

Apply InnoDB snapshot innodb-5.1-ss2637, part 2. Fixes

Bug #38839: auto increment does not work properly with InnoDB after update


Detailed revision comments:

r2609 | sunny | 2008-08-24 01:19:05 +0300 (Sun, 24 Aug 2008) | 12 lines
branches/5.1: Fix for MySQL Bug#38839. Reset the statement level last
value field in prebuilt. This field tracks the last value in an autoincrement
interval. We use this value to check whether we need to update a table's
AUTOINC counter, if the value written to a table is less than this value
then we avoid updating the table's AUTOINC value in order to reduce
mutex contention. If it's not reset (e.g., after a DELETE statement) then
there is the possibility of missing updates to the table's AUTOINC counter
resulting in a subsequent duplicate row error message under certain 
conditions (see the test case for details).

Bug #38839 - auto increment does not work properly with InnoDB after update
parent 8b0a676e
...@@ -169,3 +169,30 @@ t1 CREATE TABLE `t1` ( ...@@ -169,3 +169,30 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`c1`) PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1);
INSERT INTO t1 VALUES (NULL,8);
SELECT * FROM t1;
c1 c2
2 1
3 8
DROP TABLE t1;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1), (NULL, 8);
INSERT INTO t1 VALUES (NULL,9);
SELECT * FROM t1;
c1 c2
2 1
3 8
5 9
DROP TABLE t1;
...@@ -139,3 +139,24 @@ SELECT c1 FROM t1; ...@@ -139,3 +139,24 @@ SELECT c1 FROM t1;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug 38839
# Reset the last value generated at end of statement
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1);
INSERT INTO t1 VALUES (NULL,8);
SELECT * FROM t1;
DROP TABLE t1;
# Bug 38839 -- same as above but for multi value insert
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, 1);
DELETE FROM t1 WHERE c1 = 1;
INSERT INTO t1 VALUES (2,1), (NULL, 8);
INSERT INTO t1 VALUES (NULL,9);
SELECT * FROM t1;
DROP TABLE t1;
...@@ -6429,15 +6429,26 @@ ha_innobase::extra( ...@@ -6429,15 +6429,26 @@ ha_innobase::extra(
return(0); return(0);
} }
/**********************************************************************
Reset state of file to after 'open'.
This function is called after every statement for all tables used
by that statement. */
int ha_innobase::reset() int ha_innobase::reset()
{ {
if (prebuilt->blob_heap) { if (prebuilt->blob_heap) {
row_mysql_prebuilt_free_blob_heap(prebuilt); row_mysql_prebuilt_free_blob_heap(prebuilt);
} }
reset_template(prebuilt); reset_template(prebuilt);
return 0;
}
/* TODO: This should really be reset in reset_template() but for now
it's safer to do it explicitly here. */
/* This is a statement level counter. */
prebuilt->last_value = 0;
return(0);
}
/********************************************************************** /**********************************************************************
MySQL calls this function at the start of each SQL statement inside LOCK MySQL calls this function at the start of each SQL statement inside LOCK
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment