mysql 5.7+ 中直接 update mysql.user 会报错 error 1356,因其是只读视图;必须用 rename user 逐 host 安全重命名,并执行 flush privileges 验证。

直接 UPDATE mysql.user 会失败
MySQL 5.7+ 版本中 mysql.user 是个只读视图,不是真实表。执行 UPDATE mysql.user SET User = 'admin' WHERE User = 'root' 会立刻报错:ERROR 1356 (HY000): View 'mysql.user' references invalid table(s) or column(s)。这不是权限问题,是元数据层强制限制——硬改会破坏内部一致性,严重时导致实例无法启动。
必须用 RENAME USER 逐 host 处理
这是唯一被 MySQL 官方支持、原子且安全的方式。它同步更新权限、认证字段和缓存,不依赖 FLUSH PRIVILEGES(但显式执行更稳妥)。关键点在于:User + Host 共同构成一个完整账号,不能只改用户名忽略 host。
- 先查全量账号:
SELECT User, Host FROM mysql.user WHERE User = 'root'; - 常见组合有
'root'@'localhost'、'root'@'127.0.0.1'、'root'@'%',必须分别重命名 - 执行:
RENAME USER 'root'@'localhost' TO 'admin'@'localhost'; - 再执行:
RENAME USER 'root'@'127.0.0.1' TO 'admin'@'127.0.0.1'; - 最后:
FLUSH PRIVILEGES;
重命名后连不上?大概率是 host 或 plugin 不匹配
RENAME USER 不会改变原记录的 plugin 和 authentication_string,但某些客户端(如旧版 Workbench)对认证插件名(如 caching_sha2_password)敏感,会拒绝连接。另外,应用可能连的是未被重命名的账号,比如你只动了 'root'@'%',但程序实际走的是 'root'@'192.168.10.5'——这个账号还存在,且权限没变,导致“改了却没生效”的错觉。
- 检查连接来源:
SELECT USER(), CURRENT_USER();看实际匹配的是哪个账号 - 确认新账号插件:
SELECT User, Host, plugin FROM mysql.user WHERE User = 'admin'; - 必要时手动同步插件:
ALTER USER 'admin'@'localhost' IDENTIFIED WITH caching_sha2_password BY '$A$...';
别漏掉自动化工具和权限继承验证
运维脚本、监控系统、备份任务常硬编码 root 用户名,改完立刻失效;而 RENAME USER 虽然保留全局权限,但不会自动迁移 mysql.db 或 mysql.tables_priv 中以旧名写的记录——不过 root 本来就不靠这些表赋权,真正要盯的是 SUPER、GRANT OPTION 是否还在。
- 验证权限:
SHOW GRANTS FOR 'admin'@'localhost'; - 检查冲突:
SELECT User, Host FROM mysql.user WHERE User = 'admin';,避免重命名时目标账号已存在 - 生产环境务必低峰期操作,并提前备份当前用户状态:
SELECT * FROM mysql.user INTO OUTFILE '/tmp/user_pre_rename.csv';
重命名本身毫秒级完成,但后续验证和配套更新才是耗时主力,尤其是当多个系统依赖该用户名时,漏掉一处就可能引发连锁故障。











