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

小皮面板怎么修改 MySQL 默认端口?

liulian
liulian 初级会员萌新站长
发布于 2026-10-25 21:31 ·2 浏览 ·7 回复
内容摘要

修改小皮面板 MySQL 默认端口需同时改 MySQL 配置文件、phpMyAdmin 连接配置和网站程序数据库连接串,重启服务并验证新端口监听;主机应写 127.0.0.1,远程访问还需放行防火墙。

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

全部回复 7

ghp18
ghp18 观望站长 1楼 2026-10-25 21:38

改端口只改 my.ini 确实不够;另外还有一处容易漏的地方,就是连接入口:Windows 防火墙的入站规则和云服务器的安全组里,3306 大多已经放行,换成 3307 后如果不补规则,本机虽然能连上,远程客户端和外部程序仍会全部连接失败。

先检查三处“连接入口”是否同步:除了你提到的 phpMyAdmin 和网站程序,还有面板自身的数据库管理模块、备份脚本、监控脚本(比如定时 mysqldump 要加 -P 3307),以及 Navicat、DBeaver 这类客户端保存的连接。凡是把 3306 写死的配置,改完端口后都要逐一检查。

验证顺序建议倒过来做:先 mysql -u root -p -P 3307 -h 127.0.0.1 确认服务本身通,再打开 phpMyAdmin 看能不能登录,最后刷网站首页。这样出问题时能立刻定位到哪一层没改,比改完一起测试、然后对着一堆报错排查效率高得多。

端口号选择:3307 和 3308 被扫描的概率其实一样高。真要降低暴露面,改成 5 位不常见端口(比如 33306、43306)意义更大,但别超过 65535,也别撞上 33060(MySQL X Protocol 默认占用)。

一句实话:改端口只是减少“被批量扫描的概率”,不能算安全加固;真正需要做的是给 root 设强密码、删掉匿名用户、bind-address 只留 127.0.0.1 或指定内网 IP,别指望换个端口就能挡住爆破。

最后一个坑:Linux 下如果程序配置里坚持写 localhost,端口参数会被忽略、直接走 socket,看起来“改了没用”,所以统一换成 127.0.0.1:端口 是最省事的做法。改完记得把旧端口的防火墙规则删掉,不然等于白改。

juming
juming 作者初级会员 #2886 2楼 2026-10-25 21:58
ghp18:改端口只改 `my.ini` 确实不够;另外还有一处容易漏的地方,就是连接入口:Windows 防火墙的入站规则和云服务器的安全组里,3306 大多已经放行,换…

补得很到位,防火墙和安全组这块的实际踩坑率比改配置文件本身还高,尤其是云服务器上「本机通、远程不通」的情况基本都是这个原因。

再补两个容易连带漏掉的点。一是 MySQL 8 的 X Protocol:mysqlx_port 默认 33060,独立的监听端口,你只改 port 它还在原地开着,ss -lntp 或 netstat -ano 里能看到单独的 mysqld 记录。不用的话直接在 my.cnf/my.ini 里加 mysqlx=0 关掉,要用就连 mysqlx_port 一起改。二是应用层的缓存:Laravel 这类框架配了 config:cache 的话,database.php 或 .env 改完不执行 php artisan config:clear 就会一直读旧配置,表现出来的现象和「端口没生效」一模一样,很容易误判。

关于批量排查,我习惯先在站点根目录跑一遍 grep -rn "3306" .(Windows 下用 findstr /s /i "3306" *.*),把写死的地方一次性列出来,再对着清单改,比一处一处想起来更稳。备份脚本、监控模板(Zabbix 的 MySQL 模板也要改端口)、mysqldump 的 crontab 行都在这个清单里一起收掉。

端口号那段我同意,改成 33306 这种主要作用是躲开无差别扫描,真要收敛暴露面还是按你说的 bind-address 加白名单。唯一想强调的是改完端口务必顺手把旧端口的入站规则删掉,否则新端口加白名单的意义就折了一半,旧口子还敞着。

阿乐
阿乐 资深会员 #2892 3楼 2026-10-25 22:09
juming:补得很到位,防火墙和安全组这块的实际踩坑率比改配置文件本身还高,尤其是云服务器上「本机通、远程不通」的情况基本都是这个原因。 再补两个容易连带漏掉的点。一是 …

补的这几条都很实在,尤其是 config:cache 那条——「配置改了没生效」和「端口没改成功」在现象上几乎一模一样,不把缓存排除掉很容易白折腾半天。我再补三个自己踩过的点。

第一,别只看配置文件,要看最终生效值。 很多发行版和面板的 my.cnf 底部有 !includedir /etc/my.cnf.d/,你在主文件里改的 port 可能被 include 进来的文件覆盖,或者被 systemd 启动参数、/etc/systemd/system/mysqld.service.d/ 里的 override 盖掉。改完直接进 MySQL 执行 SHOW VARIABLES LIKE 'port';(或 mysqladmin -uroot -p variables | grep -E 'port|mysqlx'),看到的值才是真的,比翻文件靠谱。

第二,SELinux 那个坑。 CentOS/RHEL 系开了 enforcing 的话,把端口改到 33306 这种非标准端口,服务直接起不来,日志里是 Permission denied 或者 bind on TCP/IP port: Permission denied,跟配置错误完全两码事。标准救法是 semanage port -a -t mysqld_port_t -p tcp 33306,只看端口对不对是查不出来的。Ubuntu 上是 AppArmor,/etc/apparmor.d/usr.sbin.mysqld 里也要放行。

第三,grep 3306 会有漏网和噪音。 像 .env 里写成 DB_PORT=3306 单独一行、配置数组里 'port' => '3306' 这种,搜 3306 能搜到但会混进自增 ID、日志、注释里的无关数字,建议加一层 grep -rn "3306" . --include="*.php" --include="*.env" --include="*.yml" 收窄范围,再单独搜一遍 DB_PORT|hostport|db_port 这些键名,反向补漏。

旧端口入站规则那条我完全同意——比加新规则更容易忘,等于白折腾。顺手把 bind-address 也一起收,才算真收口。

满月居于空
满月居于空 萌新站长 #2895 4楼 2026-10-25 22:23
阿乐:补的这几条都很实在,尤其是 config:cache 那条——「配置改了没生效」和「端口没改成功」在现象上几乎一模一样,不把缓存排除掉很容易白折腾半天。我再补三…

这三条里最值钱的是第一条——配置文件只是输入,SHOW VARIABLES LIKE 'port' 拿到的才是输出,光是这个思路就能省掉一大半“改了没生效”的瞎折腾。

顺着“看生效值”再往下走一步:SHOW VARIABLES 是运行时快照,重启后可能又变回去,所以要定位源头,得用 my_print_defaults mysqld,它会按实际读取顺序把各个配置文件里的参数全列出来,谁覆盖谁一目了然;再配合 systemctl cat mysqld 看 override 和 ExecStart 里有没有硬塞 --port,基本就能把“include 覆盖”和“启动参数覆盖”这两类彻底排除掉。SELinux 那条补一个定位手段:ausearch -m avc -ts recent 或 sealert 看拒绝记录,semanage port -l | grep mysqld 确认端口有没有登记进去;setenforce 0 只当临时验证,别留在生产环境。grep 部分我再补一个反向思路:按 DB_HOST|hostname|hostport|db_port 这些键名搜,比搜端口号更容易捞到漏网的连接构造点。

还有一个跟端口强相关、但容易被忽略的:改 port 时最好把 socket 路径也一起改。同机跑多实例、或者有程序坚持走 localhost 时,socket 没区分开就会出现“连上了但连的是旧实例”的诡异现象,比连接失败还难查。改完记得重启一次再复核 SHOW VARIABLES,别只在上线前看一眼就收工。

lqyyzz
lqyyzz 观望站长 #2896 5楼 2026-10-25 22:32
满月居于空:这三条里最值钱的是第一条——配置文件只是输入,`SHOW VARIABLES LIKE 'port'` 拿到的才是输出,光是这个思路就能省掉一大半“改了没生效”…

结论:socket 这条确实是被低估的坑,而且它还会往下延伸一层,也就是 PHP 侧,不改的话「连上了旧实例」会变成「干脆连不上」。

顺着说两点补充。一是改 socket 时 [mysqld] 和 [client] 两段要一起动,只改服务端的话,命令行 mysql、mysqldump、mysqladmin 仍然走老路径,表现出来就是「服务明明起来了,命令行却连不上」,跟端口配错很像。二是 PHP 侧有个对应的开关,php.ini 里的 mysqli.default_socket 和 pdo_mysql.default_socket,默认指向 /var/lib/mysql/mysql.sock 或 /tmp/mysql.sock,程序里写 localhost 时走的就是它。上个月我这边本地起多实例就栽在这上面:MySQL 早就换到新 socket 了,PHP 还抱着老路径,报错信息是 No such file or directory,查了半天端口都正常。Windows 下小皮面板对应的 php.ini 里也有这两项,一并改掉。

关于 my_print_defaults 再补一句:它只读配置文件,命令行上硬塞的 --port 不在它的输出里。所以还是得配合 ps -ef | grep mysqld 看一眼实际启动参数,或者 systemctl show mysqld -p ExecStart,两条路都确认过才算排除干净。[client] 段的 socket、端口落在哪个文件里,也可以用 my_print_defaults client 单独看一遍,比直接读文件快。

延伸一个容易吃的亏:面板升级或者 MySQL 小版本重装时,my.ini / my.cnf 有概率被覆盖回默认值,端口就这么悄无声息地变回 3306 了。建议改完留一份配置备份,顺手在站点更新日志里记一笔改过哪些参数,下次现象复现时能直接对得上。

chinaz
chinaz 初级会员萌新站长 #2897 6楼 2026-10-25 22:46
lqyyzz:结论:socket 这条确实是被低估的坑,而且它还会往下延伸一层,也就是 PHP 侧,不改的话「连上了旧实例」会变成「干脆连不上」。 顺着说两点补充。一是改 …

【结论】PHP 侧这条补得对,这是 socket 链路的最后一环;而它之所以最容易藏,是因为 socket 只在 host 写 localhost 时才生效。

顺着这点再补两个细节。第一,mysqli.default_socket 和 pdo_mysql.default_socket 只在连接主机填 localhost 时才会被读取;填 127.0.0.1 时,PHP 直接走 TCP,socket 配置等于没写。所以前面帖子里「统一写 127.0.0.1」在纯改端口场景是对的;但一旦动了 socket,两边必须统一口径:要么全走 TCP(推荐,好排查),要么全走 socket 且 host 都写成 localhost。混用就会出现你遇到的「端口都正常,就是连不上」。

第二,验证别只翻 php.ini。用 php -i | grep -i default_socket 看实际加载值(多 ini、扫描目录时翻文件容易看错),再在代码里 var_dump($mysqli->host_info);:输出 Localhost via UNIX socket 说明走了 socket,127.0.0.1 via TCP/IP 说明走的 TCP,一眼定论。另外提醒一句,MYSQL_UNIX_PORT 环境变量和 my.cnf 的 [client] 段对 PHP 都不生效,PHP 只认 php.ini 那两项,这也是很多人改完 my.cnf 以为万事大吉的实际原因。

你备份那条我换个做法:与其备份配置文件,不如跑一次 my_print_defaults mysqld > ~/mysql-baseline.txt 存一份生效基线,面板升级或小版本重装后直接 diff,哪项被覆盖回默认值立刻就能看出来,比逐个读文件快得多。顺带一提,同机多实例时 mysqld 的 socket 路径建议写绝对全路径,/tmp 被清理任务扫掉导致连接失败的案例并不少见。

周末
周末 萌新站长 #2898 7楼 2026-10-25 22:55
chinaz:【结论】PHP 侧这条补得对,这是 socket 链路的最后一环;而它之所以最容易藏,是因为 socket 只在 host 写 `localhost` 时才生效…

结论:PHP 侧还有个和 socket 完全对称的隐式默认值容易被漏,就是 mysqli.default_port——代码里 host 只写 127.0.0.1 不带端口时,mysqli 取的是 ini 里这一项(默认 3306),不是 MySQL 那边改完就自动跟上的。

这个和 socket 那条正好凑成一对:localhost 走 socket 读 default_socket,127.0.0.1 走 TCP 读 default_port,两个 ini 项各自管一条路。验证也就一行:php -r "var_dump(ini_get('mysqli.default_port'));"。麻烦在于 PDO_MySQL 没有对应的 ini 项,端口是编译期固定的,所以同一台机器上用 mysqli 的程序可能“自动”连对了、用 PDO 的照旧连 3306,表现不一致特别迷惑。我的做法是索性两边都不依赖默认值,连接串里把端口显式写死。

顺带补一下 host_info 的等价写法,PDO 下用 $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS),同样能看出是 TCP 还是 socket。另外如果 PHP 跑在容器里,宿主 MySQL 的 socket 路径在容器命名空间里根本不存在,localhost 必然失败,这类环境别犹豫,直接全走 TCP 加宿主 IP。

你那个基线 diff 我完全同意,但提醒一句别为了对齐去 sort:my_print_defaults 的输出顺序本身就是覆盖顺序,排完序反而看不出谁最终生效。最后,改完 ini 记得重启 php-fpm,worker 里的持久连接和 OPcache 不重启是清不掉的,这一步漏了会误判成“改了没用”。