mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-29761 Bulk insert fails to rollback during insert..select
- InnoDB should do partial rollback when error happens during buffered bulk insert write operation.
This commit is contained in:
@@ -314,3 +314,45 @@ PARTITION pn VALUES LESS THAN (20));
|
||||
INSERT INTO t1 VALUES (1),(21);
|
||||
ERROR HY000: Table has no partition for value 21
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-29761 Bulk insert fails to rollback
|
||||
# during insert..select
|
||||
#
|
||||
CREATE TABLE t1 (f1 INT)ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (f1 INT, UNIQUE INDEX(f1)) ENGINE=InnoDB;
|
||||
CREATE TRIGGER tr AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES(1);
|
||||
BEGIN;
|
||||
INSERT t1 SELECT 1 FROM seq_1_to_2;
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
f1
|
||||
SELECT * FROM t2;
|
||||
f1
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
CHECK TABLE t2;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t2 check status OK
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# MDEV-29801 Inconsistent ER_TOO_BIG_ROWSIZE during bulk
|
||||
# insert operation
|
||||
#
|
||||
call mtr.add_suppression("InnoDB: Cannot add field `c11` in table");
|
||||
SET @format= @@innodb_default_row_format;
|
||||
CREATE TABLE t1 (pk int primary key, c01 text, c02 text, c03 text,
|
||||
c04 text, c05 text, c06 text, c07 text, c08 text,
|
||||
c09 text, c10 text, c11 text, c12 text) ENGINE=InnoDB;
|
||||
SET GLOBAL INNODB_DEFAULT_ROW_FORMAT= COMPACT;
|
||||
ALTER TABLE t1 FORCE;
|
||||
Warnings:
|
||||
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
INSERT IGNORE INTO t1 VALUES
|
||||
(1, REPEAT('x',4805), REPEAT('t',2211), REPEAT('u',974), REPEAT('e',871), REPEAT('z',224), REPEAT('j',978), REPEAT('n',190), REPEAT('t',888), REPEAT('x',32768), REPEAT('e',968), REPEAT('b',913), REPEAT('x',12107)),
|
||||
(2, REPEAT('x',4805), REPEAT('t',2211), REPEAT('u',974), REPEAT('e',871), REPEAT('z',224), REPEAT('j',978), REPEAT('n',190), REPEAT('t',888), REPEAT('x',32768), REPEAT('e',968), REPEAT('b',913), REPEAT('x',12107));
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL INNODB_DEFAULT_ROW_FORMAT= @format;
|
||||
|
@@ -327,3 +327,38 @@ CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB
|
||||
INSERT INTO t1 VALUES (1),(21);
|
||||
# Cleanup
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-29761 Bulk insert fails to rollback
|
||||
--echo # during insert..select
|
||||
--echo #
|
||||
CREATE TABLE t1 (f1 INT)ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (f1 INT, UNIQUE INDEX(f1)) ENGINE=InnoDB;
|
||||
CREATE TRIGGER tr AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES(1);
|
||||
BEGIN;
|
||||
INSERT t1 SELECT 1 FROM seq_1_to_2;
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t2;
|
||||
CHECK TABLE t1;
|
||||
CHECK TABLE t2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-29801 Inconsistent ER_TOO_BIG_ROWSIZE during bulk
|
||||
--echo # insert operation
|
||||
--echo #
|
||||
call mtr.add_suppression("InnoDB: Cannot add field `c11` in table");
|
||||
|
||||
SET @format= @@innodb_default_row_format;
|
||||
CREATE TABLE t1 (pk int primary key, c01 text, c02 text, c03 text,
|
||||
c04 text, c05 text, c06 text, c07 text, c08 text,
|
||||
c09 text, c10 text, c11 text, c12 text) ENGINE=InnoDB;
|
||||
SET GLOBAL INNODB_DEFAULT_ROW_FORMAT= COMPACT;
|
||||
ALTER TABLE t1 FORCE;
|
||||
INSERT IGNORE INTO t1 VALUES
|
||||
(1, REPEAT('x',4805), REPEAT('t',2211), REPEAT('u',974), REPEAT('e',871), REPEAT('z',224), REPEAT('j',978), REPEAT('n',190), REPEAT('t',888), REPEAT('x',32768), REPEAT('e',968), REPEAT('b',913), REPEAT('x',12107)),
|
||||
(2, REPEAT('x',4805), REPEAT('t',2211), REPEAT('u',974), REPEAT('e',871), REPEAT('z',224), REPEAT('j',978), REPEAT('n',190), REPEAT('t',888), REPEAT('x',32768), REPEAT('e',968), REPEAT('b',913), REPEAT('x',12107));
|
||||
CHECK TABLE t1;
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL INNODB_DEFAULT_ROW_FORMAT= @format;
|
||||
|
@@ -496,6 +496,13 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @return the first undo record that modified the table */
|
||||
undo_no_t get_first() const
|
||||
{
|
||||
ut_ad(valid());
|
||||
return LIMIT & first;
|
||||
}
|
||||
|
||||
/** Add the tuple to the transaction bulk buffer for the given index.
|
||||
@param entry tuple to be inserted
|
||||
@param index bulk insert for the index
|
||||
@@ -1126,6 +1133,22 @@ public:
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
/** Rollback all bulk insert operations */
|
||||
void bulk_rollback()
|
||||
{
|
||||
undo_no_t low_limit= UINT64_MAX;
|
||||
for (auto& t : mod_tables)
|
||||
{
|
||||
if (!t.second.is_bulk_insert())
|
||||
continue;
|
||||
if (t.second.get_first() < low_limit)
|
||||
low_limit= t.second.get_first();
|
||||
}
|
||||
|
||||
trx_savept_t bulk_save{low_limit};
|
||||
rollback(&bulk_save);
|
||||
}
|
||||
|
||||
/** Do the bulk insert for the buffered insert operation
|
||||
for the transaction.
|
||||
@return DB_SUCCESS or error code */
|
||||
@@ -1138,7 +1161,10 @@ public:
|
||||
for (auto& t : mod_tables)
|
||||
if (t.second.is_bulk_insert())
|
||||
if (dberr_t err= t.second.write_bulk(t.first, this))
|
||||
{
|
||||
bulk_rollback();
|
||||
return err;
|
||||
}
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user