diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2022-09-27 14:27:19 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2022-09-27 14:27:19 +0530 |
commit | d342a3303f2d82da24136cc664a1a59eab23873b (patch) | |
tree | 0c25b1e38f1d9cc9a1d0221fc27e482ccae1752f | |
parent | 7c7ac6d4a4c77d4c302732da2efe6785b1f0e455 (diff) | |
download | mariadb-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.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/insert_into_empty.test | 12 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 8 | ||||
-rw-r--r-- | storage/innobase/trx/trx0roll.cc | 1 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 9 |
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(); } |