all权限用户无法执行存储过程

   我们使用存储过程的时候,往往只注意要给调用存储过程的账号赋予相应权限,但是实际上存储过程定义用户与这个存储过程能否被执行有直接关系,如果不知道这点,即使调用存储过程的账号具备存相关权限,一样还是不能执行存储过程。

语法:

CREATE DEFINER=`xx`@`%` PROCEDURE `mmm`

这里DEFINER有两种模式Security definerSecurity invoker


Security definer
   definer:在执行存储过程前验证definer对应的用户如:xx@%是否存在,以及是否具有执行存储过程的权限。

Security invoker
   invoker:在执行存储过程时判断调用该存储过程的用户是否有相应权限。

   其实,用简单明了语言解释下可能更容易理解:

SECURITY DEFINER 表示定义者必须有相关权限。

SECURITY INVOKER 表示只要调用者有相关权限即可。


问题描述:

   今天一个别的部门的DBA同事,要我帮忙处理一个问题。说他们业务开发的程序不能正确执行存储过程,由于他们的很多业务逻辑关系都是放在存储过程中判断,而非程序判断。所以这个问题极其重要,直接导致了业务不可用。前端报错感觉是权限不够,且所有调用存储过程的账号都是同一个aaa(这里用aaa表示业务账户),检查了这个用户的权限,没有问题,最后甚至赋予了all权限,但问题依旧。到这他和他们部门同事都认为不再是权限不够的问题。尝试了一些别的方法都无法解决,问题一直就卡在这了,所有人在那着急。


   我上去分析了一下,确实如他们描述一样。到库上随机看了一个存储过程c:

  1. CREATE DEFINER=`xx_user`@`%` PROCEDURE `DBQ_MMM`  其它所有存储过程皆是如此。  

  2. show grants for 'xxx_user'@'%' 查看发现没有EXECUTE 运行存储过程的这个权限

  3. 接着,show procedure status like 'c'

      注意Security_type这里是DEFIN,所以虽然前端程序使用的是具有all权限的aaa账户,但是定义者xxx_user没有执行权限。存储过程依旧不能被执行,也就难怪为啥纠了结半天最大权限的用户依然还是没有权限了。至于这个用户的EXECUTE权限是人为revoke误操作,还是以前使用的是INVOKER模式,那就不知道了。但是前者99%的可能。虚惊一场,真是小问题险些造成大事故啊。


解决方法:

      修改存储过程定义用户,给一个具有执行权限的用户即可

      如果是从别的库导过来的,有大量存储过程一个个修改太麻烦,提供两个思路:

  1. 在导出的sql中用sed替换,然后再导入到 新库中。

  2. 直接建立一个与原先库中的定义用户一样的用户。




你可能感兴趣的:(mysql,存储过程,故障)