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: 短連接優化