Ok to push.

On Mon, Nov 30, 2015 at 6:45 PM, <serg@mariadb.org> wrote:
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