今天遇到一個很典型、但平常不一定會立刻想到的主機問題:WordPress 後台或 WP-CLI 顯示資料庫連線錯誤,但 MySQL 其實沒有壞,真正壞掉的是 localhost 連線會用到的 MySQL socket。
問題現象
WP-CLI 執行資料庫檢查時出現:
mysqli_real_connect(): (HY000/2002): No such file or directory Can't connect to local MySQL server through socket '/tmp/mysql.sock'
這種錯誤很容易被誤會成資料庫帳號密碼錯誤,或 MySQL 服務掛掉。但如果改成 127.0.0.1 就能連,通常代表問題不是帳密,而是 socket 路徑。
localhost 跟 127.0.0.1 不一樣
在 PHP / MySQL 的世界裡,localhost 跟 127.0.0.1 不只是寫法不同,連線方式也不同。
localhost:通常會走 Unix socket,例如/tmp/mysql.sock或/var/lib/mysql/mysql.sock127.0.0.1:會走 TCP,通常是連本機3306port
所以有時候同一台主機上,DB_HOST 設成 127.0.0.1 可以開,但設成 localhost 就壞掉。這不是玄學,是因為兩者走的路徑不同。
這次真正的原因
這次檢查時發現:
/var/lib/mysql/mysql.sock -> /tmp/mysql.sock /tmp/mysql.sock 不存在
也就是說,PHP 或 MySQL client 以為 socket 在 /var/lib/mysql/mysql.sock,但那其實只是指到 /tmp/mysql.sock 的 symlink。而真正的 /tmp/mysql.sock 不見了,所以所有走 localhost 的連線都可能失敗。
快速判斷指令
遇到類似問題時,可以先用這幾個指令判斷:
php -i | grep -i "mysqli.default_socket" php-fpm -i | grep -i "mysqli.default_socket" find /tmp /run /var/lib/mysql -name "*.sock" -type s 2>/dev/null mysqladmin -hlocalhost ping mysqladmin -h127.0.0.1 ping
如果 mysqladmin -h127.0.0.1 ping 正常,但 mysqladmin -hlocalhost ping 失敗,就很可能是 socket 路徑問題。
修復方式
如果 MySQL 設定本來就是要產生 /tmp/mysql.sock,通常重啟 MySQL 服務就會重建 socket:
systemctl restart mysql
實際服務名稱不一定叫 mysql,可以先查:
systemctl list-units --type=service --all | grep -Ei "mysql|maria|percona" ps aux | grep -Ei "mysqld|mariadbd" | grep -v grep
重建後再確認:
ls -la /tmp/mysql.sock mysqladmin -hlocalhost ping wp db check --allow-root
清 log 時不要清 runtime 檔
這次也順手修正了清 log 腳本的觀念:/tmp 裡面不是所有舊檔都能刪。像 socket、pid、lock 這些不是 log,也不會像 log 一樣長大,刪掉反而可能讓服務連不上。
*.sock:服務通訊用 socket,例如 MySQL、PHP-FPM*.pid:process id 記錄*.lock:鎖定檔,避免程序重複執行
比較安全的做法是:清 log 就清 log,/tmp 只刪一般檔案,不要碰 socket、symlink、pid、lock,也不要掃 systemd 的 private tmp 目錄。
我的結論
如果是 WordPress 主機,遇到資料庫連線錯誤時,不要只看帳密。尤其錯誤訊息是 No such file or directory,第一時間就要想到 socket。
localhost 壞、127.0.0.1 正常,通常就是 socket 問題。這種問題不大,但如果清 log 腳本寫得太粗暴,很容易在半夜把自己家的網站清到開不起來。









