diff options
author | gkodinov@mysql.com <> | 2006-06-13 18:18:32 +0300 |
---|---|---|
committer | gkodinov@mysql.com <> | 2006-06-13 18:18:32 +0300 |
commit | 8d94b8cacf10eb89f407ff4c2311794431ad39d5 (patch) | |
tree | 28c57dae5731b5f0ca9e5d47a0d941264f195dd0 | |
parent | c9bb9413abd01fc28a96a0d5e1636d2beb517556 (diff) | |
download | mariadb-git-8d94b8cacf10eb89f407ff4c2311794431ad39d5.tar.gz |
Bug #20195: INSERT DELAYED with auto_increment is assigned wrong values
The INSERT DELAYED should not maintain its own private auto-increment
counter, because this is assuming that other threads cannot insert
into the table while the INSERT DELAYED thread is inserting, which is
a wrong assumption.
So the start of processing of a batch of INSERT rows in the
INSERT DELAYED thread must be treated as a start of a new statement
and cached next_insert_id must be cleared.
-rw-r--r-- | mysql-test/r/delayed.result | 30 | ||||
-rw-r--r-- | mysql-test/t/delayed.test | 49 | ||||
-rw-r--r-- | sql/sql_insert.cc | 8 |
3 files changed, 87 insertions, 0 deletions
diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result index f8ae61b03fb..a336f3b4108 100644 --- a/mysql-test/r/delayed.result +++ b/mysql-test/r/delayed.result @@ -39,3 +39,33 @@ select * from t1; a 1 drop table t1; +CREATE TABLE t1 ( a int(10) NOT NULL auto_increment, PRIMARY KEY (a)); +insert delayed into t1 values(null); +insert into t1 values(null); +insert into t1 values(null); +insert delayed into t1 values(null); +insert delayed into t1 values(null); +insert delayed into t1 values(null); +insert into t1 values(null); +insert into t1 values(null); +insert into t1 values(null); +delete from t1 where a=6; +insert delayed into t1 values(null); +insert delayed into t1 values(null); +insert delayed into t1 values(null); +insert delayed into t1 values(null); +select * from t1 order by a; +a +1 +2 +3 +4 +5 +7 +8 +9 +10 +11 +12 +13 +DROP TABLE t1; diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test index 5ae757b1fde..55e8f81f763 100644 --- a/mysql-test/t/delayed.test +++ b/mysql-test/t/delayed.test @@ -50,3 +50,52 @@ insert into t1 values (1); insert delayed into t1 values (1); select * from t1; drop table t1; + +# +# Bug #20195: INSERT DELAYED with auto_increment is assigned wrong values +# +CREATE TABLE t1 ( a int(10) NOT NULL auto_increment, PRIMARY KEY (a)); + +# Make one delayed insert to start the separate thread +insert delayed into t1 values(null); + +# Do some normal inserts +insert into t1 values(null); +insert into t1 values(null); + +# Discarded, since the delayed-counter is 2, which is already used +insert delayed into t1 values(null); + +# Discarded, since the delayed-counter is 3, which is already used +insert delayed into t1 values(null); + +# Works, since the delayed-counter is 4, which is unused +insert delayed into t1 values(null); + +# Do some more inserts +insert into t1 values(null); +insert into t1 values(null); +insert into t1 values(null); + +# Delete one of the above to make a hole +delete from t1 where a=6; + +# Discarded, since the delayed-counter is 5, which is already used +insert delayed into t1 values(null); + +# Works, since the delayed-counter is 6, which is unused (the row we deleted) +insert delayed into t1 values(null); + +# Discarded, since the delayed-counter is 7, which is already used +insert delayed into t1 values(null); + +# Works, since the delayed-counter is 8, which is unused +insert delayed into t1 values(null); + +# Check what we have now +# must wait so that the delayed thread finishes +# Note: this must be increased if the test fails +--sleep 1 +select * from t1 order by a; + +DROP TABLE t1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 26f3b6f5faa..5630702fe52 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1938,6 +1938,14 @@ bool delayed_insert::handle_inserts(void) if (!using_bin_log) table->file->extra(HA_EXTRA_WRITE_CACHE); pthread_mutex_lock(&mutex); + + /* Reset auto-increment cacheing */ + if (thd.clear_next_insert_id) + { + thd.next_insert_id= 0; + thd.clear_next_insert_id= 0; + } + while ((row=rows.get())) { stacked_inserts--; |