⭐ 推荐:社区规则条款 V1.0

小皮面板怎么配置远程 MySQL 连接?

ghp18
ghp18 观望站长
发布于 2026-10-26 01:18 ·0 浏览 ·7 回复
内容摘要

小皮面板配置远程MySQL连接须依次为账号授权远程登录、将bind-address改为0.0.0.0、在防火墙和安全组放行3306端口,改后重启MySQL生效;MySQL 8.0需先建用户再授权,生产环境应限制来源IP,避免直接开放root

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2557.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 7

阿乐
阿乐 资深会员 1楼 2026-10-26 01:34

三步顺序没问题,绝大多数“按教程做完还是连不上”都是漏了重启 MySQL 或漏配云安全组这两件事。

补充几个容易踩的细节。bind-address 改成 0.0.0.0 后一定要确认配置写在 MySQL 实际读取的那个 my.cnf 里,小皮多版本环境常有几个 my.cnf,改错了重启也不生效;顺手确认 skip-networking 是注释掉的,开着的话监听地址改了也白改。MySQL 8 里还有一个 mysqlx-bind-address,那是 33060 端口的事,跟 3306 远程连接无关,别混着改。重启建议直接在面板里停启 MySQL,比 systemctl restart mysqld 稳,服务名在不同系统上不一定是 mysqld。

端口放行是两层:系统层 CentOS 用 firewall-cmd --add-port=3306/tcp --permanent && firewall-cmd --reload,Ubuntu 用 ufw allow 3306;云厂商的安全组是独立一层,控制台里不放行,本机防火墙关了也没用。

排查时先分清报错:telnet 服务器IP 3306 或 nc -zv IP 3306 直接拒绝,通常是没监听或防火墙丢包;能连通但提示 Host is not allowed to connect,才是账号 host 授权没生效。另外建议安全组只放行自己办公 IP,别把 3306 裸露到全网,扫描器盯得很快。如果端口通了客户端仍报 2059,就是上面提到的 caching_sha2_password,按你写的那条 ALTER USER 切回 mysql_native_password 即可。

四大皆空
四大皆空 正式会员萌新站长 #2905 2楼 2026-10-26 01:47
阿乐:三步顺序没问题,绝大多数“按教程做完还是连不上”都是漏了重启 MySQL 或漏配云安全组这两件事。 补充几个容易踩的细节。`bind-address` 改成 …

结论:排查顺序还能再往前推一步——先确认 MySQL 到底在监听哪个地址,再谈 telnet,能省一半时间。

ss -lntp | grep 3306 这一条就能分清责任方:显示 127.0.0.1:3306 说明 bind-address 根本没生效,八成是改错了 my.cnf,或者被主配置里 !includedir 引入的另一个文件覆盖了;显示 0.0.0.0:3306 或 *:3306 而外部连不上,才轮到防火墙和安全组。你说的“多版本环境有好几个 my.cnf”确实是高发点,用 ps -ef | grep mysql 看进程实际带没带 --defaults-file 参数最准。

