mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
Fixed bug #27650:
INSERT into InnoDB table may cause "ERROR 1062 (23000): Duplicate entry..." errors or lost records after multi-row INSERT of the form: "INSERT INTO t (id...) VALUES (NULL...) ON DUPLICATE KEY UPDATE id=VALUES(id)", where "id" is an AUTO_INCREMENT column. It happens because InnoDB handler forgets to save next insert id after updating of auto_increment column with new values. As result of that last insert id stored inside InnoDB dictionary tables differs from it's cached thd->next_insert_id value.
This commit is contained in:
parent
b77a85ef22
commit
5983038a66
3 changed files with 88 additions and 0 deletions
|
@ -446,4 +446,43 @@ a
|
||||||
2
|
2
|
||||||
5
|
5
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1(
|
||||||
|
id int auto_increment,
|
||||||
|
c char(1) not null,
|
||||||
|
counter int not null default 1,
|
||||||
|
primary key (id),
|
||||||
|
unique key (c)
|
||||||
|
) engine=innodb;
|
||||||
|
insert into t1 (id, c) values
|
||||||
|
(NULL, 'a'),
|
||||||
|
(NULL, 'a')
|
||||||
|
on duplicate key update id = values(id), counter = counter + 1;
|
||||||
|
select * from t1;
|
||||||
|
id c counter
|
||||||
|
2 a 2
|
||||||
|
insert into t1 (id, c) values
|
||||||
|
(NULL, 'b')
|
||||||
|
on duplicate key update id = values(id), counter = counter + 1;
|
||||||
|
select * from t1;
|
||||||
|
id c counter
|
||||||
|
2 a 2
|
||||||
|
3 b 1
|
||||||
|
truncate table t1;
|
||||||
|
insert into t1 (id, c) values (NULL, 'a');
|
||||||
|
select * from t1;
|
||||||
|
id c counter
|
||||||
|
1 a 1
|
||||||
|
insert into t1 (id, c) values (NULL, 'b'), (NULL, 'b')
|
||||||
|
on duplicate key update id = values(id), c = values(c), counter = counter + 1;
|
||||||
|
select * from t1;
|
||||||
|
id c counter
|
||||||
|
1 a 1
|
||||||
|
3 b 2
|
||||||
|
insert into t1 (id, c) values (NULL, 'a')
|
||||||
|
on duplicate key update id = values(id), c = values(c), counter = counter + 1;
|
||||||
|
select * from t1;
|
||||||
|
id c counter
|
||||||
|
3 b 2
|
||||||
|
4 a 2
|
||||||
|
drop table t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
|
|
@ -412,4 +412,51 @@ DROP TABLE t1;
|
||||||
|
|
||||||
--source include/innodb_rollback_on_timeout.inc
|
--source include/innodb_rollback_on_timeout.inc
|
||||||
|
|
||||||
|
|
||||||
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27650: INSERT fails after multi-row INSERT of the form:
|
||||||
|
# INSERT INTO t (id...) VALUES (NULL...) ON DUPLICATE KEY UPDATE id=VALUES(id)
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1(
|
||||||
|
id int auto_increment,
|
||||||
|
c char(1) not null,
|
||||||
|
counter int not null default 1,
|
||||||
|
primary key (id),
|
||||||
|
unique key (c)
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
insert into t1 (id, c) values
|
||||||
|
(NULL, 'a'),
|
||||||
|
(NULL, 'a')
|
||||||
|
on duplicate key update id = values(id), counter = counter + 1;
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
insert into t1 (id, c) values
|
||||||
|
(NULL, 'b')
|
||||||
|
on duplicate key update id = values(id), counter = counter + 1;
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
truncate table t1;
|
||||||
|
|
||||||
|
insert into t1 (id, c) values (NULL, 'a');
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
insert into t1 (id, c) values (NULL, 'b'), (NULL, 'b')
|
||||||
|
on duplicate key update id = values(id), c = values(c), counter = counter + 1;
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
insert into t1 (id, c) values (NULL, 'a')
|
||||||
|
on duplicate key update id = values(id), c = values(c), counter = counter + 1;
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
|
@ -3299,6 +3299,8 @@ no_commit:
|
||||||
if (error == DB_DUPLICATE_KEY && auto_inc_used
|
if (error == DB_DUPLICATE_KEY && auto_inc_used
|
||||||
&& (user_thd->lex->sql_command == SQLCOM_REPLACE
|
&& (user_thd->lex->sql_command == SQLCOM_REPLACE
|
||||||
|| user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT
|
|| user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT
|
||||||
|
|| (user_thd->lex->sql_command == SQLCOM_INSERT
|
||||||
|
&& user_thd->lex->duplicates == DUP_UPDATE)
|
||||||
|| (user_thd->lex->sql_command == SQLCOM_LOAD
|
|| (user_thd->lex->sql_command == SQLCOM_LOAD
|
||||||
&& user_thd->lex->duplicates == DUP_REPLACE))) {
|
&& user_thd->lex->duplicates == DUP_REPLACE))) {
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue