
MySQL 装完Navicat 一连接弹个 1045这几乎是每个刚接触服务器运维的人都要交一遍的学费。宝塔面板把 MySQL 的安装过程压缩成了点几下鼠标但装好和能远程连上完全是两件事——前者是软件的安装后者涉及监听地址、端口放行、用户授权表、认证插件这一整条链路。这篇内容就是把这套组合拳从头到尾捋一遍在宝塔面板上装好 MySQL配好允许远程连接的用户最后用 Navicat 从本地电脑顺利连上去如果中途撞上 1045也有完整的排查路径可以照着走。不管你是刚买了云服务器准备搭站的新手还是被这个报错卡了半天没找到北的老手下面的内容都能直接抄作业。1. 先把方案想清楚宝塔装MySQL、Navicat连远程卡点在哪1.1 这套组合的角色分工先把三个角色摆清楚后面排查问题的时候脑子才不会乱。宝塔面板本质上是一个跑在服务器上的 Web 管理程序它自己不是数据库它做的是帮你把 MySQL 装上去、把配置文件写好、把服务拉起来、再给你一个图形界面去改密码建库。所以宝塔面板的价值在于省掉了编译安装、配置 my.cnf、设置开机自启这一堆琐事但它改的仍然是标准 MySQL 的那套东西——配置文件在/www/server/mysql/my.cnf数据目录在/www/server/data服务用systemctl或者宝塔自己的脚本管理。MySQL 服务端是真正存数据、校验账号密码的一方。它对外提供服务的网络入口叫 3306 端口默认谁能连、从哪个 IP 连、用什么密码全部由它内部的mysql.user授权表说了算。这就是 1045 的源头。Navicat 是跑在你自己电脑上的客户端。它做的事情只有一件拿着你填的 IP、端口、用户名、密码向服务器的 3306 端口发起 TCP 连接然后等服务端告诉它通过或者拒绝。理解了这个分工排查思路就明确了连接失败要么是网络到不了端口、防火墙、安全组要么是到了但服务端不认你授权表、密码、认证插件。1045 属于后者。1.2 为什么1045几乎人人都会撞上1045 的完整报错文本一般是这样的1045 - Access denied for user rootxxx.xxx.xxx.xxx (using password: YES)注意括号里那段using password: YES表示你确实传了密码服务端明确拒绝了。如果显示using password: NO那说明客户端压根没把密码发出去通常是配置问题而不是密码错误。这个报错之所以高频原因有四个而且往往是叠加出现的第一MySQL 安装完成后默认的 root 账号只允许从本机localhost/127.0.0.1登录你在深圳的笔记本上拿着这个账号去连北京的服务器host 字段对不上直接拒绝。第二宝塔面板里的 root 密码和你以为的密码不是一回事面板改过一次密码之后本地记的还是旧的。第三MySQL 8.0 默认用caching_sha2_password认证插件老版本的 Navicat 握手阶段就不认表现出的错误有时也是 1045。第四密码里带、#、$这类字符在某些客户端里被转义处理了传过去的就是个残缺的密码。我见过最典型的场景是装完宝塔试了一下 phpMyAdmin 能进就觉得数据库肯定通了结果 Navicat 一连就 1045。因为 phpMyAdmin 是装在服务器本机上的它走的是localhost而 Navicat 走的是公网 IP在 MySQL 眼里这是两个完全不同的来源。这一点想通了很多莫名其妙的失败就都有解释了。2. 宝塔面板里把MySQL装明白2.1 版本怎么选内存怎么算进宝塔面板的软件商店搜索 MySQL会看到 5.6、5.7、8.0 甚至 8.4 几个版本。选哪个不是拍脑袋决定的主要看两件事你现有的程序兼容哪个版本以及服务器内存够不够。MySQL 8.0 相比 5.7 在性能、JSON 支持、窗口函数上有明显提升但它默认的innodb_buffer_pool_size起步就更高空载内存占用比 5.7 大概多出 200MB 到 400MB。所以内存规划要提前算服务器内存建议版本innodb_buffer_pool_size 建议值1GBMySQL 5.7256MB2GBMySQL 5.7 或 8.0512MB4GBMySQL 8.01GB ~ 1.5GB8GB 及以上MySQL 8.02GB ~ 4GB这个值怎么来的innodb_buffer_pool_size是 InnoDB 缓存数据和索引的内存池命中率越高磁盘 IO 越少。业界通用的经验值是如果这台机器只跑数据库设成物理内存的 50% 到 70%如果数据库和应用比如 Nginx、PHP、Java跑在同一台机器上就压到 30% 到 40%给其他进程留出空间。4GB 内存的机器1GB 到 1.5GB 是比较稳的区间再多就容易触发系统的 OOM 杀手把 MySQL 干掉了。注意宝塔面板的软件商店里安装 MySQL 8.0编译过程可能持续十几分钟到半小时取决于 CPU 核数。1 核 2G 的机器编译 8.0 会非常痛苦这种情况下要么先临时升配要么直接选 5.7。2.2 安装过程中的几个关键选项点安装之后会弹出选项主要三项安装方式编译安装 / 极速安装、是否设置大小写不敏感、以及自定义端口。安装方式上编译安装耗时但适配性好极速安装用的是预编译包几分钟就能完事。对绝大多数场景来说极速安装足够用除非你的系统版本比较特殊导致预编译包跑不起来。大小写敏感这一项要慎重。Linux 下 MySQL 默认表名区分大小写Windows 下不区分。如果你的项目是从 Windows 环境迁移过来的表名大小写混用迁到 Linux 上就会报表不存在。这时候选择大小写不敏感也就是设置lower_case_table_names1能省很多事。但要注意这个参数必须在数据库初始化之前定好初始化之后再改会导致数据目录异常甚至起不来服务。提示lower_case_table_names一旦设成 1后续所有表名都会以小写存储。如果你的业务里有靠大小写区分表名的设计千万别开。端口默认 3306除非有特殊需要不建议改。改了之后所有客户端都要跟着改容易忘。2.3 装完先做三件事第一件在宝塔面板左侧数据库页面确认能看到 MySQL 已启动的绿色状态并且能看到 root 密码那一栏。宝塔面板会给 root 分配一个随机强密码这个密码是后面连接的基础建议立刻复制出来存到密码管理器里。第二件登录服务器命令行确认服务本身是活的systemctl status mysqld # 或者宝塔自己的管理脚本 /etc/init.d/mysqld status第三件用命令行本地登录一次确认账号体系没问题mysql -uroot -p # 输入宝塔面板里显示的 root 密码登录成功后执行SELECT VERSION(); SELECT user, host, plugin FROM mysql.user;第二条语句非常关键它会把当前所有账号、允许的来源主机、以及使用的认证插件全部列出来。你会看到类似这样的输出---------------------------------------------------- | user | host | plugin | ---------------------------------------------------- | root | localhost | caching_sha2_password | | mysql.infoschema | localhost | caching_sha2_password | | mysql.session | localhost | caching_sha2_password | | mysql.sys | localhost | caching_sha2_password | ----------------------------------------------------看 host 那一列全是localhost。这意味着从这个服务器以外的任何地方来连MySQL 都找不到匹配的账号记录直接返回 1045。这就是问题的根接下来要做的就是补上远程来源的授权。3. 打通远程连接的四道关卡3.1 第一道关云安全组与面板防火墙这一步跟 MySQL 本身没关系但它是所有远程连接失败里占比最高的一类。数据包的路径是你的电脑 → 公网 → 云服务商安全组 → 服务器系统防火墙 → 宝塔面板防火墙 → MySQL 监听端口。任何一层没放行连接就会超时或者被拒绝。云服务商的安全组在控制台里配置入方向规则加一条协议端口来源说明TCP3306你的固定公网IP/32推荐只放行自己TCP33060.0.0.0/0不推荐等于对全网开放服务器系统防火墙CentOS 系是 firewalldUbuntu 系是 ufw和宝塔面板的安全页面也要同步放行 3306。宝塔面板这边有个坑面板的安全规则和系统防火墙是联动的但如果你之前手动用iptables加过规则可能会出现两边不一致的情况。稳妥的做法是在面板里加然后命令行验证一下firewall-cmd --list-ports # 或者 iptables -L -n | grep 3306注意把 3306 对0.0.0.0/0全开是非常危险的做法。公网上有大量自动化脚本在扫描 3306 端口一旦扫到就会尝试弱口令爆破。正确的思路是能限定来源 IP 就限定实在没有固定 IP比如家宽动态 IP那就把密码强度拉到最高并且改用非默认端口降低被扫描概率。3.2 第二道关MySQL监听地址MySQL 有个参数叫bind-address决定它监听在哪个网络接口上。如果是127.0.0.1那只有本机能连如果是0.0.0.0则所有网卡都监听外部才能连进来。宝塔面板安装的 MySQL这个参数一般写在/www/server/mysql/my.cnf里。用命令行看一下grep -n bind-address /www/server/mysql/my.cnf如果输出是bind-address 127.0.0.1或者压根没有这一行MySQL 8.0 某些版本默认注释掉就需要处理。用宝塔面板自带的文件编辑器打开这个文件找到[mysqld]段改成[mysqld] bind-address 0.0.0.0改完保存重启服务/etc/init.d/mysqld restart然后验证监听状态netstat -tlnp | grep 3306期望看到的是0.0.0.0:3306或者:::3306。如果还是127.0.0.1:3306说明配置没生效检查一下是不是改错了文件或者有没有其他配置文件覆盖了它MySQL 会按顺序读取多个配置文件后面的覆盖前面的。提示部分宝塔版本默认已经是0.0.0.0所以这一步不一定要做。但确认这个动作必须做不要假设。3.3 第三道关用户与host授权1045的根前面两道关解决的是网络能不能通这一道解决的是通了你让不让我进。这也是 1045 最核心的成因。MySQL 的账号是用户名主机的组合rootlocalhost和root%在 MySQL 眼里是两个完全不同的账号。%是通配符表示任意主机。登录 MySQL 命令行创建或修改一个允许远程连接的账号-- 方式一直接创建一个新账号只允许从指定 IP 连 CREATE USER dbuser203.0.113.25 IDENTIFIED BY YourStrongPssw0rd; -- 方式二允许从任意主机连方便但风险高 CREATE USER dbuser% IDENTIFIED BY YourStrongPssw0rd; -- 授权只给某个库的权限最小权限原则 GRANT ALL PRIVILEGES ON myapp_db.* TO dbuser%; -- 如果确实需要全局权限比如要做数据迁移 GRANT ALL PRIVILEGES ON *.* TO dbuser%;关于FLUSH PRIVILEGES这条命令有必要澄清一个常见误解用CREATE USER、GRANT、ALTER USER这类语句修改权限时MySQL 会自动重新加载权限表不需要手动执行FLUSH PRIVILEGES。只有当你直接用INSERT/UPDATE语句去改mysql.user表的时候才需要执行它。很多人每次授权都敲一遍属于无害但多余的操作。改完之后再查一次授权表确认记录存在SELECT user, host, plugin FROM mysql.user WHERE user dbuser;这里还有个大坑localhost这个字符串在 MySQL 里有特殊含义。它优先走 Unix socket 连接而不是 TCP。所以有时候你会发现dbuserlocalhost能用但dbuser%反而不行——因为%不匹配localhost。反过来如果你在客户端填的是127.0.0.1那走的是 TCP匹配的是%或127.0.0.1而不是localhost。这个细节在排查时经常把人绕晕。3.4 第四道关Navicat端的连接参数前面三关都通了Navicat 这边就简单了。新建连接选 MySQL填四项参数填什么常见错误主机服务器公网 IP填了内网 IP本地连不上端口3306服务端改过端口但这里没改用户名dbuser用了 root但 root 没开放远程密码对应账号的密码面板改过密码但这里没更新点测试连接。如果通过保存即可。如果不通过先看报错码——1045 是权限问题2003 是网络不通10060 是超时这几个数字基本能定位到前面四道关中的哪一道。提示Navicat 是一款商业数据库客户端请通过官方渠道获取授权使用。网上流传的各种注册机、密钥生成器不仅存在版权风险更严重的是这类工具经常捆绑木马我见过好几例因为装破解工具导致服务器凭据被窃取的情况得不偿失。4. 报错1045的完整排查实录4.1 先分清1045的三种面孔同样是 1045背后的原因可能完全不同。把报错文本拆开看能快速缩小范围。第一种Access denied for user root1.2.3.4 (using password: YES)。host 部分显示的是你的客户端 IP说明网络是通的问题在授权表里没有root1.2.3.4或者root%这条记录或者有记录但密码不匹配。第二种Access denied for user rootlocalhost (using password: YES)。注意这里 host 是localhost说明你是从服务器本机连的或者 MySQL 把连接识别成了本地连接。这种情况下要检查的是本机 socket 连接的账号。第三种Access denied for user root1.2.3.4 (using password: NO)。这个最容易被误判成密码错误实际上是密码根本没传过去。常见原因是客户端配置里密码字段为空或者密码里的特殊字符被 shell 吃掉了或者某个配置文件里的password项被覆盖成了空值。分辨清楚是哪一种排查方向立刻就明确了。4.2 一步步排查的操作顺序我习惯按这个顺序走从最外层往最里层剥第一步验证网络可达。在你自己的电脑上不是服务器上执行telnet 服务器IP 3306 # 或者 Windows PowerShell 里 Test-NetConnection -ComputerName 服务器IP -Port 3306如果卡住不动最终超时说明端口没通回到第 3.1 节检查安全组和防火墙。如果能看到一段乱码那是 MySQL 的握手包说明网络层没问题继续往下。第二步在服务器上确认授权表里的账号。登录 MySQL 执行SELECT user, host, plugin, LENGTH(authentication_string) AS pwd_len FROM mysql.user;pwd_len不为 0 说明密码字段有内容为 0 说明这是个空密码账号。第三步确认账号的密码到底是什么。这里有个实用技巧可以先临时把密码改成一个你知道的简单值排查完再改回去ALTER USER dbuser% IDENTIFIED BY Temp123456;然后用 Navicat 拿这个临时密码试。如果连上了说明之前就是密码不对如果还不行问题就不在密码上。第四步检查认证插件。执行SELECT user, host, plugin FROM mysql.user WHERE user dbuser;如果 plugin 显示caching_sha2_password而你用的是比较老的 Navicat 版本比如 11 及以下握手就可能失败。解决办法有两个升级 Navicat 到 15 及以上版本原生支持caching_sha2_password或者把账号的认证插件改成老版本兼容的ALTER USER dbuser% IDENTIFIED WITH mysql_native_password BY YourStrongPssw0rd;改完立刻生效不需要重启服务。第五步检查是否存在anonymous匿名账号。某些安装方式会残留匿名用户导致匹配优先级出现意外SELECT user, host FROM mysql.user WHERE user ;如果有删掉DROP USER localhost; DROP USER %;第六步看错误日志。MySQL 的错误日志通常在/www/server/data/下面文件名类似主机名.err。里面会记录连接失败的具体原因包括是密码校验失败还是 host 不匹配这是最权威的信息源tail -n 100 /www/server/data/*.err4.3 容易连带出现的其他错误码1045 往往不是孤立的排查过程中会撞上别的错误码提前认一下脸能省不少时间。错误码报错含义大概率原因1045访问被拒绝账号、host、密码、认证插件不匹配2003无法连接到服务器端口未放行、MySQL 未启动、bind-address 不对10060连接超时安全组拦截、公网 IP 填错1130主机不允许连接授权表里没有对应的 host 记录2059认证插件不支持Navicat 版本过低不支持 caching_sha2_password1040连接数过多max_connections 被打满1251客户端不支持认证协议同 2059或者服务端用了 sha256_password1130 和 1045 经常被混淆。1130 的完整文本是Host xxx is not allowed to connect to this MySQL server它发生在账号匹配阶段——连账号都没找到而 1045 发生在找到账号之后的密码校验阶段。搞清楚这个区别你就知道 1130 只需要加 host 授权1045 还得看密码和插件。5. 认证插件、字符集与性能参数的落地配置5.1 caching_sha2_password引发的兼容问题MySQL 8.0 把默认认证插件从mysql_native_password换成了caching_sha2_password这是一次安全性升级但对生态的冲击不小。老的客户端库、老的 ORM 框架、老的 Navicat 版本都可能在这个环节翻车。判断要不要回退看两个条件客户端是否支持以及是否有更安全的替代方案。如果只是本地开发用或者内网环境把认证插件改成mysql_native_password是可以接受的。如果服务器直接暴露在公网建议保留caching_sha2_password然后升级客户端。要批量查看哪些账号还在用老插件可以执行SELECT user, host, plugin FROM mysql.user WHERE plugin mysql_native_password;想改回去的话ALTER USER dbuser% IDENTIFIED WITH caching_sha2_password BY YourStrongPssw0rd;还有一点要注意MySQL 8.0 的配置文件里可以设置默认插件[mysqld] default_authentication_plugin mysql_native_password但这个参数在 MySQL 8.4 之后被移除了写法变成了authentication_policy。如果你用的是 8.4要按新语法来。5.2 字符集与排序规则一次定死字符集这件事最好在创建数据库的时候定死不要等到出现乱码再来救火。MySQL 8.0 的默认字符集是utf8mb4排序规则默认是utf8mb4_0900_ai_ci这个组合已经相当好了。5.7 的默认还是latin1必须手动改。建库的时候显式指定CREATE DATABASE myapp_db DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;为什么推荐utf8mb4因为它能存 4 字节的字符包括 emoji 和各种生僻汉字。老版本的utf8在 MySQL 里其实只支持 3 字节存 emoji 会直接报错。排序规则的选择上utf8mb4_general_ci和utf8mb4_unicode_ci是 5.7 时代的两个主流选项前者速度快一点后者排序更准确。8.0 里新增的utf8mb4_0900_ai_ci基于 Unicode 9.0准确性最好但只在新版本里可用。如果要在 5.7 和 8.0 之间做数据迁移统一用utf8mb4_general_ci能避免很多排序规则冲突的报错。改完之后会话级的字符集也要确认SHOW VARIABLES LIKE character_set%; SHOW VARIABLES LIKE collation%;客户端、连接、数据库、服务端四个层面的字符集最好保持一致任何一层不同都可能出现存进去是中文读出来是问号的情况。Navicat 连接属性里也有一个编码选项建议设为自动让它跟随服务端。顺便说一句索引的事。utf8mb4下每个字符最多占 4 字节索引长度限制是 3072 字节InnoDB 的DYNAMIC或COMPRESSED行格式所以一个VARCHAR(768)的字段建索引就已经到顶了。如果表结构还是COMPACT格式限制只有 767 字节那VARCHAR(191)就是上限——这个 191 的由来就是这么算出来的不是什么玄学。5.3 连接数与buffer pool怎么估算Navicat 每建立一个连接每个查询窗口就会在 MySQL 里占用一个连接槽位。默认的max_connections是 151看起来够用但如果同时有多个开发人员连着、再加上应用连接池、再加上宝塔面板自己的 phpMyAdmin很容易打满然后报 1040。估算公式大致是需要的 max_connections 应用连接池最大连接数 × 应用实例数 运维客户端并发数每人 1~3 个 监控/备份任务预留5~10 个 安全余量 20%举个例子一个 PHP 应用连接池上限 20跑 2 个实例3 个开发用 Navicat那就是 20×2 3×3 10 59再乘个 1.2 的余量大约 71。加上默认的保留连接 1 个设成 150 到 200 就很宽裕了。但max_connections不是越大越好每个连接都会消耗内存主要是线程栈和各类缓冲区设太大反而容易 OOM。常见的做法是设成 300 到 500同时严格管理连接池让应用及时归还连接。innodb_buffer_pool_size前面提过这里补充一个动态调整的方法。MySQL 5.7 以后支持在线调整SET GLOBAL innodb_buffer_pool_size 1073741824; -- 1GB不过这种调整重启后会失效要持久化还是得改配置文件。另外缓冲区调大或调小是在线分块完成的大实例上可能需要一点时间期间性能会有波动生产环境建议在低峰期操作。还有一个容易被忽略的参数是wait_timeout默认 28800 秒8 小时。Navicat 挂着不动超过这个时间会被服务端断开第二天回来点一下查询就报错。开发环境可以调小到 600 秒让连接及时释放或者干脆在 Navicat 的连接属性里勾上保持连接间隔让它定期发心跳。6. 安全加固与长期运维的实操心得6.1 别拿root当业务账号用这是我见过最多、也是最危险的坏习惯。很多人图省事所有应用、所有客户端统统用 root结果一旦某个环节泄露整个数据库服务器就全暴露了。正确的做法是按用途拆账号。比如-- 应用账号只操作业务库 CREATE USER app_web10.0.0.% IDENTIFIED BY xxx; GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO app_web10.0.0.%; -- 只读账号给报表、数据分析用 CREATE USER app_readonly10.0.0.% IDENTIFIED BY yyy; GRANT SELECT ON myapp_db.* TO app_readonly10.0.0.%; -- 运维账号从固定办公 IP 连权限放宽 CREATE USER dba_ops203.0.113.25 IDENTIFIED BY zzz; GRANT ALL PRIVILEGES ON *.* TO dba_ops203.0.113.25 WITH GRANT OPTION;MySQL 8.0 还支持角色的概念可以把一组权限打包成角色再赋给多个账号管理起来更清爽CREATE ROLE role_readonly; GRANT SELECT ON myapp_db.* TO role_readonly; GRANT role_readonly TO app_readonly10.0.0.%;注意授权之后如果发现权限没生效先检查账号有没有SET DEFAULT ROLE。MySQL 8.0 里角色默认是不激活的需要显式设置默认角色或者用SET ROLE临时激活。这个坑很多人踩过。6.2 备份、日志与慢查询宝塔面板自带计划任务可以配置定时备份数据库。但面板备份有个局限它备份的是服务器本地如果磁盘挂了备份也就没了。稳妥的做法是本地备份 异地同步。本地备份的脚本大概长这样#!/bin/bash DATE$(date %Y%m%d_%H%M%S) BACKUP_DIR/www/backup/mysql DB_NAMEmyapp_db mysqldump -u backup_user -p密码 \ --single-transaction \ --routines --triggers --events \ --default-character-setutf8mb4 \ $DB_NAME | gzip ${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz # 保留最近 7 天 find ${BACKUP_DIR} -name *.sql.gz -mtime 7 -delete其中--single-transaction是关键参数它让 mysqldump 在 InnoDB 表上以一致性快照的方式导出不锁表不影响线上业务。用 MyISAM 表的场景下这个参数不起作用需要改用--lock-tables。慢查询日志是排查性能问题的第一手资料。开启方式是在 my.cnf 里加[mysqld] slow_query_log 1 slow_query_log_file /www/server/data/slow.log long_query_time 1 log_queries_not_using_indexes 1long_query_time 1表示超过 1 秒的查询都记下来。刚上线的时候可以设小一点比如 0.5 秒抓得更细稳定之后调到 1 到 2 秒避免日志膨胀。有了慢查询日志可以用mysqldumpslow或者pt-query-digest做聚合分析找出 TOP 10 的慢语句然后针对性优化——加索引、改 SQL 写法、或者调整表结构。顺带提一句更新子查询这个老生常谈的坑-- 会报错的写法不能在 UPDATE 的子查询里引用同一个表 UPDATE t1 SET col (SELECT MAX(col) FROM t1 WHERE ...); -- 正确写法套一层派生表 UPDATE t1 SET col (SELECT max_col FROM (SELECT MAX(col) AS max_col FROM t1) AS tmp);MySQL 不允许在 UPDATE 的子查询中直接引用被更新的表套一层派生表就能绕过这个限制。这是写数据修复脚本时的高频问题。6.3 我自己踩过的几个坑第一个坑是密码里的特殊字符。有一次设置了一个带$的密码命令行用mysql -u user -p$abc123登录shell 把$abc当成变量展开成了空值实际传过去的是123一直报 1045我盯着授权表看了半小时才发现是 shell 干的。解决办法是用单引号包起来或者干脆在密码里避开 shell 里有特殊含义的字符。第二个坑是宝塔面板里改密码的方式。面板数据库页面有个改密码按钮改了之后 MySQL 里的密码确实变了但如果你之前用命令行已经给某个账号单独设过密码两边的密码会被覆盖成不一致的状态。我后来养成习惯所有账号的密码变更都在命令行里用ALTER USER做面板只用来查看和建库减少变量。第三个坑是 host 写成了192.168.%。MySQL 的 host 匹配不支持这种简写%只能出现在特定位置写成192.168.%是不合法的模式。要么写具体的 IP要么写192.168.1.%这种是可以的要么直接%。写错了 MySQL 不报错只是静默地不匹配排查起来很折磨。第四个坑是改完bind-address忘了重启。MySQL 的配置文件修改后必须重启服务才生效ALTER USER这类语句是即时的但配置文件不是。我因为这个问题白排查了二十分钟。7. 常见问题速查表把前面提到的场景整理成一张表遇到问题可以直接对号入座。现象最可能的原因处理动作Navicat 报 1045using password: YES账号不存在或密码不匹配查 mysql.user重建账号或重置密码Navicat 报 1045但 host 显示为客户端 IP没有对应的远程授权记录创建user%或user具体IP账号命令行能连Navicat 不能命令行走 socketNavicat 走 TCP检查bind-address和账号的 host报 2003 无法连接端口未放行或服务未启动查安全组、防火墙、进程状态报 10060 超时公网 IP 错误或被拦截核对 IP测试 telnet报 2059 认证插件错误Navicat 版本过低升级客户端或改用 native 插件报 1130 主机不允许host 字段不匹配补授权记录改完密码立刻能连隔天又不行wait_timeout 断连调大超时或开启保持连接数据出现中文乱码字符集不一致统一为 utf8mb4报 1040 连接数过多max_connections 打满调大参数并检查连接池泄漏服务启动失败日志报内存不足buffer pool 设置过大按物理内存 30%~50% 重设排查的核心逻辑其实就一条从外往里一层层验证。先确认网络通不通再确认账号有没有接着确认密码对不对最后确认认证插件兼不兼容。把这四步按顺序走一遍1045 以及它的一堆亲戚基本都跑不掉。我个人的习惯是新装一台服务器之后先把这套流程完整走一遍并记录下来——装完 MySQL 是什么版本、root 的 host 是什么、开的哪个端口、建了哪些账号。真出问题的时候有一份基线记录在手对比一下就能发现问题出在哪一步比现场瞎猜快得多。这个习惯帮我在好几次半夜的应急里省下了大量时间。