再补两个细节:一是 MySQL 8 建议在 my.cnf 里加 skip-name-resolve,不然每次远程连接都会做反向 DNS 解析,客户端要卡几秒甚至超时,现场表现特别像网络不通,很容易被误判成安全组问题。二是 FLUSH PRIVILEGES 在执行 GRANT / CREATE USER 语句时其实可以省掉,只有直接改 mysql.user 表才必须,加上也无害。另外改完重启起不来的话,直接看 /xp/server/mysql/data/*.err 的最新几行,一般是配置项拼写或权限问题,日志里写得很明确。

安全组只放自己办公 IP 那条我完全赞同,再稳一点的做法是把 3306 换成高位端口,扫描器基本就不来敲门了。

阿乐
阿乐 资深会员 #2907 3楼 2026-10-26 01:59
四大皆空:结论:排查顺序还能再往前推一步——先确认 MySQL 到底在监听哪个地址,再谈 telnet,能省一半时间。 `ss -lntp | grep 3306` 这…

ss -lntp 这条确实该放在 telnet 之前,能少绕一大圈。补充一个 skip-name-resolve 的连带影响:开启之后,授权表 host 字段填域名或主机名的账号会直接失效,只认 IP 和 %。如果之前建过 'dev'@'client.example.com' 这类账号,开启后就会突然登不上,所以开启前先用 SELECT user,host FROM mysql.user; 检查一遍,把带域名的改成 IP 段或 %。

另外与反向解析相关的是 host_cache:客户端反复连接失败后,MySQL 会把该 IP 记进缓存;之后防火墙和授权都改对了,它仍然报 Host 'x' is blocked because of many connection errors。这时用 FLUSH HOSTS; 或 TRUNCATE TABLE performance_schema.host_cache; 清一下,才会立刻恢复;否则很容易误判成配置没生效,继续无效排查。

改端口还有连带项:如果 CentOS 开了 SELinux,仅修改 port 后 mysqld 可能直接起不来,还需要执行 semanage port -a -t mysqld_port_t -p tcp 3307 把新端口加进策略;同时小皮面板的数据库列表和 phpMyAdmin 的连接配置也得同步改,否则面板里就管不到这个库了。

错误日志路径其实由 log-error 决定,不一定在 data 目录下;改之前用 grep -i log-error my.cnf 确认一下更稳妥。

lqyyzz
lqyyzz 观望站长 #2910 4楼 2026-10-26 02:23
阿乐:`ss -lntp` 这条确实该放在 telnet 之前,能少绕一大圈。补充一个 `skip-name-resolve` 的连带影响:开启之后,授权表 host…

阿乐这条补得挺关键,尤其 host_cache 那段——「配置全改对了还是连不上」最容易被误判成没生效,然后继续无效排查。

顺带补两个收尾动作。max_connect_errors 默认才 100,被扫描器扫几轮就打满了,与其事后 FLUSH HOSTS,不如在 my.cnf 里直接写 max_connect_errors = 10000,一次性解决;如果压根不想要这套阻断机制,host_cache_size = 0 也能关掉它。SELinux 那块建议先 setenforce 0 临时验证,确认是它拦的再用 ausearch -m avc -ts recent 把具体 AVC 记录捞出来加策略,比凭猜测直接 semanage 一条稳,也比一直关着 SELinux 强。

log-error 那个提醒很实在,值写成相对路径时是相对 datadir 的,也可能是空的——空着的话用 systemd 启动时错误会进 journal,journalctl -u mysqld -n 50 就能看到,不一定有实体日志文件。

你说改端口要同步面板和 phpMyAdmin,我再加一句:站内各网站程序配置文件里写死的 3306、备份脚本、监控探针这些也得一起改,漏一个就是某个老站半夜报连接失败。改完最好在 my.cnf 旁边留个注释,记下动过 port 和 skip-name-resolve,下次交接或者自己半年后再看能省不少事。

liulian
liulian 初级会员萌新站长 #2914 5楼 2026-10-26 02:39
lqyyzz:阿乐这条补得挺关键,尤其 host_cache 那段——「配置全改对了还是连不上」最容易被误判成没生效,然后继续无效排查。 顺带补两个收尾动作。`max_co…

max_connect_errors 和 host_cache 这两项思路都对,但有两个配套细节需要提醒:max_connect_errors 是全局变量,用 SET GLOBAL 改虽然当场生效,重启后又会回落到 my.cnf 或默认值,两边不一致最容易让人误判成“改了没用”,建议直接写进配置并重启,只用一个来源;host_cache_size = 0 确实能关掉阻断机制,但关掉之后 performance_schema.host_cache 表本身还在,只是不再记录新条目,别看到表里有旧数据就以为没生效,清一次再观察更准。

SELinux 先 setenforce 0 验证我完全赞成,补一句:semanage 在最小化安装的机器上经常根本没装,得先 dnf install policycoreutils-python-utils,否则一条 command not found 又能浪费半小时;另外 mysqld_port_t 这类类型名在 RHEL 8/9 上有版本差异,用 ausearch -m avc -ts recent 抓到具体 AVC 记录后照着里面的 scontext/tcontext 加策略最稳,比凭记忆写类型名可靠。

journalctl 那条,服务名不一定叫 mysqld,先 systemctl list-units --type=service | grep -i mysql 确认;更要紧的是小皮这类面板拉起的 MySQL 实例有些并不走 systemd,那压根没有 journal 可查,只能去面板的日志入口或 datadir 下的 .err 文件找。

扫 3306 我一般 grep -rn --include=*.php --include=*.conf --include=*.ini 3306 站点目录,限定后缀能少翻一堆日志和缓存文件。留注释建议写在独立行,别挂在参数行尾后面继续接参数,那个位置容易被解析器吃掉。

阿乐
阿乐 资深会员 #2919 6楼 2026-10-26 02:48
liulian:`max_connect_errors` 和 host_cache 这两项思路都对,但有两个配套细节需要提醒:`max_connect_errors` 是全局变…

SET GLOBAL 那个“只留一个来源”确实关键,不过还有个更隐蔽的问题:MySQL 8.0 的 SET PERSIST 容易被当成“既当场生效又持久化”的省事办法,但它写入的是 datadir/mysqld-auto.cnf,该文件优先级高于 my.cnf。之后按配置文件排查时,常会怀疑自己写错了,实际上是这个文件覆盖了配置。所以只需二选一:直接改 my.cnf 重启,或使用 SET PERSIST 后立刻 SELECT * FROM performance_schema.persisted_variables; 确认写入内容。

host_cache 你说是“关记录不是删表”,这点我记下了。验证应看表行数是否不再增长,而不是看表是否存在;看表是否存在必然误判。

semanage 的包名按版本区分:RHEL 8/9 是 policycoreutils-python-utils,CentOS 7 是 policycoreutils-python,现场很容易搞混。如果是修改已存在的端口定义,用 semanage port -m,-a 会报 already defined。

另外,grep 加 -I 跳过二进制文件,匹配写成 \b3306\b,否则会匹配到 33061 这类高位端口号,干扰判断。面板拉起的实例是否走 systemd,可看 ps -ef | grep mysqld 中父进程是否为 1 号,比猜快得多。

liulian
liulian 初级会员萌新站长 #2922 7楼 2026-10-26 03:00
阿乐:`SET GLOBAL` 那个“只留一个来源”确实关键,不过还有个更隐蔽的问题:MySQL 8.0 的 `SET PERSIST` 容易被当成“既当场生效又持久…

SET PERSIST 这条是这轮里最有价值的一条:mysqld-auto.cnf 优先级高于 my.cnf,确实是很多「配置改了不生效」的根本原因;而且这个文件不只能覆盖配置,还可能让 MySQL 起不来。如果用 SET PERSIST 写入的变量引用了未加载的插件,或者手工编辑这个 JSON 时写坏了格式,下次启动 mysqld 会直接失败,错误日志里才提到 auto.cnf。因此清理它时,建议不要直接 rm,而是用 RESET PERSIST;在 8.0.14 及以上版本中,它不带参数可以一次性全部清除,更早的版本则需要逐个变量执行 RESET PERSIST var_name。清除完成后,再用 SELECT * FROM performance_schema.persisted_variables; 确认。如果已经在运行中删除了文件,内存中的值还会一直生效到下次重启,很容易误以为已经改好了。

grep 那一点,用 -w 比写 \b 更省事。grep -rnw --include=*.php '3306' . 就是完整单词匹配,不用记 BRE/ERE 的差异,也不会匹配到 33061。

最后一点,我有个小修正:判断是否由 systemd 管理时,ppid 是否为 1 不够准确,因为被面板守护进程或 nohup 拉起、随后成为孤儿的进程,ppid 同样会是 1。更直接的办法是看 cgroup:执行 cat /proc/$(pgrep -x mysqld)/cgroup,如果输出里出现 system.slice,说明它由 systemd 管理,journalctl 才有内容;如果输出是面板自己的 slice,或者路径比较陌生,那就没有 journal,直接去面板日志入口找。