mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-24861 Assertion `trx->rsegs.m_redo.rseg' failed in innodb_prepare_commit_versioned
trx_t::commit_tables(): Ensure that mod_tables will be empty.
This was broken in commit b08448de64
where the query cache invalidation was moved from lock_release().
This commit is contained in:
@@ -91,3 +91,16 @@ ALTER TABLE t1 FORCE;
|
|||||||
TRUNCATE TABLE t1;
|
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`))
|
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;
|
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
|
||||||
|
@@ -92,3 +92,19 @@ ALTER TABLE t1 FORCE;
|
|||||||
--error ER_TRUNCATE_ILLEGAL_FK
|
--error ER_TRUNCATE_ILLEGAL_FK
|
||||||
TRUNCATE TABLE t1;
|
TRUNCATE TABLE t1;
|
||||||
DROP TABLE t2, 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
|
||||||
|
@@ -1226,44 +1226,46 @@ trx_flush_log_if_needed(
|
|||||||
/** Process tables that were modified by the committing transaction. */
|
/** Process tables that were modified by the committing transaction. */
|
||||||
inline void trx_t::commit_tables()
|
inline void trx_t::commit_tables()
|
||||||
{
|
{
|
||||||
if (!undo_no || mod_tables.empty())
|
if (mod_tables.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (undo_no)
|
||||||
|
{
|
||||||
#if defined SAFE_MUTEX && defined UNIV_DEBUG
|
#if defined SAFE_MUTEX && defined UNIV_DEBUG
|
||||||
const bool preserve_tables= !innodb_evict_tables_on_commit_debug ||
|
const bool preserve_tables= !innodb_evict_tables_on_commit_debug ||
|
||||||
is_recovered || /* avoid trouble with XA recovery */
|
is_recovered || /* avoid trouble with XA recovery */
|
||||||
# if 1 /* if dict_stats_exec_sql() were not playing dirty tricks */
|
# 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 */
|
# else /* this would be more proper way to do it */
|
||||||
dict_operation_lock_mode || dict_operation;
|
dict_operation_lock_mode || dict_operation;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const trx_id_t max_trx_id= trx_sys.get_max_trx_id();
|
const trx_id_t max_trx_id= trx_sys.get_max_trx_id();
|
||||||
const auto now= start_time;
|
const auto now= start_time;
|
||||||
|
|
||||||
for (const auto& p : mod_tables)
|
for (const auto& p : mod_tables)
|
||||||
{
|
{
|
||||||
dict_table_t *table= p.first;
|
dict_table_t *table= p.first;
|
||||||
table->update_time= now;
|
table->update_time= now;
|
||||||
table->query_cache_inv_trx_id= max_trx_id;
|
table->query_cache_inv_trx_id= max_trx_id;
|
||||||
|
|
||||||
#if defined SAFE_MUTEX && defined UNIV_DEBUG
|
#if defined SAFE_MUTEX && defined UNIV_DEBUG
|
||||||
if (preserve_tables || table->get_ref_count() || table->is_temporary() ||
|
if (preserve_tables || table->get_ref_count() || table->is_temporary() ||
|
||||||
UT_LIST_GET_LEN(table->locks))
|
UT_LIST_GET_LEN(table->locks))
|
||||||
/* do not evict when committing DDL operations or if some other
|
/* do not evict when committing DDL operations or if some other
|
||||||
transaction is holding the table handle */
|
transaction is holding the table handle */
|
||||||
continue;
|
continue;
|
||||||
/* recheck while holding the mutex that blocks
|
/* recheck while holding the mutex that blocks table->acquire() */
|
||||||
table->acquire() */
|
dict_sys.mutex_lock();
|
||||||
dict_sys.mutex_lock();
|
{
|
||||||
{
|
LockMutexGuard g{SRW_LOCK_CALL};
|
||||||
LockMutexGuard g{SRW_LOCK_CALL};
|
if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks))
|
||||||
if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks))
|
dict_sys.remove(table, true);
|
||||||
dict_sys.remove(table, true);
|
}
|
||||||
}
|
dict_sys.mutex_unlock();
|
||||||
dict_sys.mutex_unlock();
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_tables.clear();
|
mod_tables.clear();
|
||||||
|
Reference in New Issue
Block a user