revision-id: be25be4b1aaf65593d67498c2f30a99fd254ea15 (mariadb-10.1.8-71-gbe25be4)
parent(s): cf8cb9ebd810a46154f99a73045b53a6913b6eb6
committer: Sergei Golubchik
timestamp: 2015-11-30 17:45:23 +0100
message:
MDEV-8827 Duplicate key with auto increment
fix innodb auto-increment handling
three bugs:
1. innobase_next_autoinc treated the case of current<offset incorrectly
2. ha_innobase::get_auto_increment didn't recalculate current when increment changed
3. ha_innobase::get_auto_increment didn't pass offset down to innobase_next_autoinc
---
mysql-test/suite/innodb/r/innodb-autoinc.result | 16 ++++++++++++++--
mysql-test/suite/innodb/t/innodb-autoinc.test | 3 ++-
storage/innobase/handler/ha_innodb.cc | 16 +++++++---------
storage/xtradb/handler/ha_innodb.cc | 16 +++++++---------
4 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result
index 6ac8bb5..ddca468 100644
--- a/mysql-test/suite/innodb/r/innodb-autoinc.result
+++ b/mysql-test/suite/innodb/r/innodb-autoinc.result
@@ -567,7 +567,7 @@ Variable_name Value
auto_increment_increment 65535
auto_increment_offset 65535
INSERT INTO t1 VALUES (NULL),(NULL);
-ERROR 22003: Out of range value for column 'c1' at row 1
+ERROR HY000: Failed to read auto-increment value from storage engine
SELECT * FROM t1;
c1
1
@@ -641,6 +641,18 @@ PRIMARY KEY (m)) ENGINE = InnoDB;
INSERT INTO t2 (n,o) VALUES
(1 , 'true'), (1 , 'false'), (2 , 'true'), (2 , 'false'), (3 , 'true'),
(3 , 'false'), (4 , 'true'), (4 , 'false'), (5 , 'true'), (5 , 'false');
+SELECT * FROM t2;
+m n o
+1 1 TRUE
+2 1 FALSE
+3 2 TRUE
+4 2 FALSE
+5 3 TRUE
+6 3 FALSE
+7 4 TRUE
+8 4 FALSE
+9 5 TRUE
+10 5 FALSE
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
@@ -648,7 +660,7 @@ t2 CREATE TABLE `t2` (
`n` int(10) unsigned NOT NULL,
`o` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`m`)
-) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=latin1
+) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SHOW CREATE TABLE t1;
Table Create Table
diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test
index ab708e8..dd4c4ae 100644
--- a/mysql-test/suite/innodb/t/innodb-autoinc.test
+++ b/mysql-test/suite/innodb/t/innodb-autoinc.test
@@ -349,7 +349,7 @@ INSERT INTO t1 VALUES (18446744073709551610); #-- 2^64 - 2
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
SHOW VARIABLES LIKE "auto_inc%";
---error 167
+--error 1467
INSERT INTO t1 VALUES (NULL),(NULL);
SELECT * FROM t1;
DROP TABLE t1;
@@ -401,6 +401,7 @@ CREATE TABLE t2 (
INSERT INTO t2 (n,o) VALUES
(1 , 'true'), (1 , 'false'), (2 , 'true'), (2 , 'false'), (3 , 'true'),
(3 , 'false'), (4 , 'true'), (4 , 'false'), (5 , 'true'), (5 , 'false');
+SELECT * FROM t2;
SHOW CREATE TABLE t2;
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SHOW CREATE TABLE t1;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index daa649a..bf86071 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -2283,10 +2283,11 @@ innobase_next_autoinc(
if (next_value == 0) {
ulonglong next;
- if (current > offset) {
+ if (current >= offset) {
next = (current - offset) / step;
} else {
- next = (offset - current) / step;
+ next = 0;
+ block -= step;
}
ut_a(max_value > next);
@@ -15542,10 +15543,7 @@ ha_innobase::get_auto_increment(
current = *first_value;
- /* If the increment step of the auto increment column
- decreases then it is not affecting the immediate
- next value in the series. */
- if (prebuilt->autoinc_increment > increment) {
+ if (prebuilt->autoinc_increment != increment) {
WSREP_DEBUG("autoinc decrease: %llu -> %llu\n"
"THD: %ld, current: %llu, autoinc: %llu",
@@ -15553,13 +15551,13 @@ ha_innobase::get_auto_increment(
increment,
thd_get_thread_id(ha_thd()),
current, autoinc);
- if (!wsrep_on(ha_thd()))
+ if (!wsrep_auto_increment_control || !wsrep_on(ha_thd()))
{
- current = autoinc - prebuilt->autoinc_increment;
+ current = autoinc - prebuilt->autoinc_increment;
}
current = innobase_next_autoinc(
- current, 1, increment, 1, col_max_value);
+ current, 1, increment, offset, col_max_value);
dict_table_autoinc_initialize(prebuilt->table, current);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 4aa5457..6659989 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -2556,10 +2556,11 @@ innobase_next_autoinc(
if (next_value == 0) {
ulonglong next;
- if (current > offset) {
+ if (current >= offset) {
next = (current - offset) / step;
} else {
- next = (offset - current) / step;
+ next = 0;
+ block -= step;
}
ut_a(max_value > next);
@@ -16178,10 +16179,7 @@ ha_innobase::get_auto_increment(
current = *first_value;
- /* If the increment step of the auto increment column
- decreases then it is not affecting the immediate
- next value in the series. */
- if (prebuilt->autoinc_increment > increment) {
+ if (prebuilt->autoinc_increment != increment) {
WSREP_DEBUG("autoinc decrease: %llu -> %llu\n"
"THD: %ld, current: %llu, autoinc: %llu",
@@ -16189,13 +16187,13 @@ ha_innobase::get_auto_increment(
increment,
thd_get_thread_id(ha_thd()),
current, autoinc);
- if (!wsrep_on(ha_thd()))
+ if (!wsrep_auto_increment_control || !wsrep_on(ha_thd()))
{
- current = autoinc - prebuilt->autoinc_increment;
+ current = autoinc - prebuilt->autoinc_increment;
}
current = innobase_next_autoinc(
- current, 1, increment, 1, col_max_value);
+ current, 1, increment, offset, col_max_value);
dict_table_autoinc_initialize(prebuilt->table, current);
_______________________________________________
commits mailing list
commits@mariadb.org
https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits