Executando o MySql 5.7.33 em uma instância local do VirtualBox. Eu encaminhei a porta 3306 do servidor virtual para ser acessível localmente. No meu host virtual, tenho isso no meu arquivo /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
Da minha máquina local, posso me conectar à instância do MySql usando
mysql -h 127.0.0.1 -u my_user my_db -p
Mas uma vez que mudo para “localhost”, não consigo mais me conectar
$ 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)
Não tenho certeza qual é o problema. Da minha máquina local (ou seja, não do servidor virtual), isso é retornado para “localhost”…
$ host localhost
localhost has address 127.0.0.1
localhost has IPv6 address ::1
Quando você especificar,
-h localhost
omysql
cliente tentará usar o socket (ou seja , o socket do domínio UNIX ) ao invés do TCP. Este é um comportamento especial no MySQL e suas bifurcações.No entanto, como o servidor MySQL está sendo executado em uma VM, o soquete do servidor não é acessível diretamente ao cliente mysql. Soquetes de domínio UNIX só podem ser compartilhados entre processos que compartilham o mesmo kernel, e este não é o caso de um sistema operacional host (com o
mysql
cliente) executando um sistema operacional convidado em uma VM (com o servidor MySQL).A propósito, se você estiver executando o servidor MySQL em um contêiner (docker, podman, etc.), você estará compartilhando o mesmo kernel e também será possível compartilhar um soquete de domínio UNIX.
Solução 1: túnel SSH
Se você precisar usar o soquete, execute-o no sistema operacional host para criar um túnel SSH (digite a senha se solicitado):
Em seguida, em um shell separado no sistema operacional host:
A partir do cliente, você pode emitir o
status
comando para verificar se está realmente conectado através do soquete.Observe que você precisa excluir manualmente o arquivo de soquete local depois de fechar o túnel SSH. Caso contrário, você receberá um erro na próxima vez que tentar se conectar
mysql
por meio de um novo túnel:Solução 2: "localhost", mas TCP
Se você quer apenas usar
-h localhost
, mas não se importa com soquetes Unix:Simplesmente adicionando o parâmetro
--protocol=tcp
, você força omysql
cliente a se conectar via TCP em vez do soquete do domínio UNIX. (Isso funciona para mim ao conectar-se a um contêiner podman cuja porta 3306 foi encaminhada para o sistema operacional do meu host127.0.0.1:3306
.)A propósito, se você não quiser escrever esses
mysql
comandos longos toda vez que se conectar, é claro que você pode colocar alguns ou todos os parâmetros dentro de uma[client]
seção de um.my.cnf
arquivo (observe o '.' inicial) na raiz do seu$HOME
diretório. (Mesma sintaxe da sua/etc/mysql/my.cnf
na VM.)Diga ao MySQL que o "usuário" pode se conectar por meio de um soquete:
No entanto, isso só permitirá que o "usuário" se conecte a partir desse mesmo host virtual.
Pense nisso como uma máquina separada.
Acho que a questão é entender o que
localhost
é.Referência: localhost (Wikipédia)
O seu
mysql -h localhost -u my_user my_db -p
irá falhar, porque uma conexão localhost viamysql
estará procurando por um/tmp/mysql.sock
arquivo, que não pode acessar, porque está dentro do seu host MySQL no VirtualBox.Referência: (Documentação MySQL)
O que você está observando
Quando você se conecta
127.0.0.1
, aciona uma conexão TCP que parece funcionar com o encaminhamento de porta.Quando você (tenta) se conectar
localhost
, aciona a conexão SOCKET, que está procurando o/tmp/mysql.sock
arquivo. Isso não está disponível em seulocalhost
, porque está dentro do localhost da instância do MySQL.