如何建立一个连接
首先在mysql有一个监听线程,用来监听所有的数据库连接。当新的连接请求到达之后,会将这个连接请求交给mysqld.cc来处理,下面的处理的函数
pthread_handler_t handle_connections_sockets(void * args)这个线程会从参数里获得连接客户端的信息,并且创建一个新的线程来处理这个连接所有的请求.接着调用 create_new_thread(),而这个函数则用来检查连接数是否超过了最大限制,并且将这个线程放入thread_scheduler, 注意这个过程是线性的,整个函数都有mutex来保护. thread_scheduler.add_connection(thd)有点讲究,它通过一个反射函数(在scheduler.cc里的one_thread_per_connection_scheduler(scheduler_functions * func)),调用了create_thread_to_handle_connection(THD * thd). 在这之前线程并没有创建,而只是创建了一个MySQL自定义的THD类,而在这个函数里而调用了pthread_create()创建一个真正的系统上的线程。首先检查是否还还没有用到的cached thread,如果有直接从cached_thread里取,如果没有那么新建一个, 并且更新thread的一些统计信息.在这里用到的变量有:
cached_thread_count:
wake_thread
thread_created
threads: 是一个保存thread的list;
thread_count, connection_count: 这两个参数是用来记录当前有多少个thread,多少个connection的,来一个连接,在create_new_thread()函数里就会为这两个参数各加1,如果在create_thread_to_handle_connection()里新建物理线程失败,则会再各减1.
那么到这一步,一个thread, connection就建立起来了.
下面来看看如何关闭一个线程的:
sql_connect.cc里,有一个handle_one_connection()来处理所有的connection过来的请求,这个函数在一个while()内调用了do_command()方法,如果客户端发送了一个exit,那么会将thd.killed置成THD::KILL_CONNECTION, 从而这里的while()就退出了,接着调用end_connection(THD * thd), close_connection(), thread_scheduler.end_thread()方法,整个connection的资源全部被释放,结束.
这里需要注意的是,当用户发送了exit并且有了返回值的时候,DB并没有完全释放这个connection,而仅仅是告诉客户端你不能再用了。close_connection之后会调用threadd_scheduler.end_thread(THD * thd),这里又有另外一个反射函数,也就是mysqld.cc里的one_thread_per_connection_end()这个函数.这个函数释放了所有的资源,这些资源有:
调用: THD.cleanup()释放rollback(this), close_thread_tables(this), mysql_ha_cleanup(this), delete_dynamic(), hash_free(), close_temporary_tables(), my_free() 各种变量,sp_cache_clear()清除procedure和function的cache, 释放global_read_lock,
unlink_thread()里将connection_count, thread_count各减1.删除 thd.
如果 cached_thread_count < thread_cache_size,那么将这个线程cache起来. 线程结束
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7682812/viewspace-680845/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/7682812/viewspace-680845/