經典錯誤:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)。本質是**客戶端尋找 Socket 檔案路徑與服務端實際建立路徑不一致**。徹底解決需理解 Socket 機制並精準修正。
$ mysql -u root -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
# 嘗試重啟無效
$ ./mysql.server restart
Shutting down MySQL... [ OK ]
Starting MySQL... [ OK ]
$ mysql -u root -p
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
# 1. 檢查服務端實際 Socket 路徑 (my.cnf)
$ grep -n socket /etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/my.cnf 2>/dev/null
# 輸出範例:
# /etc/my.cnf: socket = /opt/mysql/mysql.sock
# /etc/my.cnf: socket = /opt/mysql/mysql.sock
# 2. 客戶端預設尋找路徑
# Linux 預設 /tmp/mysql.sock,或編譯時指定 --with-unix-socket-path
# mysql 客戶端讀取 [client] 區段 socket 參數,若無則用編譯時預設
結論:服務端建立在 /opt/mysql/mysql.sock,客戶端去 /tmp/mysql.sock 找,**路徑不一致**導致連線失敗。
# 確認服務端 Socket 實際存在
ls -l /opt/mysql/mysql.sock
# srwxrwxrwx 1 mysql mysql 0 Jan 15 10:00 /opt/mysql/mysql.sock
# 建立軟連結到客戶端預設路徑
ln -s /opt/mysql/mysql.sock /tmp/mysql.sock
# 立即驗證
mysql -u root -p
# 成功連線!
原理:Linux Socket 檔案屬特殊檔案類型 (s),軟連結同樣保持 Socket 語義,客戶端連接 /tmp/mysql.sock 實際導向 /opt/mysql/mysql.sock。
# 編輯 my.cnf (通常 /etc/my.cnf 或 /etc/mysql/my.cnf)
vim /etc/my.cnf
[mysqld]
socket = /tmp/mysql.sock # 統一為客戶端預設路徑,或雙方同指定一致路徑
[client]
socket = /tmp/mysql.sock # 關鍵:客戶端讀取此處決定連線路徑
# 重啟服務生效
systemctl restart mysqld
# 或
service mysql restart
優點:標準化配置,避免未來升級/遷移再現問題。
mysql -u root -p -S /opt/mysql/mysql.sock
# 或
mysql -u root -p --socket=/opt/mysql/mysql.sock
export MYSQL_UNIX_PORT=/opt/mysql/mysql.sock
# 加入 ~/.bashrc 或 /etc/profile 永久生效
mysql -u root -p # 自動使用環境變數路徑
若 ls /opt/mysql/mysql.sock 不存在,說明 MySQL 服務**未成功啟動**或**啟動失敗**:
tail -f /var/log/mysql/error.log 或 /opt/mysql/data/*.errdatadir 權限錯誤、innodb_force_recovery、端口佔用、配置語法錯誤、SELinux/AppArmor 阻擋。#!/bin/bash
# check_mysql_socket.sh
SOCKET_CNF=$(grep -h '^socket' /etc/my.cnf /etc/mysql/my.cnf 2>/dev/null | head -1 | awk -F= '{print $2}' | xargs)
SOCKET_CNF=${SOCKET_CNF:-/tmp/mysql.sock}
SOCKET_CLIENT=$(mysql --print-defaults 2>/dev/null | grep -o '\-\-socket=[^ ]*' | cut -d= -f2)
SOCKET_CLIENT=${SOCKET_CLIENT:-/tmp/mysql.sock}
echo "Server socket (my.cnf): $SOCKET_CNF"
echo "Client socket (default): $SOCKET_CLIENT"
if [ -S "$SOCKET_CNF" ]; then
echo "✓ Server socket file EXISTS"
else
echo "✗ Server socket file MISSING - MySQL may not be running"
fi
if [ "$SOCKET_CNF" = "$SOCKET_CLIENT" ]; then
echo "✓ Paths MATCH"
else
echo "⚠ Paths MISMATCH - Run: ln -s $SOCKET_CNF $SOCKET_CLIENT"
fi
ERROR 2002 ... /tmp/mysql.sock 核心是**客戶端與服務端 Socket 路徑不一致**。
ln -s /actual/path/mysql.sock /tmp/mysql.sock 秒級生效。my.cnf 同時設定 [mysqld] socket 和 [client] socket 為同一路徑。-S /path 或環境變數 MYSQL_UNIX_PORT。理解 Unix Domain Socket 是本地進程通訊的特殊檔案,掌握路徑協商機制,此錯誤不再是障礙。