EXECUTE权限仅对指定数据库和函数名生效,不支持全局通配;必须显式授予如GRANT EXECUTE ON FUNCTION mydb.my_func TO 'user1'@'localhost',且函数名大小写需与SHOW FUNCTION STATUS一致。

EXECUTE权限只对具体函数生效,不能跨库或全局授予
给用户授予EXECUTE权限时,MySQL要求明确指定函数所在的数据库和函数名,不支持EXECUTE ON *.*这种写法。否则会报错:ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES。
- 正确写法是:
GRANT EXECUTE ON FUNCTION mydb.my_func TO 'user1'@'localhost'; - 如果函数在
test库,但用户被授权的是mydb库的EXECUTE,调用时仍会报ERROR 1370 (42000): execute command denied to user - 函数名区分大小写(取决于系统变量
lower_case_table_names),授权时必须与SHOW FUNCTION STATUS中显示的完全一致
CREATE ROUTINE权限 ≠ EXECUTE权限,两者必须分开授予
开发人员创建函数需要CREATE ROUTINE,但调用者只需要EXECUTE。很多团队误以为给了CREATE ROUTINE就自动获得执行权,结果导致调用失败。
-
CREATE ROUTINE允许创建/修改函数,但不赋予执行能力 - 用户A创建了函数
mydb.calc_tax,用户B即使有EXECUTE ON FUNCTION mydb.calc_tax,也必须由DBA显式授权,不能靠“创建者默认可执行”机制 - 若函数定义中包含
SQL SECURITY DEFINER,执行时检查的是定义者的权限,而非调用者——这是越权高发点
SQL SECURITY DEFINER容易引发隐式越权
当函数以DEFINER方式创建(默认行为),其执行权限基于函数所有者的权限,而不是调用者。这意味着一个只有SELECT权限的用户,可能通过调用某个DEFINER函数间接执行UPDATE或读取其他库数据。
- 检查函数定义:
SHOW CREATE FUNCTION mydb.my_func;,关注SQL SECURITY字段 - 生产环境强烈建议统一使用
SQL SECURITY INVOKER,让函数权限严格受限于调用者已有权限 - 若必须用
DEFINER,定义者账号应为专用低权限账号(如func_runner@localhost),且该账号不应拥有FILE、SUPER等高危权限
角色绑定后必须显式激活才能生效
MySQL 8.0角色不会自动激活,即使已用GRANT role_name TO user绑定,用户连接后仍需执行SET ROLE role_name或SET ROLE ALL,否则EXECUTE等权限不生效。
- 验证是否激活:
SELECT CURRENT_ROLE();,返回NULL说明未激活 - 避免在应用连接池中遗漏该步骤——连接复用时角色状态不会自动继承
- 可通过
SET DEFAULT ROLE role_name TO user设为默认角色,减少每次连接的手动激活
SQL SECURITY模式、角色激活状态、函数定义变更都会动态影响执行边界。最常被忽略的是DEFINER函数在权限继承链中的穿透效应——它让EXECUTE变成一把双刃剑。


















