error 1410 根本原因是 grant 中的 'user'@'host' 在 mysql.user 表中不存在,mysql 8.0+ 禁止隐式创建用户,必须先 create user 再 grant,且 host 必须完全一致;常见错配包括 localhost 与 127.0.0.1、% 与具体 ip、navicat 默认存 % 而命令行写 127.0.0.1 等。

GRANT报ERROR 1410:用户host不匹配
根本不是权限不够,而是你写的 'user'@'host' 在 mysql.user 表里根本不存在。MySQL 8.0+ 默认禁止隐式创建用户,所以它不会帮你建账号,而是直接报错 “not allowed to create a user with GRANT”。
- 先查真实记录:
SELECT user, host FROM mysql.user WHERE user = 'your_username'; - 常见错配场景:
CREATE USER 'app'@'10.0.2.%'后,却执行GRANT ... TO 'app'@'localhost'—— 这两条记录完全独立 - Navicat 等工具默认存成
'u'@'%',但你在命令行写了'u'@'127.0.0.1',也查不到 - 修复方式只有两种:要么
CREATE USER 'u'@'h'再GRANT ... TO 'u'@'h'(两个h必须一模一样);要么用UPDATE mysql.user SET host = 'new_host' WHERE user = 'u' AND host = 'old_host'+FLUSH PRIVILEGES
GRANT报ERROR 1044或1146:目标数据库不存在
MySQL 要求 GRANT ... ON db_name.* 中的 db_name 必须已存在,否则语法校验失败,不关权限什么事。
- 错误信息里带
database 'mydb'字样,基本就是库没建 - 必须按顺序执行:
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;→GRANT ... ON mydb.* TO 'u'@'h';→FLUSH PRIVILEGES; - Linux 下
mydb和MYDB是两个库,授权时大小写必须严格一致 -
SHOW DATABASES;可快速确认库是否存在
GRANT后权限不生效:缓存、host、插件三重陷阱
执行成功 ≠ 权限落地。常见失效原因不是语法错,而是环境链路断在某个环节。
-
FLUSH PRIVILEGES在多数自动刷新场景下非必需,但在脚本化部署或权限表结构异常时显式执行更稳妥 - 连接时用的是
127.0.0.1(TCP),但只授权了'u'@'localhost'(Unix socket)——这是两个完全不同的账户,互不覆盖 - MySQL 8.0 默认认证插件是
caching_sha2_password,旧版 PHP/Python 驱动可能握手失败,建用户时得显式指定:CREATE USER 'u'@'h' IDENTIFIED WITH mysql_native_password BY 'pwd' - 验证是否真生效:用目标用户从授权 IP 连接,执行
SHOW GRANTS FOR 'u'@'h';,输出必须含你刚授的权限,而不是只有USAGE
GRANT报Unknown column或SHOW GRANTS为空:权限表结构损坏
这不是你写错了,是 MySQL 根本读不了权限字段。典型表现是 SELECT * FROM mysql.user; 报字段缺失,或 GRANT 成功但 SHOW GRANTS 返回空。
- MySQL 8.0 要求
mysql库所有系统表必须是 InnoDB 引擎,且字段名与官方定义严格一致(如password_last_changed) - 诱因包括:跨大版本升级未清空旧
mysql/目录、误用--skip-grant-tables后手动删改表、或从 5.7 拷贝 MyISAM 格式的user.MYD - 不要手改
mysql.user表字段 —— 正确做法是停库后运行:mysqld --upgrade=FORCE,让 MySQL 自动重建系统表结构 -
--skip-grant-tables下的UPDATE mysql.user是高危操作,漏改任意一个字段(如Account_locked)都可能导致后续认证失败
实际调试时最容易被忽略的,是把“执行没报错”当成“权限已生效”。真正要验证,必须走完整链路:从授权 IP 连接、登录、切换库、查表,缺一不可。











