rename database 在 mysql 5.7.23+ 已被彻底移除,无法通过权限禁用;替代方案是新建库+导出导入+删旧库,需通过收回 create、drop 和跨库写入权限来阻断“伪重命名”链。

MySQL 里 RENAME DATABASE 已被移除,别白费劲去禁用它
MySQL 5.7.23 之后,RENAME DATABASE 语句直接被删了,执行会报错:ERROR 1064 (42000): You have an error in your SQL syntax。所以你根本不需要、也没法通过权限控制去“禁用”这个命令——它压根不存在了。
真正能重命名数据库的惯用做法,是新建库 + 导出导入 + 删旧库,或者用 mysqldump + mysql 命令组合。这类操作不依赖单条 SQL 权限,而是靠用户能否连上、能否创建库、能否读写表来间接控制。
禁止用户用 ALTER DATABASE 修改库级属性
ALTER DATABASE 本身不改库名,但能改默认字符集、排序规则等,属于库级元数据操作。如果不想让用户调整这些,得收回 ALTER 权限:
REVOKE ALTER ON `old_db`.* FROM 'user'@'%';- 注意:权限粒度是
ON database_name.*,不是ON database_name(后者语法错误) - 如果用户有
ALL PRIVILEGES,必须显式REVOKE ALTER,因为 MySQL 不支持“部分回收 ALL” - 执行后记得
FLUSH PRIVILEGES;,否则权限变更不生效
真正防“重命名效果”的关键:锁死建库和删库权限
用户绕过 RENAME 实现重命名,典型路径是:CREATE DATABASE new_db → CREATE TABLE new_db.t AS SELECT * FROM old_db.t(或用 mysqldump 导入)。要阻断这条链,得卡住三个环节:
- 禁止建库:
REVOKE CREATE ON *.* FROM 'user'@'%';(注意是*.*,不是某个库) - 禁止删库:
REVOKE DROP ON *.* FROM 'user'@'%';(否则可能先删旧库再建新库) - 限制跨库写入:确保用户对目标库(比如
new_db)没有CREATE或INSERT权限,否则仍可把数据导进去 - 如果用
mysqldump --databases,还要注意:只要用户有源库SELECT权限 + 目标库CREATE/INSERT权限,就能完成“伪重命名”
权限回收后仍要小心的边界情况
权限系统不是万能的,尤其在多租户或代理连接场景下:
- 如果用户有
PROCESS权限,能看到其他连接的SHOW PROCESSLIST,可能发现临时库名或备份脚本逻辑 - 使用
mysqlpump或第三方工具时,若连接账号权限高,而应用层没做隔离,实际还是可能触发跨库操作 - MySQL 8.0+ 的角色(
ROLE)管理容易遗漏:收回用户权限后,检查是否还被某个角色隐式授予了CREATE/DROP -
root或具备GRANT OPTION的账号,随时可以重新赋权,这类账号必须严格管控登录来源和密码强度
防重命名本质是防“新建+迁移+清理”这一整套动作,不是盯住某条 SQL 就行。权限收得再紧,如果应用代码里硬编码了 CREATE DATABASE 或调用了系统命令,照样会漏。











