zoukankan      html  css  js  c++  java
  • mysql用户创建触发器权限不足跟参数log_bin_trust_function_creators

    问题描述

    有业务反馈当前用户无法创建触发器和存储过程,让用户自己测试,该用户进行对表的增删改查等其他权限没有问题,这边用root用户查证,该用户拥有对当前库的所有权限,但是为什么就是创建不了触发器呢?创建语句不涉及其他库,只是对当前库进行创建触发器,下面自己进行测试。

    处理过程:将参数log_bin_trust_function_creators设置为ON即可

    现有一下疑问?

    1.用户拥有对当前库的所有权限,但是为什么创建不了触发器呢?

    2.log_bin_trust_function_creators参数打开或关闭对创建触发器有什么影响呢?

    3.如果对用户授予一个对所有库的创建触发器,存储过程权限,会不会有效呢?

    报错:

    ERROR 1442 (HY000): Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

    测试过程:

    1.创建测试相关用例

    创建测试用例:
    mysql> create database gwhdgl;
    mysql> create user gwhdgl@'%' identified by '123';
    mysql> grant all privileges on gwhdgl.* to gwhdgl@'%';
    mysql> grant select on mysql.* to gwhdgl@'%';
    mysql> show grants for gwhdgl@'%';
    +----------------------------------------------------+
    | Grants for gwhdgl@%                                |
    +----------------------------------------------------+
    | GRANT USAGE ON *.* TO 'gwhdgl'@'%'                 |
    | GRANT ALL PRIVILEGES ON `gwhdgl`.* TO 'gwhdgl'@'%' |
    | GRANT SELECT ON `mysql`.* TO 'gwhdgl'@'%'          |
    +----------------------------------------------------+
    3 rows in set (0.00 sec)
    
    创建测试表:
    mysql> select * from t1;
    +------+--------+-----------+
    | id   | name   | start_url |
    +------+--------+-----------+
    |    1 | 张三   | Y         |
    |    2 | 李四   | Y         |
    |    3 | 王五   | Y         |
    |    4 | 马六   | Y         |
    |    5 | 是无   | Y         |
    |    6 | 亏刘   | Y         |
    +------+--------+-----------+
    6 rows in set (0.01 sec)
    
    mysql> 
    mysql> select * from t2;
    +------+--------+-----------+
    | id   | name   | start_url |
    +------+--------+-----------+
    |    1 | 张三   | Y         |
    |    2 | 李四   | Y         |
    |    3 | 王五   | Y         |
    |    4 | 马六   | Y         |
    |    5 | 是无   | Y         |
    |    6 | 亏刘   | NULL      |
    +------+--------+-----------+
    6 rows in set (0.00 sec)

    2.创建触发器,报错ERROR 1442

    mysql -ugwhdgl -p123 -h192.168.163.21 -P13306

    DELIMITER ||
    create trigger gwhdgl_t2_triggers before insert
    on t2 for each row
    begin
    update gwhdgl.t1 set start_url='Y';
    END
    ||

    ERROR 1442 (HY000): Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

    从mysql.db查看到的权限

    mysql> select * from mysql.db where user='gwhdgl' and host='%'G;
    *************************** 1. row ***************************
    Host: %
    Db: gwhdgl
    User: gwhdgl
    Select_priv: Y
    Insert_priv: Y
    Update_priv: Y
    Delete_priv: Y
    Create_priv: Y
    Drop_priv: Y
    Grant_priv: N
    References_priv: Y
    Index_priv: Y
    Alter_priv: Y
    Create_tmp_table_priv: Y
    Lock_tables_priv: Y
    Create_view_priv: Y
    Show_view_priv: Y
    Create_routine_priv: Y
    Alter_routine_priv: Y
    Execute_priv: Y
    Event_priv: Y
    Trigger_priv: Y
    *************************** 2. row ***************************
    Host: %
    Db: mysql
    User: gwhdgl
    Select_priv: Y
    Insert_priv: N
    Update_priv: N
    Delete_priv: N
    Create_priv: N
    Drop_priv: N
    Grant_priv: N
    References_priv: N
    Index_priv: N
    Alter_priv: N
    Create_tmp_table_priv: N
    Lock_tables_priv: N
    Create_view_priv: N
    Show_view_priv: N
    Create_routine_priv: N
    Alter_routine_priv: N
    Execute_priv: N
    Event_priv: N
    Trigger_priv: N
    2 rows in set (0.00 sec)

    ERROR:
    No query specified

    从mysql.user看到的权限

    mysql> select * from mysql.user where user='gwhdgl' and host='%'G;
    *************************** 1. row ***************************
    Host: %
    User: gwhdgl
    Select_priv: N
    Insert_priv: N
    Update_priv: N
    Delete_priv: N
    Create_priv: N
    Drop_priv: N
    Reload_priv: N
    Shutdown_priv: N
    Process_priv: N
    File_priv: N
    Grant_priv: N
    References_priv: N
    Index_priv: N
    Alter_priv: N
    Show_db_priv: N
    Super_priv: N
    Create_tmp_table_priv: N
    Lock_tables_priv: N
    Execute_priv: N
    Repl_slave_priv: N
    Repl_client_priv: N
    Create_view_priv: N
    Show_view_priv: N
    Create_routine_priv: N
    Alter_routine_priv: N
    Create_user_priv: N
    Event_priv: N
    Trigger_priv: N
    Create_tablespace_priv: N
    ssl_type:
    ssl_cipher:
    x509_issuer:
    x509_subject:
    max_questions: 0
    max_updates: 0
    max_connections: 0
    max_user_connections: 0
    plugin: mysql_native_password
    authentication_string: *23AE809DDACAF96AF0FD78ED04B6A265E05AA257
    password_expired: N
    password_last_changed: 2021-05-10 10:17:28
    password_lifetime: NULL
    account_locked: N
    1 row in set (0.00 sec)

    对当前库的权限具备完全,但是对其他库的权限没有,如果将对其他库的创建触发器权限给到gwhdgl用户,就是将mysql.user表的权限更改过来,会不会正常呢?

    3.授予用户mysql.user表的权限


    User表:存放用户账户信息以及全局级别(所有数据库)权限,决定了来自哪些主机的哪些用户可以访问数据库实例,如果有全局权限则意味着对所有数据库都有此权限
    Db表:存放数据库级别的权限,决定了来自哪些主机的哪些用户可以访问此数据库
    Tables_priv表:存放表级别的权限,决定了来自哪些主机的哪些用户可以访问数据库的这个表
    Columns_priv表:存放列级别的权限,决定了来自哪些主机的哪些用户可以访问数据库表的这个字段
    Procs_priv表:存放存储过程和函数级别的权限

    root用户授权
    mysql> grant create routine,execute,alter routine,trigger on *.* to gwhdgl@'%'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) mysql> mysql> show grants for gwhdgl@'%'; +------------------------------------------------------------------------------+ | Grants for gwhdgl@% | +------------------------------------------------------------------------------+ | GRANT EXECUTE, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON *.* TO 'gwhdgl'@'%' | | GRANT ALL PRIVILEGES ON `gwhdgl`.* TO 'gwhdgl'@'%' | | GRANT SELECT ON `mysql`.* TO 'gwhdgl'@'%' | +------------------------------------------------------------------------------+ 3 rows in set (0.00 sec)

    mysql> select * from mysql.db where user='gwhdgl' and host='%'G;
    *************************** 1. row ***************************
    Host: %
    Db: gwhdgl
    User: gwhdgl
    Select_priv: Y
    Insert_priv: Y
    Update_priv: Y
    Delete_priv: Y
    Create_priv: Y
    Drop_priv: Y
    Grant_priv: N
    References_priv: Y
    Index_priv: Y
    Alter_priv: Y
    Create_tmp_table_priv: Y
    Lock_tables_priv: Y
    Create_view_priv: Y
    Show_view_priv: Y
    Create_routine_priv: Y
    Alter_routine_priv: Y
    Execute_priv: Y
    Event_priv: Y
    Trigger_priv: Y
    *************************** 2. row ***************************
    Host: %
    Db: mysql
    User: gwhdgl
    Select_priv: Y
    Insert_priv: N
    Update_priv: N
    Delete_priv: N
    Create_priv: N
    Drop_priv: N
    Grant_priv: N
    References_priv: N
    Index_priv: N
    Alter_priv: N
    Create_tmp_table_priv: N
    Lock_tables_priv: N
    Create_view_priv: N
    Show_view_priv: N
    Create_routine_priv: N
    Alter_routine_priv: N
    Execute_priv: N
    Event_priv: N
    Trigger_priv: N
    2 rows in set (0.00 sec)

    ERROR:
    No query specified

    mysql> select * from mysql.user where user='gwhdgl' and host='%'G;
    *************************** 1. row ***************************
    Host: %
    User: gwhdgl
    Select_priv: N
    Insert_priv: N
    Update_priv: N
    Delete_priv: N
    Create_priv: N
    Drop_priv: N
    Reload_priv: N
    Shutdown_priv: N
    Process_priv: N
    File_priv: N
    Grant_priv: N
    References_priv: N
    Index_priv: N
    Alter_priv: N
    Show_db_priv: N
    Super_priv: N
    Create_tmp_table_priv: N
    Lock_tables_priv: N
    Execute_priv: Y
    Repl_slave_priv: N
    Repl_client_priv: N
    Create_view_priv: N
    Show_view_priv: N
    Create_routine_priv: Y
    Alter_routine_priv: Y
    Create_user_priv: N
    Event_priv: N
    Trigger_priv: Y
    Create_tablespace_priv: N
    ssl_type:
    ssl_cipher:
    x509_issuer:
    x509_subject:
    max_questions: 0
    max_updates: 0
    max_connections: 0
    max_user_connections: 0
    plugin: mysql_native_password
    authentication_string: *23AE809DDACAF96AF0FD78ED04B6A265E05AA257
    password_expired: N
    password_last_changed: 2021-05-10 10:17:28
    password_lifetime: NULL
    account_locked: N
    1 row in set (0.00 sec)

    ERROR:



    gwhdgl用户看到对trigger的权限

    mysql> DELIMITER ||
    mysql> create trigger gwhdgl_t2_triggers before insert
    -> on t2 for each row
    -> begin
    -> update gwhdgl.t1 set start_url='Y';
    -> END
    -> ||

    ERROR 1419 (HY000): You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

    经过测试,将mysql.db和mysql.user的权限都改回来,仍然没有用

    4.在所有权限都保持的情况下,打开参数log_bin_trust_function_creators

    mysql> set global log_bin_trust_function_creators=1;

    gwhdgl用户

    mysql> set global log_bin_trust_function_creators=1;
    Query OK, 0 rows affected (0.00 sec)

    mysql>
    mysql>
    mysql> show variables like '%log_bin%';
    +---------------------------------+---------------------------------------------+
    | Variable_name | Value |
    +---------------------------------+---------------------------------------------+
    | log_bin | ON |
    | log_bin_basename | /data/mysql/mysql13306/logs/mysql-bin |
    | log_bin_index | /data/mysql/mysql13306/logs/mysql-bin.index |
    | log_bin_trust_function_creators | ON |
    | log_bin_use_v1_row_events | OFF |
    | sql_log_bin | ON |
    +---------------------------------+---------------------------------------------+
    6 rows in set (0.00 sec)

    mysql> DELIMITER ||
    mysql> create trigger gwhdgl_t2_triggers before insert
    -> on t2 for each row
    -> begin
    -> update gwhdgl.t1 set start_url='Y';
    -> END
    -> ||
    Query OK, 0 rows affected (0.00 sec)

    mysql> use gwhdgl;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A

    Database changed
    mysql>
    mysql>
    mysql> drop trigger if exists gwhdgl_t1_triggers;
    Query OK, 0 rows affected, 1 warning (0.00 sec)

    经测试,打开log_bin_trust_function_creators参数可以让用户拥有创建触发器选项,此时用户的权限还是

    | GRANT EXECUTE, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON *.* TO 'gwhdgl'@'%' |
    | GRANT ALL PRIVILEGES ON `gwhdgl`.* TO 'gwhdgl'@'%' |
    | GRANT SELECT ON `mysql`.* TO 'gwhdgl'@'%'

    log_bin_trust_function_creators这个参数到底是什么意思?

    当二进制日志启用后,这个变量就会启用。它控制是否可以信任存储函数创建者,不会创建写入二进制日志引起不安全事件的存储函数。如果设置为0(默认值),用户不得创建或修改存储函数,除非它们具有除CREATE ROUTINE或ALTER ROUTINE特权之外的SUPER权限。 设置为0还强制使用DETERMINISTIC特性或READS SQL DATA或NO SQL特性声明函数的限制。 如果变量设置为1,MySQL不会对创建存储函数实施这些限制

    所以这个参数是跟随log-bin的,控制打开log-bin模式后,开启主从复制模式,对写入二进制日志引起不安全事件的存储函数信任关系的一个限制,所以下面测试将log-bin关闭,mysql用户创建触发器需要什么权限呢?

    打开这个参数就相当于允许主从复制这些函数

    5.关闭log-bin,目前用户拥有的权限是对当前库,和其他库的创建触发器的权限,测试成功

    mysql> DELIMITER ||
    mysql> create trigger gwhdgl_t2_triggers before insert
        -> on t2 for each row
        -> begin
        -> update gwhdgl.t1 set start_url='Y';
        -> END
        -> ||
    Query OK, 0 rows affected (0.00 sec)

    6.授予用户对其他库的触发器权限,目前是对当前库拥有创建触发器的权限,创建成功

    将对其他库的权限收回来
    mysql> revoke create routine,execute,alter routine,trigger on *.* from gwhdgl@'%';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show grants for gwhdgl@'%';
    +----------------------------------------------------+
    | Grants for gwhdgl@%                                |
    +----------------------------------------------------+
    | GRANT USAGE ON *.* TO 'gwhdgl'@'%'                 |
    | GRANT ALL PRIVILEGES ON `gwhdgl`.* TO 'gwhdgl'@'%' |
    | GRANT SELECT ON `mysql`.* TO 'gwhdgl'@'%'          |
    +----------------------------------------------------+
    3 rows in set (0.00 sec)
    
    测试下有没有对trigger的权限?
    mysql> select user();
    +-------------+
    | user()      |
    +-------------+
    | gwhdgl@mha4 |
    +-------------+
    1 row in set (0.00 sec)
    
    mysql> show grants for gwhdgl@'%';
    +----------------------------------------------------+
    | Grants for gwhdgl@%                                |
    +----------------------------------------------------+
    | GRANT USAGE ON *.* TO 'gwhdgl'@'%'                 |
    | GRANT ALL PRIVILEGES ON `gwhdgl`.* TO 'gwhdgl'@'%' |
    | GRANT SELECT ON `mysql`.* TO 'gwhdgl'@'%'          |
    +----------------------------------------------------+
    3 rows in set (0.00 sec)
    
    
    mysql> DELIMITER ||
    mysql> create trigger gwhdgl_t2_triggers before insert
        -> on t2 for each row
        -> begin
        -> update gwhdgl.t1 set start_url='Y';
        -> END
        -> ||
    Query OK, 0 rows affected (0.00 sec)

    结论:

    1.创建触发器其实只需要用户对当前库的create routine,execute,alter routine,trigger相关权限就可以了

    2.如果关闭log_bin_trust_function_creators模式,即便拥有了对当前库和其他库的创建触发器权限,仍然不能够创建,除非拥有SUPER privilege

    3.我使用的都是单机,并不是主从模式,但是也是受log_bin_trust_function_creators这个参数限制的

  • 相关阅读:
    Vue中使用axios时post传参之请求体带参
    MyBatisPlus常用功能之简介
    常用命令一二三之练习题
    常用命令之三
    常用命令之二
    常用命令之一
    阿里云之轻量文件分布式服务器-fastDFS
    js三座大山之三:异步和单线程
    js三座大山之二:作用域和闭包
    run build时内存溢出打包失败的解决办法
  • 原文地址:https://www.cnblogs.com/houzhiheng/p/14751459.html
Copyright © 2011-2022 走看看