MySQL 遠程連線涉及使用者授權、網路綁定、防火牆與驅動程式設定。本文涵蓋命令列、PHP (mysqli/PDO) 兩種連線方式,並解決常見「Host not allowed」與「Connection refused」錯誤。
mysql -h localhost -u root -p
# 或
mysql -u root -p # 省略 -h localhost,預設走 Socket
mysql -h 192.168.1.100 -u root -p
# 參數說明:-h 主機IP/域名 -u 使用者 -p 提示輸入密碼(或 -ppassword 直接帶入,不建議)
EXIT; 或 QUIT; 或 \q
-- 方式 A:建立新帳號允許任意 IP(% 通配符)
CREATE USER 'app_user'@'%' IDENTIFIED BY 'StrongPass123!';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%';
-- 方式 B:修改現有 root 允許遠程(僅測試環境,生產嚴禁)
-- MySQL 5.7+
ALTER USER 'root'@'%' IDENTIFIED BY 'StrongPass123!';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
-- MySQL 8.0+(需分開執行)
CREATE USER 'root'@'%' IDENTIFIED BY 'StrongPass123!';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
[mysqld]
bind-address = 0.0.0.0 # 監聽所有網卡;若只允許特定內網 IP,可寫該 IP
# skip-networking # 確保此行被註解或移除
重啟服務:systemctl restart mysqld(Linux)或服務管理器重啟(Windows)。
# CentOS 7+ firewalld
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --reload
# Ubuntu ufw
ufw allow 3306/tcp
# iptables
iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
# 從客戶端機器測試
telnet 192.168.1.100 3306
# 或
mysql -h 192.168.1.100 -u app_user -p
mysql_connect()、mysql_query() 等 mysql_* 函數已在 PHP 7.0 移除。請改用 mysqli 或 PDO。
<?php
$host = '192.168.1.100';
$user = 'app_user';
$pass = 'StrongPass123!';
$db = 'app_db';
$port = 3306;
$mysqli = new mysqli($host, $user, $pass, $db, $port);
if ($mysqli->connect_errno) {
die("連線失敗: " . $mysqli->connect_error);
}
$mysqli->set_charset("utf8mb4"); // 重要:設定字符集
// 查詢範例
$sql = "SELECT id, username FROM users WHERE status = 1 LIMIT 10";
$result = $mysqli->query($sql);
if ($result) {
while ($row = $result->fetch_assoc()) {
echo "ID: {$row['id']}, User: {$row['username']}<br>";
}
$result->free();
}
$mysqli->close();
?>
<?php
$dsn = "mysql:host=192.168.1.100;port=3306;dbname=app_db;charset=utf8mb4";
$user = 'app_user';
$pass = 'StrongPass123!';
try {
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // 使用真實預備語句
]);
$stmt = $pdo->prepare("SELECT id, username FROM users WHERE status = ? LIMIT ?");
$stmt->execute([1, 10]);
foreach ($stmt as $row) {
echo "ID: {$row['id']}, User: {$row['username']}<br>";
}
} catch (PDOException $e) {
die("連線失敗: " . $e->getMessage());
}
?>
| 錯誤代碼/訊息 | 原因 | 解決 |
|---|---|---|
| ERROR 1130 (HY000): Host 'x.x.x.x' is not allowed to connect | 使用者無遠程授權 | GRANT ... TO 'user'@'%' 或具體 IP |
| ERROR 2003 (HY000): Can't connect to MySQL server (111/10060) | 網路不通/防火牆/bind-address | 檢查防火牆、my.cnf bind-address、服務啟動狀態 |
| ERROR 2002 (HY000): Can't connect via socket | 本機連線 Socket 路徑錯誤/服務未啟動 | 確認 mysqld 運行、socket 參數一致 |
| Authentication plugin 'caching_sha2_password' not supported | MySQL 8.0 新認證插件,舊驅動不支援 | 升級驅動、或建立用戶指定 IDENTIFIED WITH mysql_native_password |
REQUIRE SSL 配合客戶端憑證。'user'@'192.168.1.%' 而非 '%'。