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 ' |
| GRANT SELECT ON `mysql`.* TO '          |
+----------------------------------------------------+
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 0.01 sec)

mysql> 
mysql>  t2;
+------+--------+-----------+
| id   | name   | start_url |
+------+--------+-----------+
|    6 | 亏刘   | NULL      |
+------+--------+-----------+
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 ( flush privileges; Query OK,1)"> mysql> show grants ; +------------------------------------------------------------------------------+ | Grants for gwhdgl@% | +------------------------------------------------------------------------------+ | GRANT EXECUTE,CREATE ROUTINE,ALTER ROUTINE,TRIGGER ON *.* TO ' | | GRANT ALL PRIVILEGES ON `gwhdgl`.* TO ' | | GRANT SELECT ON `mysql`.* TO ' | +------------------------------------------------------------------------------+ 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,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,1)">0.00 sec)

 

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

将对其他库的权限收回来
mysql> revoke create routine,trigger on *.* from gwhdgl@ sec)

mysql> show grants  sec)

测试下有没有对trigger的权限?
mysql> select user();
+-------------+
| user()      |
+-------------+
| gwhdgl@mha4 |
+-------------+
1 row  sec)


mysql> DELIMITER ||0.00 sec)

 

 

结论:

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

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

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

 

原文地址:https://www.cnblogs.com/houzhiheng

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


navicat查看某个表的所有字段的详细信息 navicat设计表只能一次查看一个字段的备注信息,那怎么才能做到一次性查询表的信息呢?SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,COLUMN_KEY FROM information_schema.CO
文章浏览阅读4.3k次。转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52768613前言:数据库每天的数据不断增多,自动删除机制总体风险太大,想保留更多历史性的数据供查询,于是从小的hbase换到大的hbase上,势在必行。今天记录下这次数据仓库迁移。看下Agenda:彻底卸载MySQL安装MySQL_linux服务器进行数据迁移
文章浏览阅读488次。恢复步骤概要备份frm、ibd文件如果mysql版本发生变化,安装回原本的mysql版本创建和原本库名一致新库,字符集都要保持一样通过frm获取到原先的表结构,通过的得到的表结构创建一个和原先结构一样的空表。使用“ALTER TABLE DISCARD TABLESPACE;”命令卸载掉表空间将原先的ibd拷贝到mysql的仓库下添加用户权限 “chown . .ibd”,如果是操作和mysql的使用权限一致可以跳过通过“ALTER TABLE IMPORT TABLESPACE;”命令恢_alter table discard tablespace
文章浏览阅读225次。当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化:单表优化除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的。而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量:字段尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNEDVARCHAR的长度只分配_开发项目 浏览记录表 过大怎么办
文章浏览阅读1.5k次。Mysql创建、删除用户MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束):1.新建用户登录MYSQL:@>mysql -u root -p@>密码创建用户:mysql> insert into mysql.user(Host,User,Password) values("localhost_删除mysql用户组
MySQL是一种开源的关系型数据库管理系统,被广泛应用于各类应用程序的开发中。对于MySQL中的字段,我们需要进行数据类型以及默认值的设置,这对于数据的存储和使用至关重要。其中,有一个非常重要的概念就是MySQL字段默认字符串。 CREATE TABLE `my_...
MySQL是一个流行的开源关系型数据库管理系统,广泛应用于Web应用程序开发、数据存储和管理。在使用MySQL时,正确设置字符集非常重要,以确保数据的正确性和可靠性。 在MySQL中,字符集表示为一系列字符和字母的集合。MySQL支持多种字符集,包括ASCII、UTF...
MySQL存储函数 n以内偶数 MySQL存储函数能够帮助用户简化操作,提高效率,常常被用于计算和处理数据。下面我们就来了解一下如何使用MySQL存储函数计算n以内的偶数。 定义存储函数 首先,我们需要定义一个MySQL存储函数,以计算n以内的偶数。下...
MySQL是一个流行的关系型数据库管理系统,基于客户机-服务器模式,可在各种操作系统上运行。 MySQL支持多种字符集,不同的字符集包括不同的字符,如字母、数字、符号等,并提供不同的排序规则,以满足不同语言环境的需求。 //查看MySQL支持的字符集与校对规...
在MySQL数据库中,我们有时需要对特定的字符串进行截取并进行分组统计。这种操作对于数据分析和报表制作有着重要的应用。下面我们将讲解一些基本的字符串截取和分组统计的方法。 首先,我们可以使用substring函数对字段中的字符串进行截取。假设我们有一张表stude...
MySQL提供了多种字符串的查找函数。下面我们就一一介绍。 1. LIKE函数 SELECT * FROM mytable WHERE mycolumn LIKE 'apple%'; 其中"apple%"表示以apple开头的字符串,%表示任意多个字符...
MySQL 是一种关系型数据库管理系统,广泛应用于各种不同规模和类型的应用程序中。在 MySQL 中,处理字符串数据是很常见的任务。有时候,我们需要在字符串的开头添加一定数量的 0 ,以达到一定的位数。比如,我们可能需要将一个数字转换为 4 位或 5 位的字符串,不足的...
MySQL是一种流行的关系型数据库管理系统,支持多种数据类型。以下是MySQL所支持的数据类型: 1. 数值型数据类型: - TINYINT 保存-128到127范围内的整数 - SMALLINT 保存-32768到32767范围内的整数 - MEDIU...
MySQL中存储Emoji表情字段类型 在现代互联网生态中,表情符号已经成为人们展示情感和思想的重要方式之一,因此将表情符号存储到数据库中是一个经常出现的问题。MySQL作为最流行的开源关系型数据库管理系统之一,也需要能够存储和管理这些表情符号的字段类型。 UT...
MySQL是一种关系型数据库管理系统。在MySQL数据库中,有多种不同的数据类型。而其中,最常见的数据类型之一就是字符串类型。在MySQL中,字符串类型的数据通常会被存储为TEXT或VARCHAR类型。 首先,让我们来看一下VARCHAR类型。VARCHAR是My...
MySQL字符串取整知识详解 MySQL是一种开源的关系型数据库管理系统,广泛应用于各个领域。在使用MySQL过程当中,我们经常需要对数据进行取整操作。本文将介绍如何使用MySQL字符串取整来处理数据取整问题。 什么是MySQL字符串取整? MySQL...
使用MySQL进行数据存储是现代应用程序开发中一个非常重要的组成部分。在MySQL中,数据存储的一个重要特点就是字符长度无限制。在下文中,我们将会详细探讨MySQL字符长度无限制的特征和优势。 什么是MySQL字符长度无限制? MySQL字符长度无限制是指在...
在MySQL中,常常会涉及到字符串和数字之间的比较。然而它们有着不同的排序规则,因此需要注意对它们进行正确的比较。 首先我们来看一下数字比较。 SELECT 1 < 2; -- 返回 1 SELECT 2 > 1; -- 返回 1 SELEC...
MySQL是一种流行的关系型数据库管理系统,可以处理各种不同类型的数据。其中字符串是MySQL中最重要的数据类型之一,因为它可以存储各种不同的数据,例如邮件地址、文本信息、数字等等。在MySQL中,有时候我们需要将字符串按照某个符合进行分隔,例如将一条包含多个数字的字符...
在MySQL中,我们经常需要将字符串与变量拼接起来,以便满足数据操作的需求。可以使用CONCAT函数来进行字符串与变量的拼接,下面是一个使用CONCAT函数的例子: SELECT CONCAT('Hello', ' ', 'world'); 这个例子...