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這個參數限制的

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM