diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3555f9b81aa..aa4c3adff9f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5445,6 +5445,7 @@ int mysqld_main(int argc, char **argv) init_server_psi_keys(); /* Instrument the main thread */ PSI_thread *psi= PSI_CALL_new_thread(key_thread_main, NULL, 0); + PSI_CALL_set_thread_os_id(psi); PSI_CALL_set_thread(psi); /* diff --git a/sql/slave.cc b/sql/slave.cc index 4ef20084678..fc27227a36b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -488,6 +488,7 @@ handle_slave_background(void *arg __attribute__((unused))) #ifdef WITH_WSREP thd->variables.wsrep_on= 0; #endif + thd->set_psi(PSI_CALL_get_thread()); thd_proc_info(thd, "Loading slave GTID position from table"); if (rpl_load_gtid_slave_state(thd)) @@ -4728,6 +4729,8 @@ pthread_handler_t handle_slave_io(void *arg) THD_CHECK_SENTRY(thd); mi->io_thd = thd; + thd->set_psi(PSI_CALL_get_thread()); + pthread_detach_this_thread(); thd->thread_stack= (char*) &thd; // remember where our stack is mi->clear_error(); @@ -5366,6 +5369,8 @@ pthread_handler_t handle_slave_sql(void *arg) executing SQL queries too. */ serial_rgi->thd= rli->sql_driver_thd= thd; + + thd->set_psi(PSI_CALL_get_thread()); /* Inform waiting threads that slave has started */ rli->slave_run_id++; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9066d939db6..de4eaf86133 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1689,6 +1689,8 @@ THD::~THD() DBUG_ENTER("~THD()"); /* Make sure threads are not available via server_threads. */ assert_not_linked(); + if (m_psi) + PSI_CALL_set_thread_THD(m_psi, 0); /* In error cases, thd may not be current thd. We have to fix this so @@ -4835,6 +4837,7 @@ MYSQL_THD create_background_thd() auto thd_mysysvar= pthread_getspecific(THR_KEY_mysys); auto thd= new THD(0); pthread_setspecific(THR_KEY_mysys, save_mysysvar); + thd->set_psi(PSI_CALL_get_thread()); /* Workaround the adverse effect of incrementing thread_count @@ -7794,3 +7797,8 @@ bool THD::timestamp_to_TIME(MYSQL_TIME *ltime, my_time_t ts, } return 0; } + +THD_list_iterator *THD_list_iterator::iterator() +{ + return &server_threads; +} diff --git a/sql/sql_class.h b/sql/sql_class.h index f74f5fb3b20..dc6e12a5c01 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1021,6 +1021,39 @@ inline bool is_supported_parser_charset(CHARSET_INFO *cs) return MY_TEST(cs->mbminlen == 1); } +/** THD registry */ +class THD_list_iterator +{ +protected: + I_List threads; + mutable mysql_rwlock_t lock; + +public: + + /** + Iterates registered threads. + + @param action called for every element + @param argument opque argument passed to action + + @return + @retval 0 iteration completed successfully + @retval 1 iteration was interrupted (action returned 1) + */ + template int iterate(my_bool (*action)(THD *thd, T *arg), T *arg= 0) + { + int res= 0; + mysql_rwlock_rdlock(&lock); + I_List_iterator it(threads); + while (auto tmp= it++) + if ((res= action(tmp, arg))) + break; + mysql_rwlock_unlock(&lock); + return res; + } + static THD_list_iterator *iterator(); +}; + #ifdef MYSQL_SERVER void free_tmp_table(THD *thd, TABLE *entry); @@ -2375,9 +2408,22 @@ public: */ const char *proc_info; + void set_psi(PSI_thread *psi) + { + my_atomic_storeptr(&m_psi, psi); + } + + PSI_thread* get_psi() + { + return static_cast(my_atomic_loadptr(&m_psi)); + } + private: unsigned int m_current_stage_key; + /** Performance schema thread instrumentation for this session. */ + PSI_thread *m_psi; + public: void enter_stage(const PSI_stage_info *stage, const char *calling_func, @@ -7262,11 +7308,8 @@ private: /** THD registry */ -class THD_list +class THD_list: public THD_list_iterator { - I_List threads; - mutable mysql_rwlock_t lock; - public: /** Constructor replacement. @@ -7314,28 +7357,6 @@ public: thd->unlink(); mysql_rwlock_unlock(&lock); } - - /** - Iterates registered threads. - - @param action called for every element - @param argument opque argument passed to action - - @return - @retval 0 iteration completed successfully - @retval 1 iteration was interrupted (action returned 1) - */ - template int iterate(my_bool (*action)(THD *thd, T *arg), T *arg= 0) - { - int res= 0; - mysql_rwlock_rdlock(&lock); - I_List_iterator it(threads); - while (auto tmp= it++) - if ((res= action(tmp, arg))) - break; - mysql_rwlock_unlock(&lock); - return res; - } }; extern THD_list server_threads; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 7a8a2f7533a..c02e595717d 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1435,6 +1435,10 @@ end_thread: !(connect= cache_thread(thd))) break; + /* Create new instrumentation for the new THD job */ + PSI_CALL_set_thread(PSI_CALL_new_thread(key_thread_one_connection, thd, + thd->thread_id)); + if (!(connect->create_thd(thd))) { /* Out of resources. Free thread to get more resources */ @@ -1449,13 +1453,6 @@ end_thread: */ thd->store_globals(); - /* - Create new instrumentation for the new THD job, - and attach it to this running pthread. - */ - PSI_CALL_set_thread(PSI_CALL_new_thread(key_thread_one_connection, - thd, thd->thread_id)); - /* reset abort flag for the thread */ thd->mysys_var->abort= 0; thd->thr_create_utime= microsecond_interval_timer(); @@ -1576,5 +1573,14 @@ THD *CONNECT::create_thd(THD *thd) thd->scheduler= scheduler; thd->real_id= pthread_self(); /* Duplicates THD::store_globals() setting. */ + + /* Attach PSI instrumentation to the new THD */ + + PSI_thread *psi= PSI_CALL_get_thread(); + PSI_CALL_set_thread_os_id(psi); + PSI_CALL_set_thread_THD(psi, thd); + PSI_CALL_set_thread_id(psi, thd->thread_id); + thd->set_psi(psi); + DBUG_RETURN(thd); } diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index f3cb2c22727..fb6d7c8ddee 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -565,8 +565,7 @@ schema */ # define pfs_register_thread(key) \ do { \ struct PSI_thread* psi = PSI_CALL_new_thread(key, NULL, 0);\ - /* JAN: TODO: MYSQL 5.7 PSI \ - PSI_CALL_set_thread_os_id(psi); */ \ + PSI_CALL_set_thread_os_id(psi); \ PSI_CALL_set_thread(psi); \ } while (0) diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c index caf6656c000..4b043f0795e 100644 --- a/storage/maria/ma_checkpoint.c +++ b/storage/maria/ma_checkpoint.c @@ -562,7 +562,7 @@ pthread_handler_t ma_checkpoint_background(void *arg) DBUG_PRINT("info",("Maria background checkpoint thread starts")); DBUG_ASSERT(interval > 0); - PSI_CALL_set_thread_user_host(0,0,0,0); + PSI_CALL_set_thread_account(0,0,0,0); /* Recovery ended with all tables closed and a checkpoint: no need to take