diff --git a/mysql-test/suite/innodb/r/innodb-truncate.result b/mysql-test/suite/innodb/r/innodb-truncate.result index 8610a892cc6..3e2ab7936dc 100644 --- a/mysql-test/suite/innodb/r/innodb-truncate.result +++ b/mysql-test/suite/innodb/r/innodb-truncate.result @@ -91,3 +91,16 @@ ALTER TABLE t1 FORCE; TRUNCATE TABLE t1; ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `test`.`t3` (`f2`)) DROP TABLE t2, t1; +# +# MDEV-24861 Assertion `trx->rsegs.m_redo.rseg' failed +# in innodb_prepare_commit_versioned +# +CREATE TABLE t1 (id INT PRIMARY KEY, f TEXT UNIQUE, +s BIGINT UNSIGNED AS ROW START, e BIGINT UNSIGNED AS ROW END, +PERIOD FOR SYSTEM_TIME(s,e)) +ENGINE=InnoDB WITH SYSTEM VERSIONING; +CREATE TABLE t2 (id INT PRIMARY KEY) ENGINE=InnoDB; +ALTER TABLE t1 FORCE; +TRUNCATE TABLE t2; +DROP TABLE t1, t2; +# End of 10.6 tests diff --git a/mysql-test/suite/innodb/t/innodb-truncate.test b/mysql-test/suite/innodb/t/innodb-truncate.test index 71c0fcfea8b..4d39fcaef6d 100644 --- a/mysql-test/suite/innodb/t/innodb-truncate.test +++ b/mysql-test/suite/innodb/t/innodb-truncate.test @@ -92,3 +92,19 @@ ALTER TABLE t1 FORCE; --error ER_TRUNCATE_ILLEGAL_FK TRUNCATE TABLE t1; DROP TABLE t2, t1; + +--echo # +--echo # MDEV-24861 Assertion `trx->rsegs.m_redo.rseg' failed +--echo # in innodb_prepare_commit_versioned +--echo # + +CREATE TABLE t1 (id INT PRIMARY KEY, f TEXT UNIQUE, + s BIGINT UNSIGNED AS ROW START, e BIGINT UNSIGNED AS ROW END, + PERIOD FOR SYSTEM_TIME(s,e)) +ENGINE=InnoDB WITH SYSTEM VERSIONING; +CREATE TABLE t2 (id INT PRIMARY KEY) ENGINE=InnoDB; +ALTER TABLE t1 FORCE; +TRUNCATE TABLE t2; +DROP TABLE t1, t2; + +--echo # End of 10.6 tests diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 8c5e9fe875a..413668e0359 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1226,44 +1226,46 @@ trx_flush_log_if_needed( /** Process tables that were modified by the committing transaction. */ inline void trx_t::commit_tables() { - if (!undo_no || mod_tables.empty()) + if (mod_tables.empty()) return; + if (undo_no) + { #if defined SAFE_MUTEX && defined UNIV_DEBUG - const bool preserve_tables= !innodb_evict_tables_on_commit_debug || - is_recovered || /* avoid trouble with XA recovery */ + const bool preserve_tables= !innodb_evict_tables_on_commit_debug || + is_recovered || /* avoid trouble with XA recovery */ # if 1 /* if dict_stats_exec_sql() were not playing dirty tricks */ - dict_sys.mutex_is_locked(); + dict_sys.mutex_is_locked(); # else /* this would be more proper way to do it */ - dict_operation_lock_mode || dict_operation; + dict_operation_lock_mode || dict_operation; # endif #endif - const trx_id_t max_trx_id= trx_sys.get_max_trx_id(); - const auto now= start_time; + const trx_id_t max_trx_id= trx_sys.get_max_trx_id(); + const auto now= start_time; - for (const auto& p : mod_tables) - { - dict_table_t *table= p.first; - table->update_time= now; - table->query_cache_inv_trx_id= max_trx_id; + for (const auto& p : mod_tables) + { + dict_table_t *table= p.first; + table->update_time= now; + table->query_cache_inv_trx_id= max_trx_id; #if defined SAFE_MUTEX && defined UNIV_DEBUG - if (preserve_tables || table->get_ref_count() || table->is_temporary() || - UT_LIST_GET_LEN(table->locks)) - /* do not evict when committing DDL operations or if some other - transaction is holding the table handle */ - continue; - /* recheck while holding the mutex that blocks - table->acquire() */ - dict_sys.mutex_lock(); - { - LockMutexGuard g{SRW_LOCK_CALL}; - if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks)) - dict_sys.remove(table, true); - } - dict_sys.mutex_unlock(); + if (preserve_tables || table->get_ref_count() || table->is_temporary() || + UT_LIST_GET_LEN(table->locks)) + /* do not evict when committing DDL operations or if some other + transaction is holding the table handle */ + continue; + /* recheck while holding the mutex that blocks table->acquire() */ + dict_sys.mutex_lock(); + { + LockMutexGuard g{SRW_LOCK_CALL}; + if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks)) + dict_sys.remove(table, true); + } + dict_sys.mutex_unlock(); #endif + } } mod_tables.clear();