宝塔面板装 MySQL,听起来就两步:软件商店点一下安装,Navicat 里填个 IP、账号、密码。但真上手的人都知道,卡人的从来不是安装本身,而是最后那一下连接——Navicat 弹一个红框出来,Access denied for user 'root'@'xxx.xxx.xxx.xxx' (using password: YES),也就是大家口中的报错 1045。这个报错特别有意思,它既可能是密码打错了一个字符,也可能是 MySQL 的权限主机域没匹配上,还可能是改了密码没刷新权限表。我见过不少人为了这一行红字来回折腾一下午,最后发现问题出在user表里host字段是localhost而不是%。
这篇内容就是把这整条链路掰开讲清楚。从宝塔面板里 MySQL 的版本选择、安装方式,到远程连接必须具备的三个前置条件,再到 1045 的逐条排查路径、Navicat 侧的参数填写细节,最后是我自己踩过的坑和运维阶段的参数微调。适合刚接触服务器运维的新手,也适合已经能连上但总在权限和防火墙之间反复横跳的同学。看完你至少能做到两件事:知道 1045 到底是哪一环出了问题,以及用最小权限的方式把远程连接配稳。
1. 先把链路捋顺:谁在跟谁说话
1.1 一次 Navicat 连接要穿过几道关卡
很多人排查 1045 时容易陷入"到处乱改"的状态,改密码、关防火墙、重启服务,全试一遍,运气好通了,但下次再遇到还是懵。问题出在没有把链路拆开看。
Navicat 点下"连接"按钮的那一刻,数据包要依次经过这些环节:
- 客户端到公网:Navicat 所在的电脑发起 TCP 连接,目标是服务器的公网 IP 加端口。
- 云服务商安全组:如果你用的是云服务器,流量先过安全组规则。这一层不通,表现是连接超时。
- 系统防火墙:
firewalld(CentOS 系)或ufw(Ubuntu 系)。这一层不通,同样是超时或被拒绝。 - MySQL 服务是否监听:如果
bind-address写死成127.0.0.1,MySQL 只接受本机连接,外部一律拒绝。 - MySQL 用户权限校验:连上了 MySQL,但账号密码或来源主机不匹配,MySQL 返回 1045。
关键点在于:报错 1045 说明前面四关都过了。这其实是个好消息,它意味着你的端口、安全组、防火墙、服务监听全都是正常的,问题 100% 出在 MySQL 自己的权限表上。反过来,如果报的是 2003Can't connect to MySQL server,那就跟权限无关,是前面的网络层没通。
把这条链路记住,排查时就能直接砍掉一半无效操作。
1.2 用宝塔装 MySQL 到底省了什么
手动编译安装 MySQL 的流程大概是:下载源码包、装依赖、cmake配置一堆参数、编译(十分钟到半小时不等)、初始化数据目录、写 systemd 服务文件、配环境变量。中途任何一个依赖缺失都要重来。
宝塔面板把这套流程包成了一个按钮,安装完之后还额外给你几样东西:
- 统一的服务管理:启动、停止、重启、开机自启都在一个界面里,不用记
systemctl命令(虽然我还是建议你记住)。 - 日志集中查看:慢查询日志、错误日志有入口,排查问题不用自己去翻
/www/server/mysql/var/。 - root 密码重置入口:忘了 root 密码的时候,面板上有个"root 密码"按钮可以直接改,比走
skip-grant-tables安全得多。 - phpMyAdmin 一键入口:临时改点数据、看一眼表结构,不用开 Navicat。
- 计划任务联动:备份数据库可以和宝塔的计划任务直接挂钩,省了自己写 crontab。
代价也很明确:MySQL 会被装到固定路径/www/server/mysql/,配置模板由面板管理,你手动改了my.cnf之后如果又通过面板改了某个参数,有些改动可能被覆盖。所以我的习惯是:面板能改的走面板,面板没有的参数才去动my.cnf,并且改完立刻记一笔在哪里改的。
2. 宝塔面板安装 MySQL 的完整流程
2.1 服务器准备与面板安装
先说操作系统。现在新开机器,我不太建议再用 CentOS 7,它已经停止维护,很多新软件的依赖源都不好使。比较稳的选择是 Ubuntu 22.04 LTS 或者 AlmaLinux / Rocky Linux 9。
配置方面,MySQL 8.0 对内存比较敏感。1G 内存的机器装 MySQL 8.0 能跑起来,但innodb_buffer_pool_size只能给到很小,稍微有点并发就顶不住,甚至安装阶段就可能因为内存不足被系统杀掉进程。我的建议是 MySQL 8.0 至少 2G 内存起步,4G 会比较舒服。
宝塔面板的安装建议从官方渠道获取脚本,装完之后终端会打印面板地址、用户名、密码。这几项务必当场存下来,尤其是:
- 面板端口(默认 8888,建议改掉)
- 安全入口(一串随机字符,拼在地址后面)
- 面板账号密码
注意:宝塔面板本身也有安全入口机制,登录地址形如
http://IP:端口/随机字符。安全入口不是摆设,它能在一定程度上挡住扫描器,别图省事把它关掉。
2.2 软件商店里选哪个 MySQL 版本
进面板后点"软件商店",搜 MySQL,会看到几个版本。选择上我整理了一张对照表:
| 版本 | 适用场景 | 注意点 |
|---|---|---|
| MySQL 5.6 | 维护老项目、老框架 | 官方已停止维护,新项目不要选 |
| MySQL 5.7 | 兼容性最广,很多现成项目默认 | 默认字符集已是 utf8mb4,json类型可用 |
| MySQL 8.0 | 新项目首选 | 默认认证插件变为caching_sha2_password,老客户端可能连不上 |
关于安装方式,宝塔一般提供"极速安装"和"编译安装"两种:
- 极速安装:直接下载官方预编译好的二进制包,几分钟到十几分钟就能装完。绝大多数场景够用。
- 编译安装:从源码编译,耗时可能三四十分钟,中途吃 CPU 和内存。它的好处是能针对特定 CPU 指令集优化,但说实话,对大多数业务来说这点性能差异感知不到。
我自己的选择是:生产环境用极速安装,省时间也省性格。除非你有明确的定制需求,否则没必要折腾编译。
安装过程中别关页面、别刷新,宝塔的任务队列一旦中断,有时候会留下半安装状态,清理起来比重新装一遍还麻烦。
2.3 装完必须做的三项检查
安装完成之后,别急着打开 Navicat,先在宝塔的终端里做三件事。
第一件,确认服务在跑:
systemctl status mysqld看到active (running)才算正常。宝塔的 MySQL 服务名可能是mysqld也可能是mysql,两个都试一下。
第二件,确认端口监听状态:
ss -lntp | grep 3306或者老系统用netstat -lntp | grep 3306。这里要重点看输出里的地址部分:
- 显示
0.0.0.0:3306或*:3306:说明监听所有网卡,远程可以连。 - 显示
127.0.0.1:3306:只监听本机,远程必然连不上,要去改bind-address。
第三件,本机登录测试:
mysql -uroot -p输入密码能进到mysql>提示符,说明账号密码本身没问题。这一步很关键,它能把"密码错误"和"远程权限问题"彻底分开。如果本机都登不进去,那 1045 的原因就是密码不对,跟远程无关。
3. 远程连接的三个硬性前提
3.1 前提一:MySQL 用户的 host 字段必须匹配
这是 1045 最高频的原因,没有之一。
MySQL 的权限表里,一个用户是由用户名 + 来源主机两部分共同确定的。也就是说,'root'@'localhost'和'root'@'%'在 MySQL 眼里是两个不同的用户,可以有不同的密码、不同的权限。
当你用 Navicat 从外网连过来时,MySQL 看到的是'root'@'你的公网IP'。如果user表里只有'root'@'localhost'这一条记录,那不管你密码打得多正确,都匹配不上,直接返回 1045。
先看一眼现状:
SELECT user, host, plugin FROM mysql.user;如果 root 只有localhost那一行,就说明问题找到了。
接下来是最容易引发争议的一点:要不要把 root 开到%?
我的答案是:不要。root 拥有全部权限,一旦暴露在公网上,等于把家门钥匙插在锁上。正确做法是建一个专用账号,只给它需要的那几个库的权限:
CREATE USER 'app_user'@'%' IDENTIFIED BY 'YourStrongPass_2024'; GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%'; FLUSH PRIVILEGES;如果你用的是 MySQL 8.0,而 Navicat 版本比较老,可能会遇到另一个报错 2059,提示Authentication plugin 'caching_sha2_password' cannot be loaded。这是 8.0 换了默认认证插件导致的。解决办法有两个:升级 Navicat 到较新版本,或者把账号改回老插件:
ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'YourStrongPass_2024'; FLUSH PRIVILEGES;提示:
mysql_native_password在新版本 MySQL 中已被标记为废弃,能升级客户端就优先升级客户端,改插件只是权宜之计。
3.2 前提二:端口得真的通
端口这一层有两道门:云服务商的安全组,以及系统防火墙。
安全组在云厂商的控制台里配,添加一条入方向规则,协议 TCP,端口 3306,来源建议填你自己的固定公网 IP 而不是0.0.0.0/0。家里宽带是动态 IP 的话,可以先用当前 IP,变了再改。
系统防火墙在宝塔的"安全"页面也能放行,但如果你关了宝塔的防火墙插件,命令行的方式是这样:
# CentOS / AlmaLinux / Rocky firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload # Ubuntu / Debian ufw allow 3306/tcp验证端口是否真的通,有个特别省事的办法:在 Navicat 所在的电脑上用telnet或者 PowerShell 的Test-NetConnection:
Test-NetConnection -ComputerName 你的服务器IP -Port 3306返回TcpTestSucceeded : True就说明网络层通了。如果这里是 False,别去翻 MySQL 的权限表,先解决网络问题。
3.3 前提三:bind-address 不能锁死本机
前面提到过,如果 MySQL 的配置里bind-address是127.0.0.1,那它只接受本机连接,安全组放得再开也没用。
配置文件位置在/www/server/mysql/my.cnf,也可以在宝塔的"软件商店 → MySQL → 配置修改"里找到。搜bind-address,改成0.0.0.0或者直接注释掉这一行,然后重启 MySQL 服务。
改完之后再跑一次ss -lntp | grep 3306确认变成0.0.0.0:3306。
这里有个细节:宝塔面板在某些版本里,"数据库"页面有一个"权限"设置,你添加数据库时可以选择访问权限是"本地"还是"所有人"。选"所有人"时,宝塔会自动帮你创建对应的'用户名'@'%'记录。很多人只改了页面上的开关,其实宝塔已经代劳了权限配置,这时候还去手动改user表反而容易乱。先看一眼mysql.user表里的实际内容,再决定动不动手。
4. 报错 1045 的逐条拆解
4.1 先把错误信息读明白
1045 的完整格式一般长这样:
1045 - Access denied for user 'root'@'203.0.113.45' (using password: YES)这三段信息每一段都有用:
'root'@'203.0.113.45':MySQL 认为你在用什么账号、从哪个 IP 来。注意这里的 IP 是 MySQL看到的 IP,如果你走了 SSH 隧道,这里会显示127.0.0.1,因为对 MySQL 来说连接是从本机发起的。(using password: YES):客户端确实传了密码。如果是NO,说明 Navicat 那边密码框是空的,或者 SSH 隧道里的密码没填。- Access denied:认证没通过。
using password: NO是很好排查的,直接检查 Navicat 的密码框有没有填错位置——尤其是用了 SSH 隧道的时候,SSH 密码和 MySQL 密码是两个不同的输入框,填反了就会出现这个提示。
4.2 五种典型场景对照表
| 现象 | 真实原因 | 处理方向 |
|---|---|---|
| 本机能连,Navicat 连不上,提示 1045 | user表里没有匹配来源 IP 的记录 | 查看并补充账号的 host |
| 改了 root 密码后立刻连不上 | 只改了localhost那条记录 | 确认%记录的密码是否同步 |
| 密码含特殊字符,本地能连远程不能 | Navicat 里字符被转义或空格混入 | 换复杂但无特殊符号的密码,或确认输入准确 |
| 提示 2059 认证插件错误 | MySQL 8.0 默认caching_sha2_password | 升级客户端或改插件 |
提示 1130Host is not allowed | 授权时 host 写成了具体 IP 但来源不符 | 检查 host 通配符 |
4.3 从宝塔终端修复的完整步骤
假设你已经确认本机能登录,问题在于远程账号不存在。整套流程走下来是这样:
第一步,登录 MySQL:
mysql -uroot -p第二步,看看现在有哪些账号:
SELECT user, host, plugin FROM mysql.user;第三步,创建远程账号(把app_user和密码换成你自己的):
CREATE USER 'app_user'@'%' IDENTIFIED BY 'YourStrongPass_2024';第四步,授权到具体数据库,不要图省事给*.*:
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%';如果只需要读写,可以收得更紧:
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'%';第五步,刷新权限:
FLUSH PRIVILEGES;第六步,验证一下授权结果:
SHOW GRANTS FOR 'app_user'@'%';输出里能看到GRANT ... ON app_db.* TO 'app_user'@'%'就对了。
注意:
CREATE USER和GRANT语句在现代 MySQL 里其实是立即生效的,FLUSH PRIVILEGES主要是给直接改mysql.user表的场景用的。但加上它没坏处,习惯性加上更稳妥。
4.4 密码里的特殊字符是个隐形陷阱
这个坑我踩过不止一次。密码里带了#、$、!这类字符,在有引号包裹的 SQL 里没问题,但如果是通过某些脚本拼接执行,或者用mysqladmin命令行传参,shell 会先把这些字符解释掉一层,实际写进数据库的密码和你以为的不是同一个。
排查办法很简单:在服务器上用一个绝对干净的密码测一次。
mysql -uapp_user -p'YourStrongPass_2024' -h 127.0.0.1注意-p和密码之间不能有空格。如果这里能进,Navicat 进不去,那问题就锁定在 Navicat 侧的输入了,可能是复制粘贴时带了不可见字符,建议手动敲一遍。
反过来,如果这里也进不去,那就说明数据库里存的密码和你以为的不一样,重新用ALTER USER改一次:
ALTER USER 'app_user'@'%' IDENTIFIED BY 'NewCleanPass2024'; FLUSH PRIVILEGES;5. Navicat 侧的配置细节
5.1 新建连接时每个框填什么
打开 Navicat,新建 MySQL 连接,常规标签页里这几项:
| 字段 | 填什么 | 说明 |
|---|---|---|
| 连接名 | 自己看得懂的名字 | 比如"生产库-主" |
| 主机 | 服务器公网 IP | 走 SSH 隧道时填 127.0.0.1 |
| 端口 | 3306 | 改过 MySQL 端口就填新端口 |
| 用户名 | app_user | 不建议用 root |
| 密码 | 对应密码 | 点"保存密码"方便下次连 |
填完之后先点左下角的"测试连接"。连不上会给出具体错误码,比盲猜快得多。
5.2 直连和 SSH 隧道该怎么选
这是很多人纠结的点,我用一张表说清楚区别:
| 方式 | 配置复杂度 | 安全性 | 适用场景 |
|---|---|---|---|
| 公网直连 3306 | 低 | 中,依赖安全组和强密码 | 有固定 IP、临时调试 |
| SSH 隧道 | 中 | 高,MySQL 端口可完全不对外开放 | 长期使用、生产环境 |
SSH 隧道的工作原理,打个比方:服务器上开了一个不对外营业的后门,只有拿着 SSH 钥匙的人才能进,进去之后再走到 MySQL 那里。对外网来说,3306 端口根本没开,扫描器扫不到。
配置方式是在 Navicat 连接窗口的"SSH"标签页里勾选"使用 SSH 隧道",然后填:
- 主机:服务器公网 IP
- 端口:22(改过 SSH 端口就填新的)
- 用户名:服务器系统用户,比如 root
- 认证方式:密码或密钥文件
填完之后回到"常规"标签页,把主机改成127.0.0.1。这是最容易错的一步——因为对 MySQL 来说,连接是从服务器本机发起的。
用 SSH 隧道的话,MySQL 那侧完全可以只保留'app_user'@'localhost',安全组里 3306 直接删掉。我个人在生产环境一律用这个方案。
5.3 常见问题速查表
| 错误码 | 提示关键字 | 大概率原因 | 一句话解决 |
|---|---|---|---|
| 1045 | Access denied | 密码错 / 主机域不匹配 | 查mysql.user,补账号或改密码 |
| 2003 | Can't connect | 服务没起 / 端口没通 | 先本机mysql -uroot -p试 |
| 1130 | Host not allowed | 来源 IP 未授权 | 加%或对应 IP 的 host |
| 2059 | auth plugin | 8.0 认证插件不兼容 | 升级客户端或改插件 |
| 10038 | 端口错误 | 端口填错或非 MySQL 端口 | 核对实际监听端口 |
| 1251 | Client does not support | 客户端版本过老 | 升级客户端 |
5.4 关于工具的合法使用
Navicat 是商业软件,官方提供 14 天试用、功能精简的免费版,以及面向学生和教师的教育授权。网络上流传的各种注册机、补丁包,我不建议碰,一是法律风险,二是这类来路不明的二进制文件本身就是很常见的风险载体,装在一台能连数据库的机器上,代价太大。
如果预算有限,其实有不少够用的替代品:DBeaver 社区版是开源免费的,跨平台;MySQL Workbench 是官方出品;HeidiSQL 在 Windows 上轻量好用。功能上做日常查询、建表、导数据完全没问题,把省下的钱花在服务器配置上更划算。
6. 服务跑起来之后的调参和运维
6.1 两个最值得调的参数
MySQL 装完默认参数是"能跑就行"的水平,有两个参数调一下收益最明显。
innodb_buffer_pool_size:这是 InnoDB 的缓存池,用来缓存表数据和索引。业界经验值是物理内存的 50% 到 70%。比如 4G 内存的机器,可以设成2G到2560M。设得太小,查询频繁读磁盘,慢查询会明显增多;设得太大,会挤压系统和 PHP 等进程的内存,可能触发 OOM。
max_connections:默认 151。每个连接都会占用一定的内存,一般在几百 KB 到几 MB 之间。如果业务是 PHP 这类短连接模型,151 通常够;如果是常驻连接池,就要按实际并发上调。但别盲目往大了设,500 × 若干 MB也是个不小的数字,内存不够反而会把服务拖垮。
还有一个容易被忽略的:
character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci这个在 MySQL 8.0 上默认就是 utf8mb4,不用改。但如果是 5.7 或者从老版本迁移过来的库,务必确认一下,否则存表情符号会直接报错。这个在宝塔的配置修改界面里可以改,改完重启生效。
6.2 备份这件事,别等到出事才想起来
宝塔的"计划任务"里可以直接建数据库备份任务,支持全库或指定库,频率可以按天、按周。我一般会这样配:
- 每天凌晨 3 点全量备份一次
- 保留最近 7 份
- 备份文件落到独立目录,如果服务器上挂了额外的数据盘,就指到数据盘
命令行的手动备份方式是:
mysqldump -uapp_user -p --single-transaction --default-character-set=utf8mb4 app_db > /backup/app_db_$(date +%F).sql--single-transaction这个参数很重要,它能让备份过程不锁表,对 InnoDB 表来说,备份期间业务基本不受影响。不加这个参数,大表备份时可能把写入卡住。
提示:备份文件一定要验证能恢复。我见过备份跑了一年的任务,真出事的时候才发现文件是空的——原因是磁盘满了,
mysqldump静默失败。定期拿一份备份在测试环境恢复一次,这个习惯值钱。
6.3 我自己踩过的几个坑
第一个坑,改完 root 密码只改了本机记录。有一次在宝塔面板上点了"修改 root 密码",以为万事大吉,结果远程还是 1045。查了一下mysql.user,发现'root'@'%'那条记录的密码根本没变。原因是面板的改密操作只针对localhost。后来我养成了习惯:改完密码先SELECT user, host FROM mysql.user WHERE user='root';看一眼有几条记录。
第二个坑,把 3306 全放开了。早期图方便,安全组里 3306 来源写0.0.0.0/0,结果日志里天天有陌生 IP 在尝试爆破,auth.log刷得飞快。后来改成只放行办公网的出口 IP,再后来干脆全部走 SSH 隧道,3306 对外彻底关闭,世界一下子清净了。
第三个坑,MySQL 8.0 装完直接拿老版客户端连。那个 2059 的报错找了我半小时,最后才反应过来是认证插件的事。现在我的做法是:新建环境时先在服务器本地用mysql -h 127.0.0.1 -uapp_user -p测一遍,本地能过,说明账号密码和插件都是对的,剩下的就只是网络和 Navicat 配置问题,排查范围一下子小了很多。
第四个坑,1G 内存的机器装 MySQL 8.0。安装到一半进程被系统杀了,日志里全是Out of memory。后来换成 5.7 才装完,但性能也很勉强。结论很简单:内存不够就别硬上 8.0,要么升配置,要么用 5.7。
最后再分享一个小技巧:Navicat 的"工具 → 服务器监控"能实时看连接数、查询数、流量,临时排查"是不是连接被打满"这类问题很方便,比登服务器敲SHOW PROCESSLIST快得多。不过它需要账号有PROCESS权限,给业务账号的时候别加这个权限,单独留一个运维账号来用。
这套流程我在几十台机器上重复过,最花时间的永远不是安装,而是权限那几张表。把mysql.user看熟,把 host 字段的含义刻进脑子里,1045 就不再是玄学,而是一道有标准答案的选择题。