mysql 8.0.16+ 才真正支持 grant execute on procedure db_name.proc_name,5.7 及更早版本执行即报 error 1064;必须先授 usage 权限,且过程名须带库名,不支持通配符。

GRANT EXECUTE ON PROCEDURE 语法是否真正生效
MySQL 8.0.16+ 才真正支持 GRANT EXECUTE ON PROCEDURE db_name.proc_name,5.7 及更早版本执行该语句会直接报错 ERROR 1064。别被文档或旧教程误导——不是“写法对不对”,而是“版本支不支持”。
- 先确认版本:
SELECT VERSION(); - 必须前置授予数据库级
USAGE权限:GRANT USAGE ON `mydb`.* TO 'dev'@'%';(缺这步,后续GRANT EXECUTE ON PROCEDURE会静默失败) - 过程名不能省略库名:
GRANT EXECUTE ON PROCEDURE calc_score错误;必须写成GRANT EXECUTE ON PROCEDURE mydb.calc_score - 不支持通配符过程名:
GRANT EXECUTE ON PROCEDURE mydb.*是非法语法;若想授整个库所有过程,用GRANT EXECUTE ON mydb.*(注意:这包含函数,不只是过程)
CALL 过程仍报 ERROR 1370 的真实原因
授了 EXECUTE 权限,CALL mydb.sync_data() 却报 ERROR 1370 (42000): execute command denied,大概率不是权限没给,而是过程内部 SQL 在权限校验时失败。
- 查定义者:
SHOW CREATE PROCEDURE mydb.sync_data,看DEFINER字段。若为'dba'@'localhost',而该账号已被删或权限回收,过程即失效 - 过程内用了跨库表(如
other_db.users),但DEFINER对other_db没权限,也会触发此错 - 连接主机名不匹配:授权是
'dev'@'10.0.1.%',但实际连的是'dev'@'localhost',MySQL 视为不同用户 -
SHOW GRANTS不显示EXECUTE ON PROCEDURE—— 别信它,直接CALL测试才可靠
让权限真正落在调用者身上:SQL SECURITY INVOKER
默认 SQL SECURITY DEFINER 会让过程以定义者身份执行,绕过调用者权限检查。想让过程“只在调用者有对应表权限时才成功”,必须改用 INVOKER。
- 新建过程时指定:
CREATE DEFINER='admin'@'%' SQL SECURITY INVOKER PROCEDURE mydb.sp_count_users() - 修改已有过程:
ALTER PROCEDURE mydb.sp_count_users SQL SECURITY INVOKER(需ALTER ROUTINE权限) - 验证当前设置:
SELECT ROUTINE_NAME, SQL_SECURITY FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='mydb' AND ROUTINE_NAME='sp_count_users'; - 改完后,调用者必须显式拥有过程内所有 DML 涉及的表权限,例如过程里有
INSERT INTO logs,就得GRANT INSERT ON mydb.logs TO 'dev'@'%'
为什么 REVOKE 单个过程权限没用
MySQL 的 EXECUTE 权限继承自数据库层级。只要用户有 mydb.* 的 EXECUTE,哪怕你执行 REVOKE EXECUTE ON PROCEDURE mydb.sp_x FROM 'dev'@'%',CALL mydb.sp_x() 依然成功——这不是 bug,是设计逻辑。
-
REVOKE EXECUTE ON PROCEDURE在 MySQL 中基本无效,仅当用户只有单个过程权限、无库级EXECUTE时才起作用(极少见) - 真正隔离过程执行,靠的是
SQL SECURITY INVOKER+ 调用者表权限控制,而不是靠 revoke - 别用
GRANT SELECT ON mysql.proc或INFORMATION_SCHEMA.ROUTINES替代——这会让用户看到所有过程定义,严重越权
最常被忽略的点不是“怎么授 EXECUTE”,而是“过程以谁的身份查哪张表”。DEFINER 和 INVOKER 的选择,决定了权限边界在哪——这个开关不改,其他操作都是表面功夫。











