并不是mysql官方企业版中的实现,只是个人尝试。

概述:
在mysql5.5的企业版中似乎已经提供了真正意义上的线程池功能,由于看不到企业版代码,所以就自己尝试实现了一下。
所谓的真正意义上的是为了区别与5.5之前的实现,5.5之前的实现可以参考我的博文 《 Mysql 中线程管理与连接池代码导读》。具体我们可以参考下图, mysql服务端会为每个客户端连接分配一个线程,这个线程会一直被该连接所占用直到这个连接断开,然后mysql会把这个空闲线程放入连接池以便在新的客户端连接到来的时候重用它。 这导致的一个问题是:如果客户端在空闲的时候不断开连接,那么它就会一直占用服务端一个线程,使得这个线程一直处于空等待状态而不能为其他客户端连接的请求服务。如果有1000个连接,那么服务端就要创建1000个线程,而可能很多时候只有很少的线程是同时在执行的。这就造成了服务端资源的浪费。

mysql线程池释放 mysql线程池优化_mysql线程池释放


上图中我们可以看到一个THD对象,你可以把它理解成客户端连接在服务端的承载体,这个对象记录并包括了客户端连接与请求的所有相关信息。当一个新的客户端连接到来时,mysql服务端就会为这个连接创建一个对应的THD对象。 为客户端连接分配线程,其实就是在该连接对应的THD对象分配一个线程。
所以不难想到,如果我们能在客户端连接空闲的时候把线程中的THD对象调出,使之变成一个空闲线程,在有客户端请求时再把THD对象调入一个空闲线程,执行客户端请求。这样我们就可以节省服务端的线程资源。具体我们可以看下图,图中绿色的部分为新增加的部分。
主要的修改有3个部分:
1. 在服务端thread中添加了超时判断,如果客户端在一个指定的时间段内没有新的请求,那么thread就把对应的THD对象调出。
2. 建立一个数组来保存调出的THD对象。
3. 启动一个后台线程,循环周期性的检查数组中THD对象是否有新的请求,如果有那么把它重新调入一个空闲的thread中。

总的来说这个设计还是基于mysql原有的线程池的实现,只是添加了一个对空闲thd对象的管理。

mysql线程池释放 mysql线程池优化_mysql线程池释放



实现:
1. 首先是该功能的主类:
这个类是个单实例的类,
主要的成员对象有:
m_thd_list.:这个链表用来存放从服务端thread中调出的空闲thd对象,线程把空闲的thd对象添加到该链表尾部。
m_using_list: 该链表中的thd对象会有专门的线程去监控,以等待新的客户端请求。

主要的方法有:
add_thd_to_list_begin: 添加空闲的thd对象到新连接池中(m_thd_list).
load_thd_to_thread: 把有新客户端请求的thd对象调入一个空闲的thread中。

handle_waiting_thd_list: 新连接池线程主函数,周期性地把m_thd_list中新的空闲thd对象移动到m_using_list中,并监控m_using_list中thd对象的新客户端请求。

mysql线程池释放 mysql线程池优化_mysql线程池释放



2. 线程主函数handler_waiting_thd_list的伪代码:




3. 空闲thd调出
mysql等待客户端请求的代码主要位于sql/net_serv.cc中 修改后的代码:
大体上的修改就是: 首先重设了超时间,然后在超时并没有读取任何数据的情况下,让线程停止等待新请求。

然后修改处理客户端请求的主循环(sql/sql_connect.cc), 通过调用add_thd_to_list_begin把thd调入新线程池。



测试:
相关测试报告,后面会补充。。。