Re: 9e7c80f8006: MDEV-32803 Assertion `total == 0' failed in Event_log::write_cache_raw
Hi, Nikita, First, I'd suggest this change: --- a/sql/online_alter.cc +++ b/sql/online_alter.cc @@ -257,8 +257,7 @@ int online_alter_end_trans(Online_alter_cache_list { my_error(ER_ERROR_ON_WRITE, MYF(ME_ERROR_LOG), binlog->get_name(), errno); - cleanup_cache_list(cache_list, is_ending_transaction); - DBUG_RETURN(error); + break; } } and also I'd suggest to move if (ending_trans) from cleanup_cache_list() to the caller (there's only one anyway). It'll make the code clearer, in particular your statement below that "the cache ... wasn't destroyed". Better do these changes in a separate commit, they aren't part of the bug fix. The fix itself is ok to push. On Jan 05, Nikita Malyavin wrote:
revision-id: 9e7c80f8006 (mariadb-11.2.1-27-g9e7c80f8006) parent(s): 0c5176b7744 author: Nikita Malyavin committer: Nikita Malyavin timestamp: 2023-11-17 23:40:10 +0100 message:
MDEV-32803 Assertion `total == 0' failed in Event_log::write_cache_raw
A second DML in a transaction for a table of non-rollbackable engine leads to a cache corruption, because the cache wasn't reset after a statement end, but also wasn't destroyed.
This patch resets the cache for a reuse by subsequent statements in current transaction.
diff --git a/sql/online_alter.cc b/sql/online_alter.cc index e0afe602ca8..5f418d8ec29 100644 --- a/sql/online_alter.cc +++ b/sql/online_alter.cc @@ -152,6 +152,7 @@ int online_alter_log_row(TABLE* table, const uchar *before_record, if (!table->online_alter_cache) { table->online_alter_cache= get_cache_data(thd, table); + DBUG_ASSERT(table->online_alter_cache->cache_log.type == WRITE_CACHE); trans_register_ha(thd, false, online_alter_hton, 0); if (thd->in_multi_stmt_transaction_mode()) trans_register_ha(thd, true, online_alter_hton, 0); @@ -237,6 +238,8 @@ int online_alter_end_trans(Online_alter_cache_list &cache_list, THD *thd, mysql_mutex_lock(binlog->get_log_lock()); error= binlog->write_cache_raw(thd, &cache.cache_log); mysql_mutex_unlock(binlog->get_log_lock()); + if (!is_ending_transaction) + cache.reset(); } } else if (!commit) // rollback
Regards, Sergei Chief Architect, MariaDB Server and security@mariadb.org
participants (1)
-
Sergei Golubchik