summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2022-09-27 14:27:19 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2022-09-27 14:27:19 +0530
commitd342a3303f2d82da24136cc664a1a59eab23873b (patch)
tree0c25b1e38f1d9cc9a1d0221fc27e482ccae1752f
parent7c7ac6d4a4c77d4c302732da2efe6785b1f0e455 (diff)
downloadmariadb-git-bb-10.7-MDEV-29570.tar.gz
MDEV-29570 InnoDB fails to clean bulk buffer when server does rollback operationbb-10.7-MDEV-29570
- During bulk insert, server detects the error and does rollback operation. At that time, InnoDB fails to clean up the bulk insert buffer trx_t::rollback_finish(): Remove modified tables from transaction trx_t::commit_cleanup(): Free the bulk buffer for bulk insert operation trx_t::commit(): Check whether modified table wasn't dropped only for non-dictionary transaction
-rw-r--r--mysql-test/suite/innodb/r/insert_into_empty.result10
-rw-r--r--mysql-test/suite/innodb/t/insert_into_empty.test12
-rw-r--r--storage/innobase/include/trx0trx.h8
-rw-r--r--storage/innobase/trx/trx0roll.cc1
-rw-r--r--storage/innobase/trx/trx0trx.cc9
5 files changed, 34 insertions, 6 deletions
diff --git a/mysql-test/suite/innodb/r/insert_into_empty.result b/mysql-test/suite/innodb/r/insert_into_empty.result
index 99afa798c09..29c5ef48da9 100644
--- a/mysql-test/suite/innodb/r/insert_into_empty.result
+++ b/mysql-test/suite/innodb/r/insert_into_empty.result
@@ -304,3 +304,13 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB PARTITION BY HASH(a) PARTITIONS 2;
INSERT INTO t1 VALUES (1),(2);
ALTER TABLE t1 REBUILD PARTITION p0;
DROP TABLE t1;
+#
+# MDEV-29570 InnoDB fails to clean bulk buffer when server
+# does rollback operation
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB
+PARTITION BY RANGE (pk) (
+PARTITION pn VALUES LESS THAN (20));
+INSERT INTO t1 VALUES (1),(21);
+ERROR HY000: Table has no partition for value 21
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/insert_into_empty.test b/mysql-test/suite/innodb/t/insert_into_empty.test
index 9762009ecdc..420af61c6de 100644
--- a/mysql-test/suite/innodb/t/insert_into_empty.test
+++ b/mysql-test/suite/innodb/t/insert_into_empty.test
@@ -315,3 +315,15 @@ INSERT INTO t1 VALUES (1),(2);
ALTER TABLE t1 REBUILD PARTITION p0;
# Cleanup
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-29570 InnoDB fails to clean bulk buffer when server
+--echo # does rollback operation
+--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB
+ PARTITION BY RANGE (pk) (
+ PARTITION pn VALUES LESS THAN (20));
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
+INSERT INTO t1 VALUES (1),(21);
+# Cleanup
+DROP TABLE t1;
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 505ef96e01d..054f1ea90d2 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -433,6 +433,8 @@ class trx_mod_table_time_t
/** Buffer to store insert opertion */
row_merge_bulk_t *bulk_store= nullptr;
+
+ friend class trx_t;
public:
/** Constructor
@param rows number of modified rows so far */
@@ -517,11 +519,9 @@ public:
}
/** @return whether the buffer storage exist */
- bool bulk_buffer_exist()
+ bool bulk_buffer_exist() const
{
- if (is_bulk_insert() && bulk_store)
- return true;
- return false;
+ return bulk_store && is_bulk_insert();
}
};
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 59c9a319330..45dc78b4440 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -59,7 +59,6 @@ const trx_t* trx_roll_crash_recv_trx;
@retval false if the rollback was aborted by shutdown */
inline bool trx_t::rollback_finish()
{
- mod_tables.clear();
apply_online_log= false;
if (UNIV_LIKELY(error_state == DB_SUCCESS))
{
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 1ce81ebcb1c..89abf678699 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1388,6 +1388,10 @@ void trx_t::commit_cleanup()
ut_ad(!dict_operation);
ut_ad(!was_dict_operation);
+ if (is_bulk_insert())
+ for (auto &t : mod_tables)
+ delete t.second.bulk_store;
+
mutex.wr_lock();
state= TRX_STATE_NOT_STARTED;
mod_tables.clear();
@@ -1479,8 +1483,11 @@ void trx_t::commit()
ut_d(was_dict_operation= dict_operation);
dict_operation= false;
commit_persist();
+#ifdef UNIV_DEBUG
+ if (!was_dict_operation)
+ for (const auto &p : mod_tables) ut_ad(!p.second.is_dropped());
+#endif /* UNIV_DEBUG */
ut_d(was_dict_operation= false);
- ut_d(for (const auto &p : mod_tables) ut_ad(!p.second.is_dropped()));
commit_cleanup();
}