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 14:52:42 +0530
commitd6e3cd6f233730e168624441d4025de5ce83affd (patch)
tree55aab55bc754eca7f6698114285e595052849dbf
parentf5ecaf232e06392e91ba2fd914d69386059f02a5 (diff)
downloadmariadb-git-d6e3cd6f233730e168624441d4025de5ce83affd.tar.gz
MDEV-26947 UNIQUE column checks fail in InnoDB resulting in table corruption
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.result29
-rw-r--r--mysql-test/suite/innodb/t/insert_into_empty.test28
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
3 files changed, 61 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..2eb6f5d4d0a 100644
--- a/mysql-test/suite/innodb/r/insert_into_empty.result
+++ b/mysql-test/suite/innodb/r/insert_into_empty.result
@@ -182,3 +182,32 @@ 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
+#
+CREATE TABLE t (c1 INT KEY,c2 INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+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
+COMMIT;
+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;
+CREATE TABLE t (c INT PRIMARY KEY,c2 CHAR(1) UNIQUE)ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t VALUES(1, ''),(2, '');
+ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
+SELECT * FROM t;
+c c2
+DELETE FROM t;
+COMMIT;
+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..cfd79f05f6c 100644
--- a/mysql-test/suite/innodb/t/insert_into_empty.test
+++ b/mysql-test/suite/innodb/t/insert_into_empty.test
@@ -193,3 +193,31 @@ 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 #
+
+CREATE TABLE t (c1 INT KEY,c2 INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+--error ER_ERROR_DURING_COMMIT
+INSERT INTO t VALUES (1,0),(2,0);
+CHECK TABLE t;
+COMMIT;
+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;
+
+CREATE TABLE t (c INT PRIMARY KEY,c2 CHAR(1) UNIQUE)ENGINE=InnoDB;
+BEGIN;
+--error ER_ERROR_DURING_COMMIT
+INSERT INTO t VALUES(1, ''),(2, '');
+SELECT * FROM t;
+DELETE FROM t;
+COMMIT;
+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 */