意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

2022-07-15 mysql接收新连接处理

来源:恒创科技 编辑:恒创科技编辑部
2023-12-21 16:17:59


目录

​​摘要:​​


2022-07-15 mysql接收新连接处理

​​流程处理:​​

​​主线程接收请求, 创建新线程:​​

​​子线程开始处理请求:​​

​​时序流程:​​


摘要:

简要分析mysql接收新连接的处理

流程处理:主线程接收请求, 创建新线程:
(gdb) bt
#0 Per_thread_connection_handler::add_connection (this=0x5e7a4d0, channel_info=0x7dc3430) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/conn_handler/connection_handler_per_thread.cc:417
#1 0x0000000001db0f66 in Connection_handler_manager::process_new_connection (this=0x5e277a0, channel_info=0x7dc3430)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/conn_handler/connection_handler_manager.cc:275
#2 0x0000000001d73037 in Connection_acceptor<Mysqld_socket_listener>::connection_event_loop (this=0x7dc18a0)
at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/conn_handler/connection_acceptor.h:75
#3 0x0000000001d6a47e in mysqld_main (argc=115, argv=0x5e27c48) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/mysqld.cc:5199
#4 0x0000000001d61097 in main (argc=8, argv=0x7ffdd55cdb28) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/main.cc:32
子线程开始处理请求:
(gdb) c
Continuing.
[New Thread 0x7fdc80137700 (LWP 11313)]
[Switching to Thread 0x7fdc80137700 (LWP 11313)]

Breakpoint 2, pfs_spawn_thread (arg=0x99ee3f0) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/perfschema/pfs.cc:2197
2197 (*user_start_routine)(user_arg);
(gdb) bt
#0 pfs_spawn_thread (arg=0x99ee3f0) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/storage/perfschema/pfs.cc:2197
#1 0x00007fdcd505eea5 in start_thread (arg=0x7fdc80137700) at pthread_create.c:307
#2 0x00007fdcd3495b0d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) p user_start_routine
$1 = (void *(*)(void *)) 0x2597a15 <handle_connection(void*)>
(gdb) s
handle_connection (arg=0x7dc3430) at /data/jenkins/workspace/stonedb5.7-zsl-centos7.9/sql/conn_handler/connection_handler_per_thread.cc:251
251 Global_THD_manager *thd_manager= Global_THD_manager::get_instance();
时序流程:

注意:

clone系统调用返回两次, 一次父线程, 一次为新创建的子线程冷色调为主线程的处理,暖色调为新的子线程的处理

2022-07-15 mysql接收新连接处理_centos

关键函数:Per_thread_connection_handler::add_connection
bool Per_thread_connection_handler::add_connection(Channel_info* channel_info)
{
int error= 0;
my_thread_handle id;

DBUG_ENTER("Per_thread_connection_handler::add_connection");

// Simulate thread creation for test case before we check thread cache
DBUG_EXECUTE_IF("fail_thread_create", error= 1; goto handle_error;);

if (!check_idle_thread_and_enqueue_connection(channel_info))
DBUG_RETURN(false);

/*
There are no idle threads avaliable to take up the new
connection. Create a new thread to handle the connection
*/
channel_info->set_prior_thr_create_utime();
error= mysql_thread_create(key_thread_one_connection, &id,
&connection_attrib,
handle_connection,
(void*) channel_info);
#ifndef NDEBUG
handle_error:
#endif // !NDEBUG

if (error)
{
connection_errors_internal++;
if (!create_thd_err_log_throttle.log())
sql_print_error("Can't create thread to handle new connection(errno= %d)",
error);
channel_info->send_error_and_close_channel(ER_CANT_CREATE_THREAD,
error, true);
Connection_handler_manager::dec_connection_count();
DBUG_RETURN(true);
}

Global_THD_manager::get_instance()->inc_thread_created();
DBUG_PRINT("info",("Thread created"));
DBUG_RETURN(false);
}
mysql_thread_create
#ifdef HAVE_PSI_THREAD_INTERFACE
#define mysql_thread_create(K, P1, P2, P3, P4) \
inline_mysql_thread_create(K, P1, P2, P3, P4)
#else
#define mysql_thread_create(K, P1, P2, P3, P4) \
my_thread_create(P1, P2, P3, P4)
#endif
int my_thread_create(my_thread_handle *thread, const my_thread_attr_t *attr,
my_start_routine func, void *arg)
{
#ifndef _WIN32
return pthread_create(&thread->thread, attr, func, arg);
#else
struct thread_start_parameter *par;
unsigned int stack_size;

par= (struct thread_start_parameter *)malloc(sizeof(*par));
if (!par)
goto error_return;

par->func= func;
par->arg= arg;
stack_size= attr ? attr->dwStackSize : 0;

thread->handle= (HANDLE)_beginthreadex(NULL, stack_size, win_thread_start,
par, 0, &thread->thread);

if (thread->handle)
{
/* Note that JOINABLE is default, so attr == NULL => JOINABLE. */
if (attr && attr->detachstate == MY_THREAD_CREATE_DETACHED)
{
/*
Close handles for detached threads right away to avoid leaking
handles. For joinable threads we need the handle during
my_thread_join. It will be closed there.
*/
CloseHandle(thread->handle);
thread->handle= NULL;
}
return 0;
}

my_osmaperr(GetLastError());
free(par);

error_return:
thread->thread= 0;
thread->handle= NULL;
return 1;
#endif
}
pfs_spawn_thread
extern "C" void* pfs_spawn_thread(void *arg)
{
PFS_spawn_thread_arg *typed_arg= (PFS_spawn_thread_arg*) arg;
void *user_arg;
void *(*user_start_routine)(void*);

PFS_thread *pfs;

/* First, attach instrumentation to this newly created pthread. */
PFS_thread_class *klass= find_thread_class(typed_arg->m_child_key);
if (likely(klass != NULL))
{
pfs= create_thread(klass, typed_arg->m_child_identity, 0);
if (likely(pfs != NULL))
{
pfs->m_thread_os_id= my_thread_os_id();
clear_thread_account(pfs);

pfs->m_parent_thread_internal_id= typed_arg->m_thread_internal_id;

memcpy(pfs->m_username, typed_arg->m_username, sizeof(pfs->m_username));
pfs->m_username_length= typed_arg->m_username_length;

memcpy(pfs->m_hostname, typed_arg->m_hostname, sizeof(pfs->m_hostname));
pfs->m_hostname_length= typed_arg->m_hostname_length;

set_thread_account(pfs);
}
}
else
{
pfs= NULL;
}
my_thread_set_THR_PFS(pfs);

/*
Secondly, free the memory allocated in spawn_thread_v1().
It is preferable to do this before invoking the user
routine, to avoid memory leaks at shutdown, in case
the server exits without waiting for this thread.
*/
user_start_routine= typed_arg->m_user_start_routine;
user_arg= typed_arg->m_user_arg;
my_free(typed_arg);

/* Then, execute the user code for this thread. */
(*user_start_routine)(user_arg);

return NULL;
}
上一篇: 2022-07-15 mysql/stonedb子查询校验exists流程分析 下一篇: 2022-07-15 mysql/stonedb子查询性能分析-FindOneInsidePack