由于MYSQL数据库外部访问需求,老九再一次遇到需要外部开放3306端口的情况。本机使用阿里云ECS UBUNTU 16.04环境。
先提及涉及的命令和工具:
1. 本机TELNET(不熟悉的可以使用远程数据库连接工具NAVICAT)环境,用来检测远程3306端口是否打开。
2. Linux命令 netstat -apn|grep * 用来检测端口状态。
3. Linux命令 find -name * 用来在当前目录检索文件位置。
find [option] [path1 path2 ......] [filename]
4. Linux命令 whereis * 用来定位二进制等文件路径。
whereis [-bmsu] filename1 filename2 .......
具体操作如下:
第一步 服务器操作 数据库开启3306端口监听 LISTEN 3306 PORT
进入数据库并赋给用户远程访问权限。
mysql -uroot -p
grant all privileges on *.* to root@"%" identified by "password" with grant option;
并更新:
flush privileges;
配置完成后,重启Mysql。
sudo service mysql restart
输入命令:netstat -apn|grep 3306,结果如下:
tcp6 0 0 127.0.0.1:3306 :::* LISTEN 13524/mysqld
注意这里是127.0.0.1,说明数据库设置仅为监听本地。这里需要修改为0.0.0.0,表示监听所有客户端连接。如果这里是0.0.0.0,那就可以跳过这个环节了。
找到mysql配置文件
find -name my.cnf
配置my.cnf【注意,部分优化后的Mysql会将配置通过 !includedir放在其他文件里,按图索骥找到对应文件编辑即可。】
vim /etc/my.cnf [这里路径根据刚刚检索到的路径输入]
接下来分为两种情况,根据数据库版本不同,你可能需要遇到两种情况:修改 bind-address=127.0.0.1 为不配置或者IP配置为0.0.0.0,表示监听所有客户端连接;或者没有bind-address的情况下,请检查是否有skip-networking语句,用#注释掉即可。
#bind-address=127.0.0.1
#skip-networking
配置完成后,重启Mysql。
sudo service mysql restart
再次检测端口监听netstat -apn|grep 3306,无误即可。
tcp6 0 0 0.0.0.0:3306 :::* LISTEN 13524/mysqld
第二步,检查防火墙配置
这里老九被摆了一道,刚开始以为防火墙是关闭的,而且iptables自己并没有安装。后来发现iptables在安装的Ubuntu环境中默认安装,导致耽误了时间。具体操作如下:
执行 whereis iptables,获得iptables目录。
通常来说,iptables默认配置路径为/etc/iptables.rules。该文件通过dir一般是看不到的,可以使用ls -l命令查看。
编辑iptables配置文件:
vim /etc/iptables.rules
根据配置不同请稍作调整。这里案例原配置中需要修改的语句如下:
-A INPUT -p tcp -m tcp --dport 3306 -j DROP
修改为
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
使防火墙规则生效
iptables-restore < /etc/iptables.rules
查看规则是否生效
iptables -L -n
第三步,解决服务器提供商端口开启问题
部分服务器提供商是限制了端口开放的。包括ECS和UCLOUD。这里以ECS为例。
在ECS</a>界面找到实例安全组,添加一条入方向规则(这里可能会纠结内网网卡的问题,具体的可以搜索解决疑惑,简单来说,这里的内网不用介意,可以理解为外网也是通用的。)
添加完毕后,再在本地测试下3306端口的联通情况。
WIN+R开启CMD输入
telnet 你的IP 3306
没有报错就说明开启成功。
附录 一些可能出现的报错处理:
1. Lost connection to MySQL server at 'reading initial communication packet'
原因分析:
mysql开启了DNS的反向解析功能,这样mysql对连接的客户端会进行DNS主机名查找。
mysql处理客户端解析过程:
1)当mysql的client连过来的时候,服务器会主动去查client的域名。
2)首先查找 /etc/hosts 文件,搜索域名和IP的对应关系。
3)如果hosts文件没有,则查找DNS设置,进行DNS反向解析,直到timeout连接失败。
mysql的DNS反向解析:
1)mysql接收到连接请求后,获得的是客户端的ip,为了更好的匹配mysql.user里的权限记录(某些是用hostname定义的)。
2)如果mysql服务器设置了dns服务器,并且客户端ip在dns上并没有相应的hostname,那么这个过程很慢,导致连接等待。
解决方案:
1)把client的ip写在mysql服务器的/etc/hosts文件里,随便给个名字做主机映射即可。
2)在my.cnf配置文件中的[mysqld]区域添加skip-name-resolve,即跳过mysql连接的DNS反向解析功能,这样能很好地提高mysql性能。在这种情况下,就只能使用MySQL授权表中的IP来连接mysql服务了。