ERROR 1227报错根本原因是执行账号缺少RELOAD权限,而非新建用户权限不足;FLUSH PRIVILEGES仅在直接修改mysql系统表时必需,CREATE USER/GRANT等标准操作自动生效,无需手动刷新。

新建用户后执行 FLUSH PRIVILEGES 报错 ERROR 1227
根本原因不是“新建用户没权限”,而是执行 FLUSH PRIVILEGES 的账号本身缺少 RELOAD 权限。MySQL 默认只给 root 或显式授过该权限的用户开放此操作。
常见错误现象:ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
- 用
CREATE USER 'u1'@'localhost'创建用户后,该用户只有USAGE权限,连登录都可能受限,更不可能执行FLUSH PRIVILEGES - 即使你用
root登录,如果该root账号是只读实例(如从库)上创建的,也会因--read-only模式报ERROR 1290 -
FLUSH PRIVILEGES不是“授权语句”,它不改变权限,只是重载内存——所以不能靠它来“补救”权限缺失
为什么新建用户后还要手动 FLUSH PRIVILEGES?
只有当你**绕过 GRANT/CREATE USER 接口,直接 INSERT 或 UPDATE mysql.user 表**时,才需要 FLUSH PRIVILEGES。而正规新建用户流程根本不需要它。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
-
CREATE USER 'u1'@'localhost' IDENTIFIED BY 'pwd';→ 自动写表 + 自动加载内存,无需FLUSH -
GRANT SELECT ON mydb.* TO 'u1'@'localhost';→ 同样自动生效,FLUSH是冗余操作 - 如果你手写
INSERT INTO mysql.user (User, Host, authentication_string, ...) VALUES (...);→ 必须FLUSH PRIVILEGES,否则新用户根本不会被识别 - 误以为“新建用户 = 必须 flush”,其实是混淆了 DML 直接改表和 SQL 权限命令的区别
ERROR 1045 出现时,别急着 FLUSH PRIVILEGES
Access denied for user 'u1'@'localhost'(错误码 1045)几乎从不因为“缓存没刷新”,而是 Host 匹配失败、认证插件不兼容或密码字段写错位置。
-
'u1'@'localhost'和'u1'@'127.0.0.1'是两个完全独立的用户,连Host字段大小写都敏感(如'localhost'≠'LOCALHOST') - MySQL 8.0+ 新建用户默认用
caching_sha2_password插件,老客户端(如某些 PHP 扩展、旧版 MySQL Workbench)不支持,会直接拒连——此时FLUSH PRIVILEGES完全无效 - 检查是否误把密码写进了
Password字段(已废弃),而实际该填authentication_string;或者用了明文字符串而非SHA2('pwd',256)加密值 - 确认连接时指定的 host 是否和用户记录中
Host值严格一致(例如用mysql -h 127.0.0.1 -u u1就匹配不到'u1'@'localhost')
FLUSH PRIVILEGES 失效的隐藏前提
它看起来是个“万能刷新键”,但前提是:权限表本身完好、字符集一致、没有损坏行。一旦底层出问题,FLUSH 只是把坏数据更快地加载进内存。
-
mysql.user表用了utf8mb4,但客户端连接用latin1发送查询 → 可能导致用户名乱码,FLUSH后反而找不到对应用户 - 权限表被误删过某列(比如少了个
account_locked字段)、或有重复主键(User+Host不唯一)→FLUSH会静默跳过异常行,造成“部分用户权限丢失”假象 - 在 Docker 环境中,若挂载的
/var/lib/mysql卷权限不对,或容器启动时未正确初始化mysql系统库 →FLUSH PRIVILEGES可能无报错但不生效 - 最易被忽略的一点:
FLUSH PRIVILEGES只影响新连接,已有连接仍用旧权限快照——哪怕你刚 flush 完,立刻用同一连接SELECT USER(), CURRENT_USER();,看到的仍是旧上下文

















