MySQL 服務端核心進程 mysqld 圍繞連接處理展開一切工作。本文基於源碼 (mysqld.cc) 深度剖析連接處理主流程:main() → win_main() → handle_connections_methods() → 三類連接監聽線程 → 服務線程池 → 命令分發執行,還原高併發連接處理的內核邏輯。
main()
→ mysqld_main()
→ win_main() // 初始化:存儲引擎、權限、網絡、線程池等
→ handle_connections_methods() // 連接處理總入口
static void handle_connections_methods() {
mysql_mutex_lock(&LOCK_thread_count);
mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL);
handler_count = 0;
// 1. 命名管道監聽 (Windows 專用)
handler_count++;
mysql_thread_create(key_thread_handle_con_namedpipes, &hThread,
&connection_attrib, handle_connections_namedpipes, 0);
// 2. Socket 監聽 (核心、跨平台)
handler_count++;
mysql_thread_create(key_thread_handle_con_sockets, &hThread,
&connection_attrib, handle_connections_sockets_thread, 0);
// 3. 共享內存監聽 (Windows 嵌入式場景)
handler_count++;
mysql_thread_create(key_thread_handle_con_sharedmem, &hThread,
&connection_attrib, handle_connections_shared_memory, 0);
// 等待所有監聽線程退出
while (handler_count > 0)
mysql_cond_wait(&COND_handler_count, &LOCK_thread_count);
mysql_mutex_unlock(&LOCK_THREAD_COUNT);
}
核心洞察:MySQL 同時支援三種通信方式,**Socket (TCP/IP) 是通用首選**,命名管道與共享內存用於 Windows 本地高效通信/嵌入式場景。
select() 監聽端口 (預設 3306)THD (Thread Handle Data) 對象void create_thread_to_handle_connection(THD *thd) {
if (cached_thread_count > wake_thread) {
// 喚醒緩存線程
mysql_cond_signal(&COND_thread_cache);
} else {
// 創建新服務線程
mysql_thread_create(key_thread_one_connection, &thd->real_id,
&connection_attrib, handle_one_connection, (void*)thd);
}
}
線程池機制:斷開連接後線程不銷毀,放入緩存池 (cached_thread_count),新連接優先複用,減少創建銷毀開銷。
handle_one_connection()
→ do_handle_one_connection()
→ init_new_connection_thread() // 線程初始化、認證
→ init_new_connection_handler_thread()
→ do_command() // 命令主迴圈
→ dispatch_command() // 命令分發 (COM_QUERY, COM_STMT_PREPARE 等)
→ mysql_parse() // SQL 解析 (詞法/語法分析)
→ mysql_execute_command() // 執行計畫生成與執行
[主進程 mysqld]
│
├─ [監聽線程 1] handle_connections_namedpipes
├─ [監聽線程 2] handle_connections_sockets ── select() ── 接受連接
│ │
│ └─ 創建 THD + VIO
│ │
│ └─ create_thread_to_handle_connection()
│ │
│ ├─ 緩存線程池 (優先)
│ └─ 新建線程 handle_one_connection()
│ │
│ └─ do_command() 迴圈
│ │
│ ├─ COM_QUERY → mysql_parse → mysql_execute_command
│ ├─ COM_STMT_PREPARE → prepare
│ ├─ COM_STMT_EXECUTE → execute
│ └─ COM_QUIT → 清理 THD、歸還線程池
│
└─ [監聽線程 3] handle_connections_shared_memory
sql/mysqld.cc:入口、初始化、連接管理主流程sql/sql_connect.cc:handle_one_connection、認證邏輯sql/sql_parse.cc:dispatch_command、mysql_parse、mysql_execute_commandsql/sql_class.h:THD 類定義 (核心巨型類)sql/vio/viosocket.c:VIO Socket 實現sql/threadpool/:線程池插件實現 (Enterprise/Percona)| 源碼知識點 | 運維/開發啟發 |
|---|---|
| THD 複用機制 | 長連接池減少認證開銷,但需防 THD 狀態洩漏 (預處理語句、臨時表、用戶變量) |
| 線程緩存池 | thread_cache_size 設置過小導致頻繁創建銷毀線程,過大佔用記憶體 |
| VIO 統一抽象 | SSL 加密只需在 VIO 層啟用,上層邏輯無感 |
| select() 監聽 | 單線程 accept 可能成為極高併發瓶頸 (解決:多監聽線程、REUSEPORT、epoll/kqueue) |
| do_command 迴圈 | 慢查詢阻塞服務線程,導致線程池耗盡 (解決:只讀副本、查詢超時、異步執行) |
MySQL 連接處理 = 多協議監聽線程 + THD 會話上下文 + VIO 統一 IO + 線程池複用 + 命令分發執行管線。源碼級理解此流程,能精準定位「連接數飆升、線程池耗盡、認證延遲、SSL 握手失敗、慢查詢阻塞」等生產疑難雜症的根因層級。