MySQL 5.7: 短连接优化
尽管比较罕见,但某些场景还是存在着短连接,即用户执行完请求后,很快断开会话。伴随着频繁创建/销毁连接的过程。
官方博客:
http://mysqlserverteam.com/improving-connectdisconnect-performance/
对应worklog: http://dev.mysql.com/worklog/task/?id=6606
在之前的版本中, THD/NET/VIO总是由接受连接请求的线程来完成,如果是长连接这没有问题,但如果都是短连接的话,就会应先main线程接受新连接请求的效率,在WL#6606中,THD和NET的初始化被移动到worker线程来完成。
0. background
增加新目录sql/conn_handler,定义了大量的类来处理连接部分的逻辑。下图简单描述了下各个类的关系,可能不是很全面,只涉及linux平台下面比较常用的类.
增加全局变量:
Connection_acceptor
Connection_acceptor作为接受socket请求的基类,封装了多种socket请求方式.
Connection_acceptor::m_listener存储了对应的listener对象.
1.主线程监听请求:mysqld_main
初始化 mysqld_socket_acceptor
mysqld.cc:1692 Mysqld_socket_listener *mysqld_socket_listener=
1693 new (std::nothrow) Mysqld_socket_listener(bind_addr_str,
1694 mysqld_port, back_log,
1695 mysqld_port_timeout,
1696 unix_sock_name);
1697 if (mysqld_socket_listener == NULL)
1698 unireg_abort(1);
1699
1700 mysqld_socket_acceptor=
1701 new (std::nothrow) Connection_acceptor(mysqld_socket_listener);
1702 if (mysqld_socket_acceptor == NULL)
1703 {
1704 delete mysqld_socket_listener;
1705 unireg_abort(1);
1706 }
1707
1708 if (mysqld_socket_acceptor->init_connection_acceptor())
1709 {
1710 delete mysqld_socket_acceptor;
1711 unireg_abort(1);
1712 }
根据thread_handling初始化connection hander:
7381 #ifndef EMBEDDED_LIBRARY
7382 if (Connection_handler_manager::init())
7383 {
7384 sql_print_error(“Could not allocate memory for connection handling”);
7385 return 1;
7386 }
7387 #endif
我们通常用的one thread one connection对应的类为Per_thread_connection_handler
进入监听connection_event_loop —> Mysqld_socket_listener::listen_for_connection_event
当获取到一个新的监听请求时,会创建一个Channel_info类,用来存储用户的socket信息。
2. 处理新连接
当从listen_for_connection_event获得新的连接请求后,调用Mgr->process_new_connection处理新请求
在检查是否超出连接数限制后,调用Per_thread_connection_handler::add_connection, 调度thread cache的线程后创建新的线程
handle_connection为worker线程入口,传递的参数为对应用户的Channel_info对象,包含了对应的新请求socket,在该函数中进行THD/NET/VIO初始化
sql/conn_handler/connection_handler_per_thread.cc:259
260 for (;;)
261 {
262 THD *thd= init_new_thd(channel_info);
主要代码:
3.WL#7260对LOCK_thread_count锁进行了拆分
因为在完成上述优化后,性能测试发现瓶颈在LOCK_thread_count锁上,因此在WL#7260中对锁进行了拆分
主要修改摘录自commit log,讲的很清楚,不重复描述了:
LOCK_thread_cache is introduced to protect the thread cache used
by the default connection handler (one thread per connection).Synchronization during startup of signal handler thread is now
done using LOCK_start_signal_handler.Synchronization during shutdown of main thread connection
listening is now done using LOCK_socket_listener_active.The global thread_id counter is now incremented using atomics,
rather than being protected by LOCK_thd_count.THD::current_linfo is now protected by THD::LOCK_thd_data rather
than LOCK_thd_count.max_used_connections is now reset under protection of
LOCK_connection_count rather than LOCK_thd_count.
worlog连接:
http://dev.mysql.com/worklog/task/?id=7260
代码连接:
http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/6844
原创文章,转载请注明: 转载自Simple Life
本文链接地址: MySQL 5.7: 短连接优化