MySQL 5.7: 短連接優化

jopen 10年前發布 | 20K 次閱讀 MySQL 數據庫服務器

盡管比較罕見,但某些場景還是存在著短連接,即用戶執行完請求后,很快斷開會話。伴隨著頻繁創建/銷毀連接的過程。

官方博客:

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平臺下面比較常用的類.

MySQL 5.7: 短連接優化

 

增加全局變量:

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!