From dd13db6f4ae70f45038c1d000cb1439e17170d98 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 14 Mar 2014 16:29:23 +0200 Subject: [PATCH] MDEV-5829: STOP SLAVE resets global status variables Reason for the bug was an optimization for higher connect speed where we moved when global status was updated, but forgot to update states when slave thread dies. Fixed by adding thd->add_status_to_global() before deleting slave thread's thd. mysys/my_delete.c: Added missing newline sql/mysqld.cc: Use add_status_to_global() sql/slave.cc: Added missing add_status_to_global() sql/sql_class.cc: Use add_status_to_global() sql/sql_class.h: Simplify adding local status to global by adding add_status_to_global() --- mysql-test/suite/rpl/r/rpl_000011.result | 6 ++++++ mysql-test/suite/rpl/t/rpl_000011.test | 8 ++++++++ mysys/my_delete.c | 2 +- sql/mysqld.cc | 4 +--- sql/slave.cc | 2 ++ sql/sql_class.cc | 4 +--- sql/sql_class.h | 17 +++++++++++++---- 7 files changed, 32 insertions(+), 11 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_000011.result b/mysql-test/suite/rpl/r/rpl_000011.result index 8a59eb746ad..12859a17f95 100644 --- a/mysql-test/suite/rpl/r/rpl_000011.result +++ b/mysql-test/suite/rpl/r/rpl_000011.result @@ -2,7 +2,13 @@ include/master-slave.inc [connection master] create table t1 (n int); insert into t1 values(1); +show global status like 'com_insert'; +Variable_name Value +Com_insert 1 stop slave; +show global status like 'com_insert'; +Variable_name Value +Com_insert 1 include/wait_for_slave_to_stop.inc start slave; include/wait_for_slave_to_start.inc diff --git a/mysql-test/suite/rpl/t/rpl_000011.test b/mysql-test/suite/rpl/t/rpl_000011.test index 625b0c22c62..faad2242235 100644 --- a/mysql-test/suite/rpl/t/rpl_000011.test +++ b/mysql-test/suite/rpl/t/rpl_000011.test @@ -1,9 +1,17 @@ +# +# Test very simply slave replication (to ensure it works at all) +# In addition, test also: +# MDEV-5829 STOP SLAVE resets global status variables +# + source include/master-slave.inc; create table t1 (n int); insert into t1 values(1); sync_slave_with_master; +show global status like 'com_insert'; stop slave; +show global status like 'com_insert'; --source include/wait_for_slave_to_stop.inc start slave; --source include/wait_for_slave_to_start.inc diff --git a/mysys/my_delete.c b/mysys/my_delete.c index f5737ea66e0..155e925e9ba 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -150,4 +150,4 @@ error: my_osmaperr(last_error); DBUG_RETURN(-1); } -#endif \ No newline at end of file +#endif diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b71a7f7c880..136255f0e8b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2483,9 +2483,7 @@ void unlink_thd(THD *thd) thd_cleanup(thd); dec_connection_count(thd); - mysql_mutex_lock(&LOCK_status); - add_to_status(&global_status_var, &thd->status_var); - mysql_mutex_unlock(&LOCK_status); + thd->add_status_to_global(); mysql_mutex_lock(&LOCK_thread_count); thread_count--; diff --git a/sql/slave.cc b/sql/slave.cc index c3c50501f53..702b6d38cbe 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3356,6 +3356,7 @@ err: } write_ignored_events_info_to_relay_log(thd, mi); thd_proc_info(thd, "Waiting for slave mutex on exit"); + thd->add_status_to_global(); mysql_mutex_lock(&mi->run_lock); err_during_init: @@ -3746,6 +3747,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ thd->catalog= 0; thd->reset_query(); thd->reset_db(NULL, 0); + thd->add_status_to_global(); thd_proc_info(thd, "Waiting for slave mutex on exit"); mysql_mutex_lock(&rli->run_lock); err_during_init: diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2ead1b533d9..4b9701c4eb5 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1360,9 +1360,7 @@ void THD::init_for_queries() void THD::change_user(void) { - mysql_mutex_lock(&LOCK_status); - add_to_status(&global_status_var, &status_var); - mysql_mutex_unlock(&LOCK_status); + add_status_to_global(); cleanup(); reset_killed(); diff --git a/sql/sql_class.h b/sql/sql_class.h index c25a5f82eac..dff9b7354cd 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -695,6 +695,11 @@ typedef struct system_status_var #define last_system_status_var questions +void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var); + +void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, + STATUS_VAR *dec_var); + void mark_transaction_to_rollback(THD *thd, bool all); #ifdef MYSQL_SERVER @@ -3103,6 +3108,14 @@ public: void wait_for_wakeup_ready(); /* Wake this thread up from wait_for_wakeup_ready(). */ void signal_wakeup_ready(); + + void add_status_to_global() + { + mysql_mutex_lock(&LOCK_status); + add_to_status(&global_status_var, &status_var); + mysql_mutex_unlock(&LOCK_status); + } + private: /** The current internal error handler for this thread, or NULL. */ @@ -4145,10 +4158,6 @@ public: */ #define CF_SKIP_QUESTIONS (1U << 1) -void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var); - -void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, - STATUS_VAR *dec_var); void mark_transaction_to_rollback(THD *thd, bool all); /* Inline functions */