在 MySQL 中,指定連線主機為 127.0.0.1 或 localhost 雖然都指向本機,但底層的連線機制卻截然不同,這直接影響權限匹配與連線效能。
127.0.0.1 或 localhost.localdomain。localhost。MySQL 權限表(mysql.user)中 Host 欄位嚴格區分 localhost、127.0.0.1、::1 等值。若使用者帳號僅授權 'user'@'localhost',則使用 -h 127.0.0.1 連線會被拒絕,反之亦然。
實測驗證:
shell> mysql -h 127.0.0.1 -u root -p
mysql> status;
Connection: 127.0.0.1 via TCP/IP
Current user: root@localhost <-- 注意:伺服器回報 user 為 root@localhost
shell> mysql -h localhost -u root -p
mysql> status;
Connection: Localhost via UNIX socket
Current user: root@localhost
某專案中,Apache + PHP 環境下使用 mysql_connect('localhost', ...) 失敗,報錯 Can't connect to local MySQL server through socket...,但命令列 php test.php 卻能正常連線。
原因: PHP 在 Web 模組模式下解析 localhost 時,嘗試尋找 Unix Socket 檔(通常在 /tmp/mysql.sock 或 /var/lib/mysql/mysql.sock),但實際 Socket 路徑與 PHP 預期不符,或 Socket 檔不存在/權限不足。而命令列 PHP 可能讀取了不同的 php.ini 或環境變數。
解決方案:
localhost 改為 127.0.0.1,強制走 TCP/IP 繞過 Socket 問題。php.ini 或 MySQL 設定檔(my.cnf 的 [client] 區段)中明確指定 socket = /path/to/mysql.sock。my.cnf 的 [mysql] 區段加入 protocol=tcp,重啟 MySQL 後所有 localhost 連線改走 TCP。Windows 無 Unix Socket 機制,localhost 實際上經由 TCP/IP 回環介面解析為 127.0.0.1,兩者行為一致。但若 hosts 檔未正確映射 127.0.0.1 localhost,可能導致解析失敗。
127.0.0.1,避免 Socket 路徑問題。my.cnf、php.ini、應用程式設定三方 Socket 路徑一致,並授權 'user'@'localhost'。'user'@'localhost'、'user'@'127.0.0.1'、'user'@'::1' 三組帳號,或使用 'user'@'%'(謹慎評估安全性)。