MySQL远程连接失败主因是四层配置未全通:用户权限仅限localhost、bind-address绑定127.0.0.1、系统/云安全组未放行3306、MySQL 8.0+认证插件不兼容。

MySQL 用户权限没开,远程连不上是常态
宝塔默认创建的数据库用户只允许 localhost 或 127.0.0.1 连接,这是最常被忽略的第一道坎。哪怕安全组、防火墙全放行,mysql -h your-server-ip -u user -p 仍会报 Access denied for user。
实操建议:
- 进宝塔 → 数据库 → 找到对应数据库用户 → 点击“权限”列的“修改” → 把“允许访问的 IP”从
127.0.0.1改成%(表示任意 IP),或填具体客户端 IP(更安全) - 改完别忘了点“保存”,这个操作会执行
GRANT ... ON *.* TO 'user'@'%' IDENTIFIED BY 'xxx'并自动FLUSH PRIVILEGES - 如果用的是低版本 MySQL(如 5.7),
%不包含 IPv6 的::1,测试时优先用 IPv4 连
宝塔没开 3306 端口,防火墙拦在系统层
宝塔面板本身不管理服务器防火墙,它只管自己的 Web 端口(8888)。MySQL 的 3306 默认被系统防火墙(firewalld 或 ufw)和云厂商安全组双重封锁。
实操建议:
- 先确认 MySQL 是否监听外网:运行
netstat -tnlp | grep :3306,看到0.0.0.0:3306才算正常;若只有127.0.0.1:3306,需编辑/www/server/mysql/etc/my.cnf,注释掉或删掉bind-address = 127.0.0.1,然后重启mysqld - 宝塔后台 → 安全 → 放行端口 → 添加
3306(TCP)→ 提交 - 同时必须去云控制台(阿里云/腾讯云等)配安全组规则,入方向放行
3306/TCP,源 IP 建议限制为你的办公 IP,别写0.0.0.0/0
MySQL 8.0+ 的密码认证插件导致连接失败
MySQL 8.0 默认用 caching_sha2_password 插件,而很多旧版客户端(比如某些 Navicat 版本、Python 的 pymysql 未指定 auth_plugin)不支持,会卡在握手阶段,报错类似 Authentication plugin 'caching_sha2_password' cannot be loaded。
实操建议:
- 临时兼容方案:登录 MySQL 后执行
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 长期建议升级客户端驱动,或连接时显式指定插件(如 Python 中加参数
auth_plugin='mysql_native_password') - 注意:改认证方式后要再执行一次
FLUSH PRIVILEGES;,否则不生效
远程连接成功但查不到数据库,可能是字符集或 SQL 模式问题
有些应用(尤其是旧 PHP 项目)依赖 sql_mode 中的 NO_AUTO_CREATE_USER 或特定字符集,而 MySQL 8.0+ 默认模式更严格,远程连接后执行 SHOW DATABASES; 可能只显示 information_schema,真实库“消失”了。
实操建议:
- 检查当前会话的 SQL 模式:
SELECT @@sql_mode;,对比本地与远程是否一致 - 如果只是开发调试,可在
my.cnf的[mysqld]下加一行sql_mode=STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION(去掉不兼容项) - 字符集建议统一设为
utf8mb4:确认character_set_server=utf8mb4和collation_server=utf8mb4_unicode_ci已写入配置并重启
远程连数据库不是“开个端口 + 改个权限”就完事,MySQL 层、系统防火墙层、云平台层、客户端协议层,四层里漏一环都会断在不同位置。最容易被跳过的其实是 bind-address 和认证插件——这两个不调,其他全对也白搭。

















