From c44cac91ab9ea449cb57eabf593cca4a5cfe2deb Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 27 Dec 2023 17:04:43 +0100 Subject: [PATCH] MDEV-33031 Assertion failure upon reading from performance schema with binlog enabled need to protect access to thread-local cache_mngr with LOCK_thd_data technically only access from different threads has to be protected, but this is the SHOW STATUS code path, so the difference is neglectable --- .../suite/perfschema/r/rpl_threads.result | 6 +++++ .../suite/perfschema/t/rpl_threads.test | 6 +++++ sql/log.cc | 23 ++++++++++--------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/mysql-test/suite/perfschema/r/rpl_threads.result b/mysql-test/suite/perfschema/r/rpl_threads.result index c756b4d9046..3e9cf22f715 100644 --- a/mysql-test/suite/perfschema/r/rpl_threads.result +++ b/mysql-test/suite/perfschema/r/rpl_threads.result @@ -58,4 +58,10 @@ select NAME, TYPE, PROCESSLIST_COMMAND, PROCESSLIST_STATE from performance_schema.threads where PROCESSLIST_ID = @slave_sql_pid; NAME TYPE PROCESSLIST_COMMAND PROCESSLIST_STATE +# +# MDEV-33031 Assertion failure upon reading from performance schema with binlog enabled +# +select variable_name, variable_value from performance_schema.status_by_thread +where variable_name like '%impossible%'; +variable_name variable_value include/rpl_end.inc diff --git a/mysql-test/suite/perfschema/t/rpl_threads.test b/mysql-test/suite/perfschema/t/rpl_threads.test index a5ca51a94a4..fcecf775722 100644 --- a/mysql-test/suite/perfschema/t/rpl_threads.test +++ b/mysql-test/suite/perfschema/t/rpl_threads.test @@ -81,5 +81,11 @@ select NAME, TYPE, PROCESSLIST_COMMAND, PROCESSLIST_STATE from performance_schema.threads where PROCESSLIST_ID = @slave_sql_pid; +--echo # +--echo # MDEV-33031 Assertion failure upon reading from performance schema with binlog enabled +--echo # +select variable_name, variable_value from performance_schema.status_by_thread +where variable_name like '%impossible%'; # should not crash + --source include/rpl_end.inc diff --git a/sql/log.cc b/sql/log.cc index fa15ccfeb4c..2e55949a722 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -11826,14 +11826,21 @@ set_binlog_snapshot_file(const char *src) void TC_LOG_BINLOG::set_status_variables(THD *thd) { - binlog_cache_mngr *cache_mngr; + bool have_snapshot= false; if (thd && opt_bin_log) - cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); - else - cache_mngr= 0; + { + mysql_mutex_lock(&thd->LOCK_thd_data); + auto cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); + have_snapshot= cache_mngr && cache_mngr->last_commit_pos_file[0]; + if (have_snapshot) + { + set_binlog_snapshot_file(cache_mngr->last_commit_pos_file); + binlog_snapshot_position= cache_mngr->last_commit_pos_offset; + } + mysql_mutex_unlock(&thd->LOCK_thd_data); + } - bool have_snapshot= (cache_mngr && cache_mngr->last_commit_pos_file[0] != 0); mysql_mutex_lock(&LOCK_commit_ordered); binlog_status_var_num_commits= this->num_commits; binlog_status_var_num_group_commits= this->num_group_commits; @@ -11848,12 +11855,6 @@ TC_LOG_BINLOG::set_status_variables(THD *thd) binlog_status_group_commit_trigger_timeout= this->group_commit_trigger_timeout; binlog_status_group_commit_trigger_lock_wait= this->group_commit_trigger_lock_wait; mysql_mutex_unlock(&LOCK_prepare_ordered); - - if (have_snapshot) - { - set_binlog_snapshot_file(cache_mngr->last_commit_pos_file); - binlog_snapshot_position= cache_mngr->last_commit_pos_offset; - } }