summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2021-11-01 13:49:57 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2021-11-01 13:49:57 +0530
commitf6bf152b5a98ad6231024879fd98a882c80148d5 (patch)
tree350cfd3f00306a0caae11b9380b6fd355eb184c3
parentf5ecaf232e06392e91ba2fd914d69386059f02a5 (diff)
downloadmariadb-git-bb-10.7-MDEV-26497.tar.gz
MDEV-26947 UNIQUE column checks fail in InnoDB resulting in table corruptionbb-10.7-MDEV-26497
InnoDB fails to rollback the bulk insert buffered operation when trx_mark_sql_stat_end() encounters the DB_DUPLICATE_KEY error. In this case, check table fails with secondary index row count mismatch. InnoDB gives the error "ER_ERROR_DURING_COMMIT" while encountering the DB_DUPLICATE_KEY in trx_mark_sql_stat_end()
-rw-r--r--mysql-test/suite/innodb/r/insert_into_empty.result27
-rw-r--r--mysql-test/suite/innodb/t/insert_into_empty.test26
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
3 files changed, 57 insertions, 0 deletions
diff --git a/mysql-test/suite/innodb/r/insert_into_empty.result b/mysql-test/suite/innodb/r/insert_into_empty.result
index b35b508fa7f..a1258c18434 100644
--- a/mysql-test/suite/innodb/r/insert_into_empty.result
+++ b/mysql-test/suite/innodb/r/insert_into_empty.result
@@ -182,3 +182,30 @@ CREATE TABLE t (i INT) ENGINE=InnoDB PARTITION BY HASH (i) PARTITIONS 2;
INSERT INTO t VALUES (0);
INSERT INTO t VALUES (1),(0),(1);
DROP TABLE t;
+#
+# MDEV-26947 UNIQUE column checks fail in InnoDB resulting
+# in table corruption
+#
+SET autocommit=0,foreign_key_checks=0,unique_checks=0;
+CREATE TABLE t (c1 INT KEY,c2 INT,UNIQUE (c2)) ENGINE=InnoDB;
+INSERT INTO t VALUES (1,0),(2,0);
+ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
+CHECK TABLE t;
+Table Op Msg_type Msg_text
+test.t check status OK
+DROP TABLE t;
+CREATE TABLE t (i INT UNIQUE)engine=innodb;
+INSERT INTO t VALUES (0),(0);
+ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
+CHECK TABLE t;
+Table Op Msg_type Msg_text
+test.t check status OK
+DROP TABLE t;
+SET sql_mode='';
+CREATE TABLE t (c INT AUTO_INCREMENT KEY,c2 CHAR(1) NOT NULL,UNIQUE INDEX uc2 (c2))engine=innodb;
+INSERT INTO t VALUES(),();
+ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
+SELECT * FROM t;
+c c2
+DELETE FROM t;
+DROP TABLE t;
diff --git a/mysql-test/suite/innodb/t/insert_into_empty.test b/mysql-test/suite/innodb/t/insert_into_empty.test
index 8b885cb5b4f..e6f967f2acd 100644
--- a/mysql-test/suite/innodb/t/insert_into_empty.test
+++ b/mysql-test/suite/innodb/t/insert_into_empty.test
@@ -193,3 +193,29 @@ CREATE TABLE t (i INT) ENGINE=InnoDB PARTITION BY HASH (i) PARTITIONS 2;
INSERT INTO t VALUES (0);
INSERT INTO t VALUES (1),(0),(1);
DROP TABLE t;
+
+--echo #
+--echo # MDEV-26947 UNIQUE column checks fail in InnoDB resulting
+--echo # in table corruption
+--echo #
+
+SET autocommit=0,foreign_key_checks=0,unique_checks=0;
+CREATE TABLE t (c1 INT KEY,c2 INT,UNIQUE (c2)) ENGINE=InnoDB;
+--error ER_ERROR_DURING_COMMIT
+INSERT INTO t VALUES (1,0),(2,0);
+CHECK TABLE t;
+DROP TABLE t;
+
+CREATE TABLE t (i INT UNIQUE)engine=innodb;
+--error ER_ERROR_DURING_COMMIT
+INSERT INTO t VALUES (0),(0);
+CHECK TABLE t;
+DROP TABLE t;
+
+SET sql_mode='';
+CREATE TABLE t (c INT AUTO_INCREMENT KEY,c2 CHAR(1) NOT NULL,UNIQUE INDEX uc2 (c2))engine=innodb;
+--error ER_ERROR_DURING_COMMIT
+INSERT INTO t VALUES(),();
+SELECT * FROM t;
+DELETE FROM t;
+DROP TABLE t;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 948e7406af4..e9679adb7d5 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4547,6 +4547,10 @@ innobase_commit(
SQL statement */
trx_mark_sql_stat_end(trx);
+ if (UNIV_UNLIKELY(trx->error_state != DB_SUCCESS)) {
+ trx_rollback_for_mysql(trx);
+ DBUG_RETURN(1);
+ }
}
/* Reset the number AUTO-INC rows required */