必须显式授予grant execute on procedure db_name.proc_name to 'user'@'host',缺procedure关键字、对象粒度错误或host不匹配均导致授权失效;还需检查sql security definer是否有效及调用者或定义者对过程内涉及表的权限。

直接给 EXECUTE 权限,但必须写对语法——漏掉 PROCEDURE 关键字、用错对象粒度、或 host 不匹配,都会让授权静默失效。
GRANT EXECUTE ON PROCEDURE 语句必须带 PROCEDURE 关键字
MySQL 不接受模糊或省略写法。以下写法全都不行:
-
GRANT EXECUTE ON mydb.my_proc TO 'u'@'%'❌ 缺PROCEDURE,MySQL 当成数据库权限处理,实际没授到过程上 -
GRANT EXECUTE ON mydb.* TO 'u'@'%'⚠️ 虽然能执行,但会授予该库下所有现有及未来新建的存储过程,含他人创建的,安全风险高 -
GRANT EXECUTE ON FUNCTION mydb.my_func TO 'u'@'%'❌ 函数和过程权限不互通,不能混用
唯一可靠写法是:
GRANT EXECUTE ON PROCEDURE mydb.my_proc TO 'u'@'%';
注意:库名、过程名、用户名、host 都要严格匹配,包括引号和反引号(如含特殊字符)。
调用仍报 ERROR 1370?先查 DEFINER 和 SQL SECURITY
即使 GRANT EXECUTE 成功,运行时失败大概率是过程定义的问题。执行:
SHOW CREATE PROCEDURE my_proc;
重点看两处:
- 是否含
DEFINER=`some_user`@`%`—— 若该用户已被删或密码过期,过程就跑不动 - 是否含
SQL SECURITY DEFINER(默认值)—— 权限检查对象是 DEFINER,不是调用者
修复方向有两个:
- 重建过程,加
SQL SECURITY INVOKER,然后确保调用者有过程内所有表的SELECT/INSERT等权限 - 保留
DEFINER模式,但用管理员身份确认 DEFINER 用户存在、未锁定,并拥有过程里每条 SQL 所需的最小权限(比如过程里查other_db.t1,就得给 DEFINER 授SELECT ON other_db.t1)
SHOW GRANTS 看不到 EXECUTE 就基本等于没授权
验证是否真授了权,别信“我刚执行过了”。运行:
SHOW GRANTS FOR 'u'@'%';
输出里必须出现类似这一行才算生效:
GRANT EXECUTE ON PROCEDURE `mydb`.`my_proc` TO 'u'@'%'
常见误判点:
-
USAGE ON *.*只表示能连上,不等于能干任何事 - 只看到
SELECT, INSERT ON mydb.*,不代表能调过程 -
'u'@'localhost'和'u'@'%'是两个完全独立的账号,权限不共享
如果应用是从容器或云服务 IP 连的(比如 10.20.30.40),而你只授了 'u'@'localhost',那一定失败。
跨库操作时 EXECUTE 权限只是起点
GRANT EXECUTE 只解决“能不能 CALL”,不解决“CALL 之后能不能跑完”。例如过程里有:
INSERT INTO log_db.audit_log VALUES (...);
那么:
- 若过程是
SQL SECURITY DEFINER,就要确保 DEFINER 用户有INSERT ON log_db.audit_log - 若过程是
SQL SECURITY INVOKER,就要确保调用者(即当前连接用户)有该权限
别指望靠一次授权一劳永逸——过程内部访问哪些库、哪些表,就得对应补哪些权限,粒度必须对得上。











