dxzmpk

endless hard working

0%

解决Mysql无法远程连接的问题

前言

最近开发中遇到一个问题,mysql在服务器本地可以登录,但是远程通过3306端口却不可以。这个问题困扰了我一周之久,终于在今天解决了。在解决的过程中试了很多的方法,遂记录下来,希望能给大家一些提示。

排查错误位置

客户端方面

首先通过ping命令对服务器进行测试,如果ping不通,则是网络的问题,本文中没有涉及这类问题的解决。
如果能ping通,再测试端口有没有问题。首先安装telnet, telnet是windows系统自带的,搜索”启动或关闭Windows功能”, 找telnet客户端,勾选即可启动。在cmd中输入telnet {服务器IP} 3306, 如果不能正确连接,说明是端口设置的问题, 再试试22端口有没有问题,如果也有问题,就是服务器整体的端口设置有问题,如果只有3306有问题,那么就是3306端口、mysql的设置问题,继续往下测试。

服务器方面

针对只有3306端口不能连接的情况,有以下几种解决方法:

1. 修改配置文件,开启对其他ip地址的监听

输入命令netstat -ntpl |grep 3306netstat -ntpl |grep 22, 查看端口的绑定情况
正确情况下应为以下输出:

如果3306只绑定的本地端口,就会出现和上图不一致的输出。需要对其配置文件进行修改:

1
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

打开配置文件, 找到bind-address开头的一行,如果后面的ip地址是127.0.0.1,也就是服务器只会接收本地的连接请求,那么就需要改变此地址来指向外部的IP地址。例如,可以改为:

1
2
3
4
5
6
lc-messages-dir = /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 0.0.0.0

如果你的mysql版本是MySQL 8+,那么mysqld.cnf中可能不会包含bind-address这一行,应该像下面所示方法进行添加:
1
2
3
4
5
6
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
log-error = /var/log/mysql/error.log
bind-address = 0.0.0.0

修改完成后,保存并退出。重启mysql服务sudo systemctl restart mysql,使得配置文件的修改得以生效。
接下来再次回到客户端进行验证,如果能够telnet连接3306端口,说明配置成功,如果还是不能连接,进入下一步骤。

2. 关闭防火墙

Ubuntu默认的防火墙为ufw。防火墙的作用是管理网络规则,默认情况下打开防火墙是更好的选择, 但是这里为了排除debug时的影响,就先关闭一下。
查看防火墙状态sudo ufw status, 如果显示active, 就运行sudo ufw disable关闭。

3. 修改 iptables

iptables定义了网络访问规则,它工作在内核中,是一个网络过滤器。
运行

1
sudo iptables -I INPUT -p tcp --dport 3306 -j ACCEPT

表示添加接收3306端口的规则。
-I INPUT将当前命令插入在filter链的第一位置。
-p tcp表示添加tcp协议的扩展。
—dport XX-XX:指定目标端口。
-j ACCEPT: 规定的动作,这里为接收。
完成后,保存修改的配置sudo iptables-save
然后再次在客户端用telnet进行测试,得到结果:

说明连接3306端口成功了。(忽略这里的乱码)