rename user 是 mysql 官方支持的原子性账号重命名操作,仅修改 mysql.user 表、不中断活跃连接、自动迁移权限,但需手动处理角色授权和 proxy user 关系,并严格按数据库改名→应用配置更新→滚动重启顺序执行。

RENAME USER 是唯一合法且原子的操作
MySQL 从 5.0 起就支持 RENAME USER,它不是临时补丁,而是官方定义的、事务安全的账号重命名方式。它只改 mysql.user 表里的记录,不碰权限表结构,也不影响已建立的连接——旧账号的活跃会话仍能继续执行完,新账号从下一次连接开始生效。
常见错误是误以为要先删旧用户再建新用户,那样会导致权限丢失(比如 GRANT 记录没迁移)或中间窗口期无权限可用。而 RENAME USER 是单条 SQL,要么全成功,要么全失败,不会留下半截状态。
-
RENAME USER 'old_user'@'%' TO 'new_user'@'%';—— 主机名必须完全匹配,'old_user'@'localhost'和'old_user'@'127.0.0.1'是两个不同账号,需分别 rename - 不能跨主机重命名:不允许把
'user'@'192.168.1.100'改成'user'@'%',host 部分必须保持一致 - 目标用户名不能已存在,否则报错
ERROR 1396 (HY000): Operation ALTER USER failed for 'new_user'@'%'
线上业务不停服的关键动作顺序
重命名本身不中断服务,但应用配置若硬编码了旧用户名,就会在下次连接时失败。所以真正风险不在数据库侧,而在应用侧衔接。
必须按这个顺序操作,缺一不可:
- 先在数据库里执行
RENAME USER,让新账号具备全部权限 - 立刻更新所有应用配置文件、连接池配置、环境变量中的
username字段为新账号名 - 滚动重启应用实例(避免一次性全量重启导致雪崩),每台机器重启前确认旧连接已自然断开(可通过
SHOW PROCESSLIST观察old_user连接数归零) - 观察监控指标(如连接成功率、QPS、慢查询)稳定 5 分钟以上,再操作下一台
别跳过滚动重启——哪怕应用用了连接池,池子里可能还缓存着旧用户的空闲连接,直接切配置会导致部分请求认证失败。
权限继承与隐式陷阱
RENAME USER 会把原账号在 mysql.db、mysql.tables_priv 等所有权限表中的记录自动迁移到新账号名下,这点很可靠。但有两个容易被忽略的例外:
- 如果旧账号有通过
CREATE USER ... IDENTIFIED WITH ...指定了插件(如caching_sha2_password),新账号会继承同一插件和密码哈希,但某些旧客户端不支持新插件,需同步升级驱动或显式指定default_authentication_plugin - 如果旧账号被授予了角色(
GRANT role_name TO 'old_user'@'%'),角色授权不会自动转移,必须手动补一句GRANT role_name TO 'new_user'@'%' - 应用如果用到了
PROXY USER(比如 web 用户代理到后端账号),代理关系绑定的是用户名字面值,rename 后需同步调整SET DEFAULT ROLE或代理配置
验证是否真完成,别只看 user 表
执行完 RENAME USER 后,光查 SELECT User, Host FROM mysql.user 不够。必须验证三件事:
- 用新账号连一次:
mysql -u new_user -p -e "SELECT 1",确认能登录且无权限拒绝 - 检查权限是否完整:
SHOW GRANTS FOR 'new_user'@'%';,对比 rename 前旧账号的输出,确保行数和内容一致 - 查是否有残留旧账号连接:
SELECT ID, USER, HOST FROM information_schema.PROCESSLIST WHERE USER = 'old_user';,非零结果说明还有活跃会话,得等它们自然退出或 kill 掉(KILL [ID])
最常漏掉的是角色授权和代理关系,它们不在 mysql.user 里,只出现在其他系统表中,不显式检查就上线,半夜告警才暴露。











