MySQL遠程連接失敗(錯誤碼:2003)
更新於2018年3月12日
一 環境信息
- 服務器系統:Oracle Linux 7.3
- 服務器MySQL版本:MySQL 5.7.20
- 本地系統:win10
- 本地客戶端:Navicat for MySQL 10.1.7
- 本地開發環境:python(3.6.3),PyMySQL(0.8.0)
- 假設:登錄用戶名為admin,密碼為adminpwd ,MySQL連接端口3306
二 問題描述
-
本地客戶端及代碼連接均失敗: 2003, "Can't connect to MySQL server on '192.168.1.166' (10061)"
-
python連接MySQL代碼
import pymysql
conn= pymysql.connect(
host='192.168.1.166',
port = 3306,
user='admin',
passwd='adminpwd',
db ='test',
charset='utf8'
)
# 使用cursor方法獲取操作游標
cur = conn.cursor()
# 使用execute 方法執行sql語句
cur.execute("select version()")
# 使用fetchone()方法獲取一條數據庫
data = cur.fetchone()
print("datebase version : %s"%data)
# 關閉數據庫連接
conn.close()
- python連接MySQL報錯
Traceback (most recent call last):
File "D:/JetBrains/test/study_test/mysql_test1.py", line 15, in <module>
charset='utf8'
File "D:\JetBrains\pyEnv\python363\lib\site-packages\pymysql\__init__.py", line 90, in Connect
return Connection(*args, **kwargs)
File "D:\JetBrains\pyEnv\python363\lib\site-packages\pymysql\connections.py", line 699, in __init__
self.connect()
File "D:\JetBrains\pyEnv\python363\lib\site-packages\pymysql\connections.py", line 967, in connect
raise exc
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on '192.168.1.166' (timed out)")
三 官方文檔描述
"The error (2003) Can't connect to MySQL server on 'server' (10061) indicates that the network connection has been refused. You should check that there is a MySQL server running, that it has network connections enabled, and that the network port you specified is the one configured on the server."
金山譯文:錯誤(2003年)無法連接到“server”(10061)上的mysql服務器,表示網絡連接已被拒絕。您應該檢查是否有一個mysql服務器正在運行,它是否啟用了網絡連接,並且您指定的網絡端口是在服務器上配置的。
四 解決過程
-
(1) Xshell遠程登陸服務器,用“ps aux|grep mysql”命令查看,MySQL服務已啟動:
-
(2) 用"vim my.cnf"命令查看my.cnf文件(在MySQL安裝目錄下,我的位置是/usr/local/mysql/my.cnf),修改其對應的值並重啟MySQL。對應內容如下:
[mysqld]
bind-address = 0.0.0.0 # 表示允許任何主機登陸MySQL
port=3306 # 表示MySQL運行端口為3306
- (3)用“mysql -u admin -p”命令,回車后輸入密碼“adminpsw”能正常登陸服務器MySQL
mysql> show global variables like 'port'; # 查看MySQL運行的實際端口
+---------------+-------
| Variable_name | Value |
+---------------+-------+
| port | 3306 |
+---------------+-------+
1 row in set (0.01 sec)
mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select host,user from user;
+-----------+---------------+
| host | user |
+-----------+---------------+
| % | admin |
| % | root |
| localhost | mysql.session |
| localhost | mysql.sys |
+-----------+---------------+
5 rows in set (0.00 sec)
# 如果上述查詢結果,admin用戶對應的host不為%,則修改用戶權限
# 此處需注意的是,修改權限時要帶上密碼(IDENTIFIED BY 'adminpwd'),雖然不知道具體原理,但是沒加密碼之前客戶端還是不能遠程訪問MySQL。
mysql> GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' IDENTIFIED BY 'adminpwd' WITH GRANT OPTION;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
-
(4) 至此,我的本地Navicat客戶端已經能都正常訪問服務器端,但是運行上述python連接MySQL代碼還是報一樣的錯誤。
-
(5)查網上資料說可能是防火牆屏蔽了3306端口,本地cmd"ping 192.168.1.166"能夠Ping通,再用”telnet 192.168.1.166 3306“命令檢查端口是否被屏蔽,結果為"正在連接192.168.1.166...無法打開到主機的連接。 在端口 3306: 連接失敗",說明是防火牆的問題
(如果Win10 telnet不是內部或外部命令,決解方法參考連接:https://jingyan.baidu.com/article/1e5468f9033a71484961b7d7.html) -
(6) 起初我以為是指我本地防火牆的問題,於是把本地防火牆關了,結果問題並沒有解決。
-
(7) 其實應該是遠程服務器的防火牆問題。遠程登陸服務器(我用root用戶登錄的),檢查防火牆狀態
systemctl start firewalld # 開啟防火牆
systemctl stop firewalld # 關閉防火牆
systemctl status firewalld #檢查防火牆狀態
- (8) 關閉遠端服務器防火牆后,運行本地運行本地python連接MySQL代碼,MySQL連接成功
[root@db sysconfig]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: active (running) since 三 2018-02-28 17:18:10 CST; 7s ago
Docs: man:firewalld(1)
Main PID: 5452 (firewalld)
CGroup: /system.slice/firewalld.service
└─5452 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
[root@db sysconfig]# systemctl stop firewalld
[root@db sysconfig]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
- (9)如果你覺得關閉防火牆不安全,可打開遠端服務器的iptables(安裝或升級命令“yum install iptables”)(我用root用戶登錄的),並用“vi /etc/sysconfig/iptables”檢查3306端口是否打開,如沒有,在文件中加入“-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT”(如下所示),保存文件並用“service iptables restart”命令重啟iptables
# Generated by iptables-save v1.4.21 on Wed Feb 28 12:19:33 2018
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [34:3136]
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT ## 加上此行
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibite
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Wed Feb 28 12:19:33 2018
~
~
"/etc/sysconfig/iptables" 17L, 654C
- (10)運行本地python連接MySQL代碼,結果如下:
datebase version : 5.7.20-enterprise-commercial-advanced
