基於 MySQL 5.6 源碼,剖析 handle_slave_io → safe_connect → mysql_real_connect 的完整調用鏈與網絡協議細節。
handle_slave_io() // Slave IO 主循環
→ safe_connect() // 封裝重試邏輯
→ mysql_real_connect() // C API 核心連接函數
→ vio_socket_connect() // 底層 Socket 連接
→ cli_safe_read() // 讀取初始握手包
→ run_plugin_auth() // 認證插件交互
→ mysql_select_db() // 選擇默認庫
| 階段 | 方向 | 關鍵數據結構 | 源碼關鍵點 |
|---|---|---|---|
| 1. 建立 Socket 連接 | C→S | VIO 結構、unix_socket 或 TCP | vio_new(), vio_socket_connect() |
| 2. 讀取初始握手包 | S→C | protocol_version, server_version, connection_id, scramble_part1, capabilities, charset, status | cli_safe_read(), 解析握手包字段 |
| 3. 發送認證響應包 | C→S | client_capabilities, max_packet, charset, username, auth_response (scramble 加密密碼), db(可選), plugin_name(可選) | native_password_auth_client(), scramble(), vio_write_packet() |
| 4. 讀取認證結果包 | S→C | OK_Packet / ERR_Packet / AuthSwitchRequest | cli_read_change_user_result() |
| 5. 選擇默認數據庫 | C→S | COM_INIT_DB 命令包 | mysql_select_db() → simple_command(COM_INIT_DB) |
1 byte protocol_version (10)
N string[NUL] server_version
4 uint32 connection_id (thread_id)
8 string auth_plugin_data_part_1
1 byte 0x00 (filler)
2 uint16 capabilities_low
1 byte charset
2 uint16 status_flags
2 uint16 capabilities_high
1 byte auth_plugin_data_len
10 string reserved (0x00...)
N string auth_plugin_data_part_2 ($len = MAX(13, len-8))
N string[NUL] auth_plugin_name (if CLIENT_PLUGIN_AUTH)
4 uint32 client_capabilities (CLIENT_PROTOCOL_41 always set)
4 uint32 max_packet_size
1 byte charset
23 string reserved (0x00...)
N string[NUL] username
N lenenc-str auth_response (scramble 加密後的密碼)
N string[NUL] database (if CLIENT_CONNECT_WITH_DB)
N string[NUL] auth_plugin_name (if CLIENT_PLUGIN_AUTH)
N lenenc-str key-value pairs (if CLIENT_CONNECT_ATTRS)
1 byte 0x00 (OK) / 0xFF (ERR) / 0xFE (EOF/AuthSwitch)
... 根據類型解析 affected_rows, insert_id, status_flags, warnings, info
sql-common/client.c:mysql_real_connect 主流程sql-common/client_plugin.c:認證插件框架 run_plugin_authsql/auth/auth_common.cc:native_password_auth_client 實現vio/vio.c:VIO 抽象層,Socket/SSL/命名管道統一接口sql/slave.cc:handle_slave_io、safe_connect、register_slave_on_masterCOM_REGISTER_SLAVE 註冊從庫信息(server_id、hostname、user、password、port)COM_BINLOG_DUMP 請求 binlog(位置、文件名、server_id、flags)掌握協議細節,可實現自定義代理、連接池、異構同步工具,或排查「連得上卻查不了」的詭異問題。