Mysql

可以使用 127.0.0.1 連接到虛擬 MySql 實例,但不能使用 localhost

  • December 18, 2021

在本地 VirtualBox 實例上執行 MySql 5.7.33。我已從虛擬伺服器轉發埠 3306,以便在本地訪問。在我的虛擬主機上,我的 /etc/mysql/my.cnf 文件中有這個…

[client]
#password = your_password
port = 3306
socket = /var/run/mysqld/mysqld.sock

[mysqld]
port = 3306
bind-address = 0.0.0.0
datadir = /var/lib/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid

從我的本地機器,我可以使用連接到 MySql 實例

mysql -h 127.0.0.1 -u my_user my_db -p

但是一旦我更改為“localhost”,我就無法再連接

$ mysql -h localhost -u my_user my_db -p
Enter password: 
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

不確定是什麼問題。從我的本地機器(即不是虛擬伺服器),這是為“localhost”返回的……

$ host localhost
localhost has address 127.0.0.1
localhost has IPv6 address ::1

當您指定客戶端-h localhostmysql嘗試使用套接字(即UNIX 域套接字)而不是 TCP。這是 MySQL 及其分支中的一種特殊行為。

但是,由於 MySQL 伺服器在 VM 中執行,因此 mysql 客戶端無法直接訪問伺服器的套接字。UNIX 域套接字只能在共享相同核心的程序之間共享,而主機作業系統(帶有mysql客戶端)在 VM(帶有 MySQL 伺服器)中執行來賓作業系統的情況並非如此。

順便說一句,如果在容器(docker、podman 等)中執行 MySQL 伺服器,那麼您將共享相同的核心,並且還可以共享 UNIX 域套接字。

解決方案 1:SSH 隧道

如果您必須使用套接字,請從您的主機作業系統執行此命令以創建 SSH 隧道(如果出現提示,請輸入密碼):

ssh -L /tmp/mysql.sock:/var/run/mysqld/mysqld.sock $VM_USER@$VM_IPADDR

然後,在主機作業系統上的一個單獨的 shell 中:

mysql -h localhost --protocol=socket -u my_user -p -S /tmp/mysql.sock my_db

您可以從客戶端發出status命令以驗證您確實通過套接字連接。

請注意,您需要在關閉 SSH 隧道後手動刪除本地套接字文件。mysql否則下次嘗試通過新隧道連接時會出現錯誤:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111) 

解決方案 2:“localhost”,但 TCP

如果您只想使用-h localhost,但不關心 Unix 套接字:

$ mysql -h localhost --protocol=tcp -u my_user my_db -p

通過簡單地添加參數--protocol=tcp,您可以強制mysql客戶端通過 TCP 而不是 UNIX 域套接字進行連接。(當連接到埠 3306 已轉發到我的主機作業系統的 podman 容器時,這對我有用127.0.0.1:3306。)

順便說一句,如果您不想mysql每次連接時都編寫這些長命令,您當然可以將部分或全部參數放在文件的一個[client]部分中.my.cnf(注意前導’.’)在你的根目錄中$HOME目錄。/etc/mysql/my.cnf(與您在 VM 上的語法相同。)

引用自:https://dba.stackexchange.com/questions/302856