lsg00 2019-05-02
我们在mysql创建view、trigger、function、procedure、event时都会定义一个Definer=‘xxx’,类似如下:
加红的部分SQL SECURITY 其实后面有两个选项,一个为DEFINER,一个为INVOKER
SQL SECURITY { DEFINER | INVOKER } :指明谁有权限来执行。DEFINER 表示按定义者拥有的权限来执行
INVOKER 表示用调用者的权限来执行。默认情况下,系统指定为DEFINER
1、创建一个definer存储过程
用root帐号登陆:
发现系统报错查询不到了,这是因为在上述定义的SQL SECURITY值为INVOKER,存储过程执行过程中会以user1具有的权限来执行,其中调用到了mysql的库,而我们的user1帐户只有testdb库的使用权限,所以会返回失败。
2、修改为invoker存储过程
发现可以查询出来了,因为user1对存储过程user_count有执行的权限,虽然它依旧没有权限直接操作mysql库,由于我们定义的SQL SECURITY为DEFINER,所以在执行时是以root的身份执行的,所以可以正常查询出来。
因为开发经常用root来创建函数或者创建存储过程,定义到的definer为`root`@`%`,存在着大量的更新,上百个的视图,函数等一个个改不免太麻烦并且也可能遗漏。如下为总结出的方便修改所有definer的方法,可以直到查漏补缺的作用。
现在在mysql涉及的definer有view、trigger、function、procedure、event。
1.修改function、procedure的definer
select definer from mysql.proc; -- 函数、存储过程 update mysql.proc set definer='user@localhost'; -- 如果有限定库或其它可以加上where条件
2.修改event的definer
select DEFINER from mysql.EVENT; -- 定时事件 update mysql.EVENT set definer=' user@localhost ';
3.修改view的definer
相比function的修改麻烦点:
select DEFINER from information_schema.VIEWS; select concat("alter DEFINER=`user`@`localhost` SQL SECURITY DEFINER VIEW ",TABLE_SCHEMA,".",TABLE_NAME," as ",VIEW_DEFINITION,";") from information_schema.VIEWS where DEFINER<>'user@localhost';
查询出来的语句再执行一遍就好了。
4.修改trigger的definer
目前还没有具体方便的方法,可以借助工具端如HeidiSQL、sqlyog等来一个个修改。注意改前有必要锁表,因为如果改的过程中有其它表改变而触发,会造成数据不一致。
Flush tables with readlock Unlock tables
篇幅有限,关于definer的内容就介绍到这了,大家有兴趣可以研究下,对mysql的权限管理的理解还是很有帮助的。
后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注一下~