最近遇到了一件非常棘手的问题,用Navicat或者pycharm远程连接MySQL数据库居然连接不到,真是头都大了。网上查阅了一下原因,原来是没有开通远程权限或者是端口的问题,好吧,下面我就来回忆一下自己怎么处理这问题的!
当然首先得先确保你填的mysql 主机ip,数据库名以及密码等信息都是正确的,最好检查下,不然就没用了!!
好了,开始问题整理以及解决办法
错误一:

错误原因:
本地IP(xxx.xxx.xxx.xxx)没有访问远程数据库的权限。于是下面开启本地IP(xxx.xxx.xxx.xxx)对远程mysql数据库的访问权限。
解决办法:
1.首先远程连接进入服务器,在cmd中输入mysql -u root -p,然后回车,输入密码后回车进入mysql命令行。
2.输入use mysql;
3.输入select user,password,host from user;
可以看到host中只有localhost主机。我们需要将http://xxx.xxx.xxx.xxx也添加到这里才对。

4.添加方法如下,不同的mysql版本号不一样,操作口令可能不一样,请注意:
输入
grant all privileges on *.* to root@”xxx.xxx.xxx.xxx” identified by “密码”;
或者 GRANT ALL PRIVILEGES ON *.* TO ‘root’@’xxx.xxx.xxx.xxx’ IDENTIFIED BY ‘123456’ WITH GRANT OPTION;
这相当于是给http://IP-xxx.xxx.xxx.xxx赋予了所有的权限,包括远程访问权限。
然后再输入
flush privileges;
这相当于是重新加载一下mysql权限,这一步必须有。

5.再次输入select user,password,host from user;
可以看到host中已经有了新加的IP。
6.现在再次用Navicat for MySQl访问远程mysql数据库,已经能正常打开了。
问题解决。
7.如果还是连接不到,那是不是 MySQL Server 绑定了本地地址,打开 /etc/mysql/my.cnf,
找到:bind-address = 127.0.0.1
去除 IP 地址绑定,把它改为:bind-address = 0.0.0.0
然后重启 MySQL Server:/etc/init.d/mysql restart
错误二:
ERROR 2003 (HY000): Can’t connect to MySQL server on ‘hostxxxxx’ (10061)
错误原因:
mysqld数据库服务没有启动。
解决办法:
检查 :在windows 的任务管理器,或者 unix/linux 下 ps -aux | grep mysql 看一下。确认服务已经启动。
处理 :启动mysqld 服务
错误三:
防火墙未开启3306了,或者drop了
DROP tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306
解决方法:
防火墙需要允许3306端口连接。
drop了的解决方法:
先登录服务器,用命令netstat -tuln查看一下:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.1.1:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:445 0.0.0.0:* LISTEN
...
可以看出,MySQL配置应该没问题的,当然也确保MySQL用户密码等都是对的。
查了半天,怀疑是不是iptables问题(但记不得之前曾经配置过iptables,所以一直没想这块):
sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- localhost anywhere tcp dpt:mysql
DROP tcp -- anywhere anywhere tcp dpt:mysql
ACCEPT tcp -- anywhere anywhere tcp dpt:mysql
ACCEPT tcp -- 192.168.1.0/24 anywhere tcp dpt:mysql
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (1 references)
target prot opt source destination
很奇怪这边怎么会有一个对mysql访问的DROP规则,但还是先删为敬!
这次再iptables命令多加个参数:
sudo iptables -L -n –line-number
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
4 ACCEPT tcp -- 127.0.0.1 0.0.0.0/0 tcp dpt:3306
5 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306
6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306
7 ACCEPT tcp -- 192.168.1.0/24 0.0.0.0/0 tcp dpt:3306
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 DOCKER all -- 0.0.0.0/0 0.0.0.0/0
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
这下每条规则前都有了序号,所以可以根据序号直接来修改或删除:
sudo iptables -D INPUT 5
把INPUT的第五条规则删除,然后去客户端再次登录MySQL,成功!