From 584fc85e215c934b1df2a0a27c4ecada07a44c6a Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 9 Jun 2024 14:00:32 +0200 Subject: [PATCH] MDEV-32537 Name threads to improve debugging experience and diagnostics. Use SetThreadDescription/pthread_setname_np to give threads a name. --- include/my_pthread.h | 1 + mysys/my_thr_init.c | 29 +++++++++++++++++++++++++++++ mysys/thr_timer.c | 1 + sql/event_scheduler.cc | 2 ++ sql/log.cc | 1 + sql/mysqld.cc | 1 + sql/rpl_parallel.cc | 1 + sql/semisync_master_ack_receiver.cc | 1 + sql/slave.cc | 2 ++ sql/sql_connect.cc | 1 + sql/sql_manager.cc | 1 + sql/threadpool_generic.cc | 2 ++ sql/threadpool_win.cc | 1 + storage/innobase/buf/buf0flu.cc | 1 + storage/innobase/srv/srv0srv.cc | 1 + storage/maria/ma_checkpoint.c | 1 + tpool/aio_liburing.cc | 3 +++ tpool/aio_linux.cc | 4 +++- 18 files changed, 53 insertions(+), 1 deletion(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index 8f0b3ec30e3..c1cd43b640c 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -619,6 +619,7 @@ typedef uint64 my_thread_id; extern void my_threadattr_global_init(void); extern my_bool my_thread_global_init(void); +extern void my_thread_set_name(const char *); extern void my_thread_global_reinit(void); extern void my_thread_global_end(void); extern my_bool my_thread_init(void); diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index f40dab43fa8..0021a37faff 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -172,6 +172,35 @@ my_bool my_thread_global_init(void) return 0; } +#ifdef _WIN32 +#define MAX_THREAD_NAME 256 +#elif defined(__linux__) +#define MAX_THREAD_NAME 16 +#elif defined(__FreeBSD__) || defined(__OpenBSD__) +#include +#endif + +void my_thread_set_name(const char *name) +{ +#ifdef _WIN32 + wchar_t wname[MAX_THREAD_NAME]; + wname[0]= 0; + MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_THREAD_NAME); + SetThreadDescription(GetCurrentThread(), wname); +#elif defined __linux__ + char shortname[MAX_THREAD_NAME]; + snprintf(shortname, MAX_THREAD_NAME, "%s", name); + pthread_setname_np(pthread_self(), shortname); +#elif defined __NetBSD__ + pthread_setname_np(pthread_self(), "%s", (void *) name); +#elif defined __FreeBSD__ || defined __OpenBSD__ + pthread_set_name_np(pthread_self(), name); +#elif defined __APPLE__ + pthread_setname_np(name); +#else + (void) name; +#endif +} /** End the mysys thread system. Called when ending the last thread diff --git a/mysys/thr_timer.c b/mysys/thr_timer.c index 76517c52d8b..fbf7d86d996 100644 --- a/mysys/thr_timer.c +++ b/mysys/thr_timer.c @@ -304,6 +304,7 @@ static sig_handler process_timers(struct timespec *now) static void *timer_handler(void *arg __attribute__((unused))) { my_thread_init(); + my_thread_set_name("statement_timer"); mysql_mutex_lock(&LOCK_timer); while (likely(thr_timer_inited)) diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 97529bd9809..5f3491b3065 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -227,6 +227,7 @@ event_scheduler_thread(void *arg) thd->thread_stack= (char *)&thd; // remember where our stack is mysql_thread_set_psi_id(thd->thread_id); + my_thread_set_name("event_scheduler"); res= post_init_event_thread(thd); @@ -263,6 +264,7 @@ event_worker_thread(void *arg) thd= event->thd; mysql_thread_set_psi_id(thd->thread_id); + my_thread_set_name("event_worker"); Event_worker_thread worker_thread; worker_thread.run(thd, event); diff --git a/sql/log.cc b/sql/log.cc index 830c0934fe7..6c062c275e6 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -11140,6 +11140,7 @@ binlog_background_thread(void *arg __attribute__((unused))) Binlog_background_job **freelist_endptr= &freelist; THD *thd; my_thread_init(); + my_thread_set_name("binlog_background"); DBUG_ENTER("binlog_background_thread"); thd= new THD(next_thread_id()); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 80d434e9638..5be648dc2e5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3219,6 +3219,7 @@ pthread_handler_t signal_hand(void *) sigset_t set; int sig; my_thread_init(); // Init new thread + my_thread_set_name("signal_hand"); signal_thread_in_use= 1; if (test_flags & TEST_SIGINT) diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 454a105bf91..bdf089cb5d9 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -1226,6 +1226,7 @@ handle_rpl_parallel_thread(void *arg) struct rpl_parallel_thread *rpt= (struct rpl_parallel_thread *)arg; my_thread_init(); + my_thread_set_name("rpl_parallel"); thd = new THD(next_thread_id()); thd->thread_stack = (char*)&thd; server_threads.insert(thd); diff --git a/sql/semisync_master_ack_receiver.cc b/sql/semisync_master_ack_receiver.cc index 29fa5fd5328..77a5c13b9f4 100644 --- a/sql/semisync_master_ack_receiver.cc +++ b/sql/semisync_master_ack_receiver.cc @@ -33,6 +33,7 @@ pthread_handler_t ack_receive_handler(void *arg) Ack_receiver *recv= reinterpret_cast(arg); my_thread_init(); + my_thread_set_name("ack_receive"); recv->run(); my_thread_end(); diff --git a/sql/slave.cc b/sql/slave.cc index 25cf0c30ab6..5ba8d388f2e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4786,6 +4786,7 @@ pthread_handler_t handle_slave_io(void *arg) #endif // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff my_thread_init(); + my_thread_set_name("slave_io"); DBUG_ENTER("handle_slave_io"); DBUG_ASSERT(mi->inited); @@ -5441,6 +5442,7 @@ pthread_handler_t handle_slave_sql(void *arg) // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff my_thread_init(); + my_thread_set_name("slave_sql"); DBUG_ENTER("handle_slave_sql"); #ifdef WITH_WSREP diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index de6e78ed38d..555aff33d3a 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1342,6 +1342,7 @@ pthread_handler_t handle_one_connection(void *arg) CONNECT *connect= (CONNECT*) arg; mysql_thread_set_psi_id(connect->thread_id); + my_thread_set_name("one_connection"); if (init_new_connection_handler_thread()) connect->close_with_error(0, 0, ER_OUT_OF_RESOURCES); diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index b3d95c9ed31..2cffddf0158 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -75,6 +75,7 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) struct timespec abstime; bool reset_flush_time = TRUE; my_thread_init(); + my_thread_set_name("handle_manager"); DBUG_ENTER("handle_manager"); pthread_detach_this_thread(); diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc index 0a653474ffa..74405ee4c80 100644 --- a/sql/threadpool_generic.cc +++ b/sql/threadpool_generic.cc @@ -559,6 +559,7 @@ static void* timer_thread(void *param) pool_timer_t* timer=(pool_timer_t *)param; my_thread_init(); + my_thread_set_name("timer_thread"); DBUG_ENTER("timer_thread"); timer->next_timeout_check.store(std::numeric_limits::max(), std::memory_order_relaxed); @@ -1533,6 +1534,7 @@ static void *worker_main(void *param) worker_thread_t this_thread; pthread_detach_this_thread(); my_thread_init(); + my_thread_set_name("connection_worker"); DBUG_ENTER("worker_main"); diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc index 65e40598135..158185c6662 100644 --- a/sql/threadpool_win.cc +++ b/sql/threadpool_win.cc @@ -244,6 +244,7 @@ void tp_win_callback_prolog() thread_created++; tp_stats.num_worker_threads++; my_thread_init(); + my_thread_set_name("connection_worker"); } } diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 494486d3ba2..62011955e2e 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -2398,6 +2398,7 @@ pools. As of now we'll have only one coordinator. */ static void buf_flush_page_cleaner() { my_thread_init(); + my_thread_set_name("ib_page_cleaner"); #ifdef UNIV_PFS_THREAD pfs_register_thread(page_cleaner_thread_key); #endif /* UNIV_PFS_THREAD */ diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index eb612aa7781..5a647abcd47 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -530,6 +530,7 @@ srv_print_master_thread_info( static void thread_pool_thread_init() { my_thread_init(); + my_thread_set_name("ib_tpool_worker"); pfs_register_thread(thread_pool_thread_key); } static void thread_pool_thread_end() diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c index 2741f54d7d7..18653ed130c 100644 --- a/storage/maria/ma_checkpoint.c +++ b/storage/maria/ma_checkpoint.c @@ -577,6 +577,7 @@ pthread_handler_t ma_checkpoint_background(void *arg) PAGECACHE_FILE *UNINIT_VAR(kfile); /**< index file currently being flushed */ my_thread_init(); + my_thread_set_name("ma_checkpoint_background"); DBUG_PRINT("info",("Maria background checkpoint thread starts")); DBUG_ASSERT(interval > 0); diff --git a/tpool/aio_liburing.cc b/tpool/aio_liburing.cc index 447c2335c74..d678b446322 100644 --- a/tpool/aio_liburing.cc +++ b/tpool/aio_liburing.cc @@ -19,12 +19,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/ #include "mysqld_error.h" #include +#include #include #include #include #include #include +#include namespace { @@ -139,6 +141,7 @@ public: private: static void thread_routine(aio_uring *aio) { + my_thread_set_name("io_uring_wait"); for (;;) { io_uring_cqe *cqe; diff --git a/tpool/aio_linux.cc b/tpool/aio_linux.cc index 507c6b9264f..abf37e2277c 100644 --- a/tpool/aio_linux.cc +++ b/tpool/aio_linux.cc @@ -21,7 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/ # include # include # include - +# include +# include /** Invoke the io_getevents() system call, without timeout parameter. @@ -93,6 +94,7 @@ class aio_linux final : public aio static void getevent_thread_routine(aio_linux *aio) { + my_thread_set_name("my_getevents"); /* We collect events in small batches to hopefully reduce the number of system calls.