mysql_real_connect() 是 MySQL C API 建立資料庫連線的核心函數。正確理解每個參數的含義、預設行為及常見陷阱,對開發穩健的 MySQL 客戶端程式至關重要。本文基於官方文檔深度解析各參數,並提供最佳實踐配置模板。
MYSQL *mysql_real_connect(
MYSQL *mysql, // 已初始化的 MYSQL 結構指標
const char *host, // 主機名或 IP
const char *user, // 用戶名
const char *passwd, // 密碼
const char *db, // 預設資料庫
unsigned int port, // TCP 端口
const char *unix_socket,// Unix socket/Windows named pipe 路徑
unsigned long client_flag // 客戶端功能標誌位
);
mysql_init(NULL) 或 mysql_init(&my_struct) 初始化。mysql_options() 設定連線選項(超時、字符集、SSL 等)。host 參數決定連線協議類型,port/unix_socket 為輔助。mysql.user 表中 authentication_string 為空的賬號。USE db)。mysql_select_db()。/tmp/mysql.sock)或 Windows Named Pipe 名稱。MYSQL_UNIX_PORT 環境變數。位元組合,常用標誌:
| 標誌常量 | 功能說明 | 適用場景 |
|---|---|---|
| CLIENT_COMPRESS | 啟用壓縮協議 | 跨公網/低帶寬環境傳輸大量數據 |
| CLIENT_FOUND_ROWS | UPDATE 返回匹配行數而非影響行數 | 需區分「已是目標值」與「實際修改」的業務 |
| CLIENT_IGNORE_SPACE | 允許函數名後有空格 | 兼容非標準 SQL 生成器 |
| CLIENT_INTERACTIVE | 使用 interactive_timeout 替代 wait_timeout | 長連線交互式客戶端(如 CLI 工具) |
| CLIENT_LOCAL_FILES | 啟用 LOAD DATA LOCAL INFILE | 需從客戶端導入本地文件 |
| CLIENT_MULTI_STATEMENTS | 允許單次查詢執行多條 SQL(分號分隔) | 批量執行 DDL/DML、遷移腳本 |
| CLIENT_MULTI_RESULTS | 支援多結果集(存儲過程、多語句) | 配合 MULTI_STATEMENTS 自動啟用 |
| CLIENT_SSL | 使用 SSL 加密連線 | 勿直接設定,應呼叫 mysql_ssl_set() 後自動置位 |
| CLIENT_REMEMBER_OPTIONS | 記住 mysql_options 設定供重連使用 | 需自動重連場景 (MariaDB/Connector/C) |
推薦預設組合:CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS(現代應用常需多語句、存儲過程、自動重連)。
MYSQL *connect_mysql(const char *host, const char *user, const char *pass, const char *db, unsigned int port) {
MYSQL *mysql = mysql_init(NULL);
if (!mysql) { fprintf(stderr, "mysql_init() failed\n"); return NULL; }
// 連線超時 5 秒
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&(int){5});
// 自動重連 (MariaDB/Connector/C 支援)
my_bool reconnect = 1;
mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect);
// 字符集 utf8mb4
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4");
// 讀取選項檔 [client] 區段
mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "myapp");
unsigned long flags = CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS;
if (!mysql_real_connect(mysql, host, user, pass, db, port, NULL, flags)) {
fprintf(stderr, "Connection failed [%d]: %s\n", mysql_errno(mysql), mysql_error(mysql));
mysql_close(mysql);
return NULL;
}
printf("Connected to MySQL %s (Thread ID: %lu)\n", mysql_get_server_info(mysql), mysql_thread_id(mysql));
return mysql;
}
| 錯誤碼 | 含義 | 典型原因與對策 |
|---|---|---|
| CR_CONN_HOST_ERROR | 無法連線到 MySQL Server | 主機名解析失敗、防火牆阻攔、Server 未啟動 |
| CR_CONNECTION_ERROR | 無法連線到本地 MySQL Server | Socket 檔案不存在、權限不足、Server 崩潰 |
| CR_IPSOCK_ERROR | 建立 IP Socket 失敗 | 系統文件描述符耗盡、網路子系統故障 |
| CR_OUT_OF_MEMORY | 記憶體不足 | 進程/系統記憶體耗盡 |
| CR_SOCKET_CREATE_ERROR | 建立 Unix Socket 失敗 | Socket 路徑目錄不存在、權限問題 |
| CR_UNKNOWN_HOST | 主機名解析失敗 | DNS 故障、/etc/hosts 缺失 |
| CR_VERSION_ERROR | 協議版本不匹配 | 極舊客戶端連新 Server 需加 --old-protocol |
| CR_SERVER_LOST | 連線過程中 Server 掛掉 | connect_timeout 過短、Server 啟動中崩潰 |
[client] password="..."。mysql_ssl_set() 必須在 mysql_real_connect() 前呼叫,且 CA 憑證路徑正確。CLIENT_MULTI_STATEMENTS 後,需循環呼叫 mysql_next_result() 處理每個結果集,否則會「Commands out of sync」錯誤。SET NAMES、time_zone、用戶變數)丟失,需在重連回調中恢復。mysql_real_connect() 參數看似繁多,實則邏輯清晰:初始化結構 → 設定選項 → 指定目標與憑證 → 啟用功能標誌。掌握 host 決定協議、client_flag 控制能力、mysql_options() 微調行為三大核心,配合選項檔管理憑證,即可編寫出健壯、可移植、高性能的 MySQL C 客戶端程式。