MySQL參數log_bin_trust_function_creators介紹

作者:瀟湘隱者

出處:http://www.cnblogs.com/kerrycode/p/7641835.html

 

MySQL的有個參數log_bin_trust_function_creators,官方文檔對這個參數的介紹、解釋如下所示:

log_bin_trust_function_creators

Command-Line Format

--log-bin-trust-function-creators

System Variable

Name

log_bin_trust_function_creators

Variable Scope

Global

Dynamic Variable

Yes

Permitted Values

Type

boolean

Default

FALSE

 

 

This variable applies when binary logging is enabled. It controls whether stored function creators can be trusted not to create stored functions that will cause unsafe events to be written to the binary log. If set to 0 (the default), users are not permitted to create or alter stored functions unless they have the SUPER privilege in addition to the CREATE ROUTINE or ALTER ROUTINE privilege. A setting of 0 also enforces the restriction that a function must be declared with theDETERMINISTIC characteristic, or with the READS SQL DATA or NO SQL characteristic. If the variable is set to 1, MySQL does not enforce these restrictions on stored function creation. This variable also applies to trigger creation. See Section 23.7, “Binary Logging of Stored Programs”.

 

 

簡單介紹一下,當二進制日誌啓用後,這個變量就會啓用。它控制是否可以信任存儲函數創建者,不會創建寫入二進制日誌引起不安全事件的存儲函數。如果設置爲0(默認值),用戶不得創建或修改存儲函數,除非它們具有除CREATE ROUTINE或ALTER ROUTINE特權之外的SUPER權限。 設置爲0還強制使用DETERMINISTIC特性或READS SQL DATA或NO SQL特性聲明函數的限制。 如果變量設置爲1,MySQL不會對創建存儲函數實施這些限制。 此變量也適用於觸發器的創建。 請參見第23.7節“Binary Logging of Stored Programs

 

下面我們測試一下,當開啓二進制日誌後,如果變量log_bin_trust_function_creators爲OFF,那麼創建或修改存儲函數就會報“ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)這樣的錯誤,如下所示: 


mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.00 sec)
 
mysql>  show variables like '%log_bin_trust_function_creators%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF   |
+---------------------------------+-------+
1 row in set (0.00 sec)
 
mysql> 
mysql> DELIMITER //
mysql> CREATE FUNCTION GET_UPPER_NAME(emp_id INT)
    -> RETURNS VARCHAR(12)
    -> BEGIN
    ->   RETURN(SELECT UPPER(NAME) FROM TEST WHERE ID=emp_id);
    -> END
    -> //
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
mysql> 
 

在調用存儲函數時,也會遇到這個錯誤,如下測試所示:

  


mysql> DELIMITER ;
mysql> set global log_bin_trust_function_creators=1;
Query OK, 0 rows affected (0.00 sec)
 
mysql> DELIMITER //
mysql> CREATE FUNCTION GET_UPPER_NAME(emp_id INT)
    -> RETURNS VARCHAR(12)
    -> BEGIN
    ->   RETURN(SELECT UPPER(NAME) FROM TEST WHERE ID=emp_id);
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)
 
mysql> SELECT ID,
    ->        GET_UPPER_NAME(ID)
    -> FROM TEST;
    -> //
+------+--------------------+
| ID   | GET_UPPER_NAME(ID) |
+------+--------------------+
|  100 | KERRY              |
|  101 | JIMMY              |
+------+--------------------+
2 rows in set (0.00 sec)
 
mysql> DELIMITER ;
mysql> set global log_bin_trust_function_creators=0;
Query OK, 0 rows affected (0.00 sec)
 
mysql> SELECT ID,
    ->        GET_UPPER_NAME(ID)
    -> FROM TEST;
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
mysql> 
 

clip_image001

 

 

那麼爲什麼MySQL有這樣的限制呢? 因爲二進制日誌的一個重要功能是用於主從複製,而存儲函數有可能導致主從的數據不一致。所以當開啓二進制日誌後,參數log_bin_trust_function_creators就會生效,限制存儲函數的創建、修改、調用。那麼此時如何解決這個問題呢?官方文檔介紹如下,具體可以參考23.7 Binary Logging of Stored Programs

  


If you do not want to require function creators to have the SUPER privilege (for example, if all users with the CREATE ROUTINE privilege on your system are experienced application developers), set the global log_bin_trust_function_creators system variable to 1. You can also set this variable by using the --log-bin-trust-function-creators=1 option when starting the server. If binary logging is not enabled, log_bin_trust_function_creators does not apply. SUPER is not required for function creation unless, as described previously, the DEFINER value in the function definition requires it.

 

If a function that performs updates is nondeterministic, it is not repeatable. This can have two undesirable effects:

        

·         It will make a slave different from the master.

  

·         Restored data will be different from the original data.

To deal with these problems, MySQL enforces the following requirement: On a master server, creation and alteration of a function is refused unless you declare the function to be deterministic or to not modify data. Two sets of function characteristics apply here:

      

·         The DETERMINISTIC and NOT DETERMINISTIC characteristics indicate whether a function always produces the same result for given inputs. The default is NOT DETERMINISTIC if neither characteristic is given. To declare that a function is deterministic, you must specify DETERMINISTIC explicitly.

     

·         The CONTAINS SQL, NO SQL, READS SQL DATA, and MODIFIES SQL DATA characteristics provide information about whether the function reads or writes data. Either NO SQL or READS SQL DATA indicates that a function does not change data, but you must specify one of these explicitly because the default is CONTAINS SQL if no characteristic is given.

·          

 

1: 如果數據庫沒有使用主從複製,那麼就可以將參數log_bin_trust_function_creators設置爲1。

 

mysql> set global log_bin_trust_function_creators=1;

 

這個動態設置的方式會在服務重啓後失效,所以我們還必須在my.cnf中設置,加上log_bin_trust_function_creators=1,這樣就會永久生效。

 

 

 

2:明確指明函數的類型,如果我們開啓了二進制日誌, 那麼我們就必須爲我們的function指定一個參數。其中下面幾種參數類型裏面,只有 DETERMINISTIC, NO SQL 和 READS SQL DATA 被支持。這樣一來相當於明確的告知MySQL服務器這個函數不會修改數據。

 

1 DETERMINISTIC 不確定的

2 NO SQL 沒有SQl語句,當然也不會修改數據

3 READS SQL DATA 只是讀取數據,當然也不會修改數據

4 MODIFIES SQL DATA 要修改數據

5 CONTAINS SQL 包含了SQL語句 


mysql> show variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF   |
+---------------------------------+-------+
1 row in set (0.00 sec)
 
mysql> DROP FUNCTION GET_UPPER_NAME;
Query OK, 0 rows affected (0.00 sec)
 
mysql> DELIMITER //
mysql> CREATE FUNCTION GET_UPPER_NAME(emp_id INT)
    -> RETURNS VARCHAR(12)
    -> READS SQL DATA
    -> BEGIN
    ->   RETURN(SELECT UPPER(NAME) FROM TEST WHERE ID=emp_id);
    -> END
    -> //
Query OK, 0 rows affected (0.01 sec)
 
mysql> DELIMITER ;
mysql> SELECT ID,
    ->        GET_UPPER_NAME(ID)
    -> FROM TEST;
+------+--------------------+
| ID   | GET_UPPER_NAME(ID) |
+------+--------------------+
|  100 | KERRY              |
|  101 | JIMMY              |
+------+--------------------+
2 rows in set (0.00 sec)
 

clip_image002

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章