本质是MySQL内核拒绝加载非法记录:authentication_string哈希格式、plugin字段、account_locked等状态必须严格匹配且合法,否则FLUSH PRIVILEGES会静默跳过该行;同时需确保user/db/tables_priv三表字段精确关联,并通过SELECT USER(), CURRENT_USER()确认实际匹配的账号。

UPDATE mysql.user 后权限不生效,本质是数据不被 MySQL 认可
直接改 mysql.user 表后执行 FLUSH PRIVILEGES 仍连不上,不是缓存没刷,而是 MySQL 内核压根拒绝加载那条记录。它校验的是字段组合的合法性:比如 authentication_string 必须是 SHA256 哈希值,且必须和 plugin 字段严格匹配(caching_sha2_password 对应特定格式,mysql_native_password 对应另一种)。手动 UPDATE 很容易填错哈希、漏改 plugin、写错字段名(如还用已废弃的 Password),甚至忽略 account_locked 或 password_last_changed 等状态字段——这些字段一旦非法,MySQL 重载时会静默跳过该行,导致账号“查得到但用不了”。
系统用户宿主表(user/db/tables_priv)之间存在强约束关系
权限不是孤立生效的。mysql.user 控制登录和全局权限,mysql.db 控制库级权限,mysql.tables_priv 控制表级权限,三者通过 User 和 Host 字段关联。如果只更新了 user 表里的 authentication_string,却忘了同步 db 表里对应 User+Host 的记录(比如 Db 字段大小写不一致、Host 多了个空格),或者 tables_priv 里残留了旧的 Table_priv 值(如只含 Select 却没清空 Insert),就会出现“能连上但 SELECT 都被拒”的现象。MySQL 不会自动补全或修正这些不一致,它只按字段精确匹配执行授权逻辑。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
CURRENT_USER() 返回的才是真实生效的宿主记录
执行 SELECT USER(), CURRENT_USER(); 是最直接的验证手段:USER() 是你声明的身份(比如 'u'@'127.0.0.1'),而 CURRENT_USER() 才是 MySQL 实际查到并用于权限判定的那一行(比如 'u'@'localhost')。很多“权限突然失效”其实是客户端连接方式变了(socket → TCP),但你只给 'u'@'localhost' 授权,没给 'u'@'127.0.0.1' 或 'u'@'%';或者 DNS 解析导致实际匹配到了另一条 Host 更宽泛但权限更少的记录。不比对这两个值,就永远不知道 MySQL 真正在用哪一行做判断。
修复前必须确认是否处于 --skip-grant-tables 模式
如果 MySQL 曾以 --skip-grant-tables 启动过,权限系统会被绕过,后续即使重启、执行 FLUSH PRIVILEGES,也可能因缓存未重建或表结构未加载而持续异常。先运行 SELECT @@skip_grant_tables; 确认返回值为 OFF;再检查 mysql.user 表字段是否完整(比如是否有 plugin、authentication_string),若缺失,说明权限表结构本身没升级到位,得先跑 mysqld --upgrade=FORCE 而非继续修数据。
GRANT 或 ALTER USER 的直接写表操作,都得先问一句:这个值,MySQL 自己在创建用户时会不会生成?

















