ERROR 1396主因是'user'@'host'残留,如DROP USER 'u'仅删'@localhost'而'@%'仍存在;须先SELECT查全量host,再显式DROP所有变体,最后CREATE USER并指定认证插件。

MySQL 8.0 中“同名用户”根本不存在——真正冲突的是 'user'@'host' 这个完整标识符。所谓“无法创建同名用户”,99% 是因为残留了不同 host 的同名账号,或误删未清空。
为什么 DROP USER 'u' 后 CREATE USER 'u'@'localhost' 仍报 ERROR 1396
执行 DROP USER 'u' 实际只删除 'u'@'localhost'(MySQL 默认 host),但若之前建过 'u'@'%' 或 'u'@'127.0.0.1',这些记录仍在 mysql.user 表里。再执行 CREATE USER 'u'@'localhost' 时,系统发现 'u' 这个用户名在其他 host 下已存在,直接拒绝创建,抛出 ERROR 1396。
- 必须显式查全量:
SELECT user, host FROM mysql.user WHERE user = 'u'; -
DROP USER不支持模糊匹配,'u'和'u'@'localhost'是两个语法;不带 host 的写法是历史兼容行为,仅作用于 localhost - 别用
DELETE FROM mysql.user手动删——它绕过权限系统内部清理逻辑,后续可能引发认证失败或权限不生效
安全重建用户的三步操作顺序
按这个顺序做,基本避开 1396:
- 先确认残留:
SELECT user, host FROM mysql.user WHERE user = 'u'; - 逐个显式删除:
DROP USER 'u'@'localhost', 'u'@'%', 'u'@'127.0.0.1';(把上一步查到的所有行都列进去) - 立即验证是否清空:
SELECT user, host FROM mysql.user WHERE user = 'u';—— 结果应为空 - 再创建:
CREATE USER 'u'@'localhost' IDENTIFIED WITH mysql_native_password BY 'pwd';(加插件指定,避免客户端兼容问题)
容易被忽略的两个硬性细节
'u'@'%' 和 'u'@'localhost' 完全独立:密码、权限、认证插件都可以不同。本地连接默认走 socket,匹配的是 'u'@'localhost',不是 'u'@'%' —— 这导致很多“远程能连、本地连不上”的调试困境。
- MySQL 8.0 默认认证插件是
caching_sha2_password,老客户端(如 Navicat ≤15.0、PyMySQL ALTER USER 'u'@'localhost' IDENTIFIED WITH mysql_native_password BY 'pwd'; -
FLUSH PRIVILEGES对DROP USER/CREATE USER非必需,但它对ALTER USER后立即生效有帮助;如果建户后立刻改插件,建议加上这句
真正卡住人的从来不是语法对错,而是没意识到 MySQL 把 user 和 host 当作不可分割的键,以及没检查 host 维度的残留。多查一次 SELECT user, host,比反复试错快得多。


















