MDEV-32537 Name threads to improve debugging experience and diagnostics.

Use SetThreadDescription/pthread_setname_np to give threads a name.
This commit is contained in:
Vladislav Vaintroub 2024-06-09 14:00:32 +02:00
parent 027f137741
commit 584fc85e21
18 changed files with 53 additions and 1 deletions

View file

@ -619,6 +619,7 @@ typedef uint64 my_thread_id;
extern void my_threadattr_global_init(void); extern void my_threadattr_global_init(void);
extern my_bool my_thread_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_reinit(void);
extern void my_thread_global_end(void); extern void my_thread_global_end(void);
extern my_bool my_thread_init(void); extern my_bool my_thread_init(void);

View file

@ -172,6 +172,35 @@ my_bool my_thread_global_init(void)
return 0; return 0;
} }
#ifdef _WIN32
#define MAX_THREAD_NAME 256
#elif defined(__linux__)
#define MAX_THREAD_NAME 16
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
#include <pthread_np.h>
#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 End the mysys thread system. Called when ending the last thread

View file

@ -304,6 +304,7 @@ static sig_handler process_timers(struct timespec *now)
static void *timer_handler(void *arg __attribute__((unused))) static void *timer_handler(void *arg __attribute__((unused)))
{ {
my_thread_init(); my_thread_init();
my_thread_set_name("statement_timer");
mysql_mutex_lock(&LOCK_timer); mysql_mutex_lock(&LOCK_timer);
while (likely(thr_timer_inited)) while (likely(thr_timer_inited))

View file

@ -227,6 +227,7 @@ event_scheduler_thread(void *arg)
thd->thread_stack= (char *)&thd; // remember where our stack is thd->thread_stack= (char *)&thd; // remember where our stack is
mysql_thread_set_psi_id(thd->thread_id); mysql_thread_set_psi_id(thd->thread_id);
my_thread_set_name("event_scheduler");
res= post_init_event_thread(thd); res= post_init_event_thread(thd);
@ -263,6 +264,7 @@ event_worker_thread(void *arg)
thd= event->thd; thd= event->thd;
mysql_thread_set_psi_id(thd->thread_id); mysql_thread_set_psi_id(thd->thread_id);
my_thread_set_name("event_worker");
Event_worker_thread worker_thread; Event_worker_thread worker_thread;
worker_thread.run(thd, event); worker_thread.run(thd, event);

View file

@ -11140,6 +11140,7 @@ binlog_background_thread(void *arg __attribute__((unused)))
Binlog_background_job **freelist_endptr= &freelist; Binlog_background_job **freelist_endptr= &freelist;
THD *thd; THD *thd;
my_thread_init(); my_thread_init();
my_thread_set_name("binlog_background");
DBUG_ENTER("binlog_background_thread"); DBUG_ENTER("binlog_background_thread");
thd= new THD(next_thread_id()); thd= new THD(next_thread_id());

View file

@ -3219,6 +3219,7 @@ pthread_handler_t signal_hand(void *)
sigset_t set; sigset_t set;
int sig; int sig;
my_thread_init(); // Init new thread my_thread_init(); // Init new thread
my_thread_set_name("signal_hand");
signal_thread_in_use= 1; signal_thread_in_use= 1;
if (test_flags & TEST_SIGINT) if (test_flags & TEST_SIGINT)

View file

@ -1226,6 +1226,7 @@ handle_rpl_parallel_thread(void *arg)
struct rpl_parallel_thread *rpt= (struct rpl_parallel_thread *)arg; struct rpl_parallel_thread *rpt= (struct rpl_parallel_thread *)arg;
my_thread_init(); my_thread_init();
my_thread_set_name("rpl_parallel");
thd = new THD(next_thread_id()); thd = new THD(next_thread_id());
thd->thread_stack = (char*)&thd; thd->thread_stack = (char*)&thd;
server_threads.insert(thd); server_threads.insert(thd);

View file

@ -33,6 +33,7 @@ pthread_handler_t ack_receive_handler(void *arg)
Ack_receiver *recv= reinterpret_cast<Ack_receiver *>(arg); Ack_receiver *recv= reinterpret_cast<Ack_receiver *>(arg);
my_thread_init(); my_thread_init();
my_thread_set_name("ack_receive");
recv->run(); recv->run();
my_thread_end(); my_thread_end();

View file

@ -4786,6 +4786,7 @@ pthread_handler_t handle_slave_io(void *arg)
#endif #endif
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init(); my_thread_init();
my_thread_set_name("slave_io");
DBUG_ENTER("handle_slave_io"); DBUG_ENTER("handle_slave_io");
DBUG_ASSERT(mi->inited); 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 // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init(); my_thread_init();
my_thread_set_name("slave_sql");
DBUG_ENTER("handle_slave_sql"); DBUG_ENTER("handle_slave_sql");
#ifdef WITH_WSREP #ifdef WITH_WSREP

View file

@ -1342,6 +1342,7 @@ pthread_handler_t handle_one_connection(void *arg)
CONNECT *connect= (CONNECT*) arg; CONNECT *connect= (CONNECT*) arg;
mysql_thread_set_psi_id(connect->thread_id); mysql_thread_set_psi_id(connect->thread_id);
my_thread_set_name("one_connection");
if (init_new_connection_handler_thread()) if (init_new_connection_handler_thread())
connect->close_with_error(0, 0, ER_OUT_OF_RESOURCES); connect->close_with_error(0, 0, ER_OUT_OF_RESOURCES);

View file

@ -75,6 +75,7 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused)))
struct timespec abstime; struct timespec abstime;
bool reset_flush_time = TRUE; bool reset_flush_time = TRUE;
my_thread_init(); my_thread_init();
my_thread_set_name("handle_manager");
DBUG_ENTER("handle_manager"); DBUG_ENTER("handle_manager");
pthread_detach_this_thread(); pthread_detach_this_thread();

View file

@ -559,6 +559,7 @@ static void* timer_thread(void *param)
pool_timer_t* timer=(pool_timer_t *)param; pool_timer_t* timer=(pool_timer_t *)param;
my_thread_init(); my_thread_init();
my_thread_set_name("timer_thread");
DBUG_ENTER("timer_thread"); DBUG_ENTER("timer_thread");
timer->next_timeout_check.store(std::numeric_limits<uint64_t>::max(), timer->next_timeout_check.store(std::numeric_limits<uint64_t>::max(),
std::memory_order_relaxed); std::memory_order_relaxed);
@ -1533,6 +1534,7 @@ static void *worker_main(void *param)
worker_thread_t this_thread; worker_thread_t this_thread;
pthread_detach_this_thread(); pthread_detach_this_thread();
my_thread_init(); my_thread_init();
my_thread_set_name("connection_worker");
DBUG_ENTER("worker_main"); DBUG_ENTER("worker_main");

View file

@ -244,6 +244,7 @@ void tp_win_callback_prolog()
thread_created++; thread_created++;
tp_stats.num_worker_threads++; tp_stats.num_worker_threads++;
my_thread_init(); my_thread_init();
my_thread_set_name("connection_worker");
} }
} }

View file

@ -2398,6 +2398,7 @@ pools. As of now we'll have only one coordinator. */
static void buf_flush_page_cleaner() static void buf_flush_page_cleaner()
{ {
my_thread_init(); my_thread_init();
my_thread_set_name("ib_page_cleaner");
#ifdef UNIV_PFS_THREAD #ifdef UNIV_PFS_THREAD
pfs_register_thread(page_cleaner_thread_key); pfs_register_thread(page_cleaner_thread_key);
#endif /* UNIV_PFS_THREAD */ #endif /* UNIV_PFS_THREAD */

View file

@ -530,6 +530,7 @@ srv_print_master_thread_info(
static void thread_pool_thread_init() static void thread_pool_thread_init()
{ {
my_thread_init(); my_thread_init();
my_thread_set_name("ib_tpool_worker");
pfs_register_thread(thread_pool_thread_key); pfs_register_thread(thread_pool_thread_key);
} }
static void thread_pool_thread_end() static void thread_pool_thread_end()

View file

@ -577,6 +577,7 @@ pthread_handler_t ma_checkpoint_background(void *arg)
PAGECACHE_FILE *UNINIT_VAR(kfile); /**< index file currently being flushed */ PAGECACHE_FILE *UNINIT_VAR(kfile); /**< index file currently being flushed */
my_thread_init(); my_thread_init();
my_thread_set_name("ma_checkpoint_background");
DBUG_PRINT("info",("Maria background checkpoint thread starts")); DBUG_PRINT("info",("Maria background checkpoint thread starts"));
DBUG_ASSERT(interval > 0); DBUG_ASSERT(interval > 0);

View file

@ -19,12 +19,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/
#include "mysqld_error.h" #include "mysqld_error.h"
#include <liburing.h> #include <liburing.h>
#include <pthread.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <stdexcept> #include <stdexcept>
#include <my_sys.h>
namespace namespace
{ {
@ -139,6 +141,7 @@ public:
private: private:
static void thread_routine(aio_uring *aio) static void thread_routine(aio_uring *aio)
{ {
my_thread_set_name("io_uring_wait");
for (;;) for (;;)
{ {
io_uring_cqe *cqe; io_uring_cqe *cqe;

View file

@ -21,7 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/
# include <cstdio> # include <cstdio>
# include <libaio.h> # include <libaio.h>
# include <sys/syscall.h> # include <sys/syscall.h>
# include <pthread.h>
# include <my_sys.h>
/** /**
Invoke the io_getevents() system call, without timeout parameter. 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) static void getevent_thread_routine(aio_linux *aio)
{ {
my_thread_set_name("my_getevents");
/* /*
We collect events in small batches to hopefully reduce the We collect events in small batches to hopefully reduce the
number of system calls. number of system calls.