首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 服務器連接處理流程源碼級淺析:從監聽到線程池

     編輯:MySQL 資料庫相關知識

核心入口:mysqld_main() → win_main()

MySQL 服務器主進程 mysqld 從 mysqld_main()(sql/mysqld.cc)啟動,調用 win_main() 完成:

  1. 全局變量初始化、配置解析、插件注冊。
  2. 存儲引擎初始化(InnoDB 紅o log、buffer pool、錯誤碼映射)。
  3. 權限表加載、時區表構建、字符集初始化。
  4. 網絡層初始化:創建 TCP/IP socket、Unix domain socket、Named Pipe、Shared Memory 監聽端點。

連接分發總線:handle_connections_methods()

static void handle_connections_methods(void) {
  mysql_mutex_lock(&LOCK_thread_count);
  mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL);
  handler_count = 0;

  /* 1. Named Pipe (Windows) */
  handler_count++;
  mysql_thread_create(key_thread_handle_con_namedpipes, &hThread,
                      &connection_attrib, handle_connections_namedpipes, 0);

  /* 2. TCP/IP Socket (主流) */
  handler_count++;
  mysql_thread_create(key_thread_handle_con_sockets, &hThread,
                      &connection_attrib, handle_connections_sockets_thread, 0);

  /* 3. Shared Memory (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);
}

三大監聽線程並行啟動,**TCP/IP Socket 承載 99%+ 生產流量**。

Socket 監聽循環:handle_connections_sockets()

  1. 調用 select()/poll()/epoll() 監聽端口(默認 3306)。
  2. 新連接到達 → accept() 獲取客戶端 socket fd。
  3. 創建 THD(Thread Handle Data)對象,**連接生命周期的核心上下文**:
    • 線程 ID、連接 ID、用戶/權限信息。
    • 查詢緩衝區、解析樹、執行計劃、結果集。
    • Vio 結構體:封裝 socket 讀寫、SSL、壓縮、超時邏輯。
  4. 調用 create_thread_to_handle_connection(thd) 分發給工作線程。

工作線程池:create_thread_to_handle_connection()

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);
  }
}
  • 線程緩存機制:斷開連接後線程不銷毀,進入 thread_cache 等待復用(受 thread_cache_size 限制)。
  • 減少 pthread_create/open 銷毀開銷,提升高併發短連接性能。

工作線程主循環:handle_one_connection()

handle_one_connection()
  → do_handle_one_connection()
    → init_new_connection_thread()      // 安全上下文、字符集、事務隔離級別
    → do_command()                      // 命令分發總入口
      → dispatch_command()
        → com_data → mysql_parse()      // SQL 解析器入口
          → mysql_execute_command()     // 執行器入口
            → 根據 SQL 類型分發:
              SELECT → JOIN::exec()
              INSERT/UPDATE/DELETE → write_record()
              COMMIT/ROLLBACK → ha_commit/rollback()
              ...
    → 清理 THD、歸還線程緩存或退出

關鍵數據結構:THD 與 Vio

結構核心字段作用
THDthread_id, query_string, lex, stmt_arena, transaction, security_context, net, vio單條連接的完整上下文,「交際花」贯穿解析、優化、執行、發送全程
Viotype (SOCKET/SSL/PIPE/MEMORY), sd (socket fd), read/write 函數指針, timeout網絡 IO 抽象層,屏蔽傳輸協議差異

性能調優映射表

現象源碼關鍵點調優參數
連接建立慢accept() → THD 初始化 → 線程創建/喚醒thread_cache_size、back_log、skip_name_resolve
併發連接數擊穿cached_thread_count 耗盡 → 頻繁 pthread_createmax_connections、thread_cache_size、連接池中間件
SSL 握手延遲Vio::ssl_accept()ssl_cert/key、硬件加速、TLS 1.3
長連接洩漏THD 未正確清理 → 線程不歸還緩存wait_timeout、interactive_timeout、應用層連接池回收

總結

MySQL 連接處理遵循 **Reactor + Thread-Per-Connection + Thread-Cache** 模式:
主線程 select/epoll 監聽 → 接受連接構建 THD → 分發給工作線程(優先復用緩存) → 工作線程循環 do_command → dispatch → parse → execute。
理解此流程,可精準定位「連接風暴、線程疲勞、SSL 瓶頸、長連接洩漏」等生產疑難雜癥,並通過參數與架構調優實現量級提升。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved