非root用户默认无法创建存储过程或函数,必须显式授予create routine权限,因创建例程属于独立权限范畴,仅grant create on db.不足以授权;还需配合alter routine(修改)、execute(调用)权限,且须作用于数据库级别(如db.),并推荐使用sql security invoker避免definer权限校验问题。

非root用户默认无法创建存储过程或函数,必须显式授予 CREATE ROUTINE 权限,并确保 sql_mode 不含 NO_AUTO_CREATE_USER(已弃用)或限制性设置;否则即使授权也会报错 ERROR 1419 (HY000): You do not have the SUPER privilege...。
为什么 GRANT CREATE ON db.* 不够?
MySQL 中创建存储过程/函数不是普通 DDL 操作,它属于“例程(routine)”范畴,需要独立的权限位。仅给 CREATE 权限只能建表,不能建 procedure 或 function。
-
CREATE ROUTINE:允许创建、修改存储过程和函数 -
ALTER ROUTINE:允许修改或删除自己创建的例程(注意:不能改别人创建的,除非有super) -
EXECUTE:允许调用(但不隐含查看定义的权限)
这三项权限需单独授予,且必须作用于数据库级别(如 testown.*),不能是 *.*(除非你真要全局授权)。
执行授权时必须指定 DEFINER 吗?
不需要在 GRANT 语句里写 DEFINER —— 那是创建例程时的属性,不是权限控制点。但要注意:
如果用户用 DEFINER='root'@'%' 创建过程,那普通用户即使有 EXECUTE 权限也无法调用(因安全机制会校验 definer 权限)。所以建议:
- 新建例程时统一用
SQL SECURITY INVOKER(推荐) - 或明确设
DEFINER = 'username'@'%',与当前登录用户一致 - 避免依赖
DEFINER = 'root'@'%',否则必须额外给该用户SUPER权限(极不安全)
常见报错及绕过方式
典型错误:ERROR 1419 (HY000): You do not have the SUPER privilege and binary logging is enabled...
这是 MySQL 5.6+ 的安全限制:当启用 binlog 时,DEFINER 为高权限账户会触发校验。解决方法只有两个:
- 关闭 binlog(生产环境严禁)
- 改用
SQL SECURITY INVOKER并确保所有相关权限已授予(最稳妥)
验证是否生效:登录目标用户后执行 SHOW GRANTS;,确认输出中包含 GRANT CREATE ROUTINE ON `testown`.* TO 'username'@'%'。
真正容易被忽略的是:权限变更后必须执行 FLUSH PRIVILEGES;(仅在直接操作 mysql.user 表时才需要;用 GRANT 语句则自动生效),以及例程创建时的 DELIMITER 设置——漏掉它会导致语法解析失败,错误信息却指向第一行 CREATE PROCEDURE,让人误以为是权限问题。











