MySQL 创建线程 插件_mysql创建线程处理链接请求

mysqld通过 RUN_HOOK(server_state, before_handle_connection, (NULL)); 调用

/**

Thread handler for a connection

@param arg Connection object (Channel_info)

This function (normally) does the following:

- Initialize thread // 初始化线程

- Initialize THD to be used with this thread // 初始化THD 信息

- Authenticate user // 权限认证

- Execute all queries sent on the connection // 处理query

- Take connection down

- End thread / Handle next connection using thread from thread cache

*/

extern "C" void *handle_connection(void *arg)

{

Global_THD_manager *thd_manager= Global_THD_manager::get_instance();

Connection_handler_manager *handler_manager=

Connection_handler_manager::get_instance();

Channel_info* channel_info= static_cast(arg);

bool pthread_reused MY_ATTRIBUTE((unused))= false;

// my_thread_init 给线程分配内存空间,如果正常返回false, 否则返回true

if (my_thread_init())

{

connection_errors_internal++;

channel_info->send_error_and_close_channel(ER_OUT_OF_RESOURCES, 0, false);

handler_manager->inc_aborted_connects();

Connection_handler_manager

::dec_connection_count(channel_info->is_on_extra_port());

delete channel_info;

my_thread_exit(0);

return NULL;

}

for (;;)

{

// Save this here as init_new_thd destroys channel_info

bool extra_port_connection= channel_info->is_on_extra_port();

THD *thd= init_new_thd(channel_info);

if (thd == NULL)

{

connection_errors_internal++;

handler_manager->inc_aborted_connects();

Connection_handler_manager::dec_connection_count(extra_port_connection);

break; // We are out of resources, no sense in continuing.

}

DBUG_EXECUTE_IF("after_thread_setup",

{

const char act[]=

"now signal thread_setup";

DBUG_ASSERT(!debug_sync_set_action(thd,

STRING_WITH_LEN(act)));

};);

#ifdef HAVE_PSI_THREAD_INTERFACE

if (pthread_reused)

{

/*

Reusing existing pthread:

Create new instrumentation for the new THD job,

and attach it to this running pthread.

*/

PSI_thread *psi= PSI_THREAD_CALL(new_thread)

(key_thread_one_connection, thd, thd->thread_id());

PSI_THREAD_CALL(set_thread_os_id)(psi);

PSI_THREAD_CALL(set_thread)(psi);

}

#endif

#ifdef HAVE_PSI_THREAD_INTERFACE

/* Find the instrumented thread */

PSI_thread *psi= PSI_THREAD_CALL(get_thread)();

/* Save it within THD, so it can be inspected */

thd->set_psi(psi);

#endif /* HAVE_PSI_THREAD_INTERFACE */

mysql_thread_set_psi_id(thd->thread_id());

mysql_thread_set_psi_THD(thd);

mysql_socket_set_thread_owner(

thd->get_protocol_classic()->get_vio()->mysql_socket);

// thd_manager 添加这个线程的thd信息

thd_manager->add_thd(thd);

// thd_prepare_connection 登录认证,ok 返回0, 出错返回1

if (thd_prepare_connection(thd, extra_port_connection))

handler_manager->inc_aborted_connects();

else

{

// 检测链接是否依然存活

while (thd_connection_alive(thd))

{

// 执行query,这个会阻塞等待客户端发query,等待超过"net_wait_timeout"后会断开链接

if (do_command(thd))

break;

}

// 结束链接

end_connection(thd);

}

close_connection(thd, 0, false, false);

thd->get_stmt_da()->reset_diagnostics_area();

thd->release_resources();

#if OPENSSL_VERSION_NUMBER < 0x10100000L

// Clean up errors now, before possibly waiting for a new connection.

ERR_remove_state(0);

#endif

thd_manager->remove_thd(thd);

Connection_handler_manager::dec_connection_count(extra_port_connection);

#ifdef HAVE_PSI_THREAD_INTERFACE

/*

Delete the instrumentation for the job that just completed.

*/

thd->set_psi(NULL);

PSI_THREAD_CALL(delete_current_thread)();

#endif /* HAVE_PSI_THREAD_INTERFACE */

delete thd;

if (abort_loop) // Server is shutting down so end the pthread.

break;

channel_info= Per_thread_connection_handler::block_until_new_connection();

if (channel_info == NULL)

break;

pthread_reused= true;

}

my_thread_end();

my_thread_exit(0);

return NULL;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值