zoukankan      html  css  js  c++  java
  • mysql如何修改所有的definer

     

    mysql中的definer是什么,有什么作用?

    我们在mysql创建view、trigger、function、procedure、event时都会定义一个Definer=‘xxx’,类似如下:

    CREATE
        ALGORITHM = UNDEFINED
        DEFINER = `root`@`%`
        SQL SECURITY DEFINER
    VIEW `v_ questions` AS
        SELECT
            `q`.`id` AS `id`,
            `q`.`title` AS `title`
        FROM
             Test q;
    或者像这样的:
    
    CREATE DEFINER=`root`@`%` PROCEDURE `user_count`()
      LANGUAGE SQL
      NOT DETERMINISTIC
      CONTAINS SQL
      SQL SECURITY DEFINER
      COMMENT ''
    BEGIN
        select count(*) from mysql.user;
    END

    加红的部分SQL SECURITY 其实后面有两个选项,一个为DEFINER,一个为INVOKER

    SQL SECURITY { DEFINER | INVOKER } :指明谁有权限来执行。DEFINER 表示按定义者拥有的权限来执行

    INVOKER 表示用调用者的权限来执行。默认情况下,系统指定为DEFINER 

    以存储过程为例:

    (1)MySQL存储过程是通过指定SQL SECURITY子句指定执行存储过程的实际用户;

    (2)如果SQL SECURITY子句指定为DEFINER,存储过程将使用存储过程的DEFINER执行存储过程,验证调用存储过程的用户是否具有存储过程的execute权限和DEFINER用户是否具有存储过程引用的相关对象的权限;

    (3)如果SQL SECURITY子句指定为INVOKER,那么MySQL将使用当前调用存储过程的用户执行此过程,并验证用户是否具有存储过程的execute权限和存储过程引用的相关对象的权限;

    (4)如果不显示的指定SQL SECURITY子句,MySQL默认将以DEFINER执行存储过程。

     

     

    我们来看下面几个小例子。

    先授权一个:
    grant all on testdb.* to 'user1'@'%' identified by '000000' with grant option;    
    然后我们创建一个存储过程如下:
    USE `testdb`;
    DROP procedure IF EXISTS `user_count`;
    DELIMITER $$
    USE `testdb`$$
    CREATE DEFINER=`root`@`%` PROCEDURE `user_count`()
      LANGUAGE SQL
      NOT DETERMINISTIC
      CONTAINS SQL
      SQL SECURITY INVOKER
      COMMENT ''
    BEGIN
        select count(*) from mysql.user;
    END$$
    DELIMITER ;

     

    用root帐号登陆:

    mysql> use testdb;
    Database changed
    mysql> call user_count();
    
    +----------+
    | count(*) |
    +----------+
    |        3 |
    +----------+
    1 row in set (0.00 sec)
    
    Query OK, 0 rows affected (0.00 sec)
    可以正常查询出来。
    
    我们再用user1进行登陆:
    
    mysql> use testdb;
    Database changed
    mysql> call user_count();
    ERROR 1142 (42000): SELECT command denied to user 'user1'@'localhost' for table 'user'

    发现系统报错查询不到了,这是因为我们在上述定义的SQL SECURITY值为INVOKER,存储过程执行过程中会以user1具有的权限来执行,其中调用到了mysql的库,而我们的user1帐户只有testdb库的使用权限,所以会返回失败。

     

    我们把上面的invoker改为definer再来试一下:

    update mysql.proc set security_type='DEFINER' where db='testdb' and name='user_count';
    
    再次用user1进行登陆:
    mysql> use testdb;
    Database changed
    mysql> call user_count();
    +----------+
    | count(*) |
    +----------+
    |        3 |
    +----------+
    1 row in set (0.00 sec)
    Query OK, 0 rows affected (0.00 sec)

     

    发现可以查询出来了,因为user1对存储过程user_count有执行的权限,虽然它依旧没有权限直接操作mysql库,由于我们定义的SQL SECURITY为DEFINER,所以在执行时是以root的身份执行的,所以可以正常查询出来。

     

    如果方便修改mysql中所有已经定义到的definer?

    由于前期在测试库上开发的缘故,我们经常定义到的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

     

    如果有找到方法的方法,记得留言,相互学习。

  • 相关阅读:
    作业20181127-1 附加作业 软件工程原则的应用实例分析
    20181120-1 每周例行报告
    20181113-2 每周例行报告
    获奖感言
    作业 20181030-4 每周例行报告
    20181023-3 每周例行报告
    Weekly 13
    Weekly 10
    Weekly 11
    weekly 8
  • 原文地址:https://www.cnblogs.com/zejin2008/p/4767531.html
Copyright © 2011-2022 走看看