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()
parent f5ecaf23
...@@ -182,3 +182,32 @@ CREATE TABLE t (i INT) ENGINE=InnoDB PARTITION BY HASH (i) PARTITIONS 2; ...@@ -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 (0);
INSERT INTO t VALUES (1),(0),(1); INSERT INTO t VALUES (1),(0),(1);
DROP TABLE t; 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;
...@@ -193,3 +193,31 @@ CREATE TABLE t (i INT) ENGINE=InnoDB PARTITION BY HASH (i) PARTITIONS 2; ...@@ -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 (0);
INSERT INTO t VALUES (1),(0),(1); INSERT INTO t VALUES (1),(0),(1);
DROP TABLE t; 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;
...@@ -4547,6 +4547,10 @@ innobase_commit( ...@@ -4547,6 +4547,10 @@ innobase_commit(
SQL statement */ SQL statement */
trx_mark_sql_stat_end(trx); 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 */ /* Reset the number AUTO-INC rows required */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment