您的位置:首页 > 数据库 > MySQL

MySQL参数log_bin_trust_function_creators介绍

2017-10-09 17:02 411 查看
MySQL的有个参数log_bin_trust_function_creators,官方文档对这个参数的介绍、解释如下所示:

log_bin_trust_function_creators

Command-LineFormat

--log-bin-trust-function-creators

SystemVariable

Name

log_bin_trust_function_creators

VariableScope

Global

DynamicVariable

Yes

PermittedValues

Type

boolean

Default

FALSE

Thisvariableapplieswhenbinaryloggingisenabled.Itcontrolswhetherstoredfunctioncreatorscanbetrustednottocreatestoredfunctionsthatwillcauseunsafeeventstobewrittentothebinarylog.Ifsetto0(thedefault),usersarenotpermittedtocreateoralterstoredfunctionsunlesstheyhavetheSUPERprivilegeinadditiontotheCREATEROUTINEorALTERROUTINEprivilege.Asettingof0alsoenforcestherestrictionthatafunctionmustbedeclaredwiththeDETERMINISTICcharacteristic,orwiththeREADSSQLDATAorNOSQLcharacteristic.Ifthevariableissetto1,MySQLdoesnotenforcetheserestrictionsonstoredfunctioncreation.Thisvariablealsoappliestotriggercreation.SeeSection23.7,“BinaryLoggingofStoredPrograms”.

简单介绍一下,当二进制日志启用后,这个变量就会启用。它控制是否可以信任存储函数创建者,不会创建写入二进制日志引起不安全事件的存储函数。如果设置为0(默认值),用户不得创建或修改存储函数,除非它们具有除CREATEROUTINE或ALTERROUTINE特权之外的SUPER权限。设置为0还强制使用DETERMINISTIC特性或READSSQLDATA或NOSQL特性声明函数的限制。如果变量设置为1,MySQL不会对创建存储函数实施这些限制。此变量也适用于触发器的创建。请参见第23.7节“BinaryLoggingofStoredPrograms”。

下面我们测试一下,当开启二进制日志后,如果变量log_bin_trust_function_creators为OFF,那么创建或修改存储函数就会报“ERROR1418(HY000):ThisfunctionhasnoneofDETERMINISTIC,NOSQL,orREADSSQLDATAinitsdeclarationandbinaryloggingisenabled(you*might*wanttousethelesssafelog_bin_trust_function_creatorsvariable)”这样的错误,如下所示:

mysql>showvariableslike'log_bin';
+---------------+-------+
|Variable_name|Value|
+---------------+-------+
|log_bin|ON|
+---------------+-------+
1rowinset(0.00sec)
mysql>showvariableslike'%log_bin_trust_function_creators%';
+---------------------------------+-------+
|Variable_name|Value|
+---------------------------------+-------+
|log_bin_trust_function_creators|OFF|
+---------------------------------+-------+
1rowinset(0.00sec)
mysql>
mysql>DELIMITER//
mysql>CREATEFUNCTIONGET_UPPER_NAME(emp_idINT)
->RETURNSVARCHAR(12)
->BEGIN
->RETURN(SELECTUPPER(NAME)FROMTESTWHEREID=emp_id);
->END
->//
ERROR1418(HY000):ThisfunctionhasnoneofDETERMINISTIC,NOSQL,orREADSSQLDATAinitsdeclarationandbinaryloggingisenabled(you*might*wanttousethelesssafelog_bin_trust_function_creatorsvariable)
mysql>


在调用存储函数时,也会遇到这个错误,如下测试所示:

mysql>DELIMITER;
mysql>setgloballog_bin_trust_function_creators=1;
QueryOK,0rowsaffected(0.00sec)
mysql>DELIMITER//
mysql>CREATEFUNCTIONGET_UPPER_NAME(emp_idINT)
->RETURNSVARCHAR(12)
->BEGIN
->RETURN(SELECTUPPER(NAME)FROMTESTWHEREID=emp_id);
->END
->//
QueryOK,0rowsaffected(0.00sec)
mysql>SELECTID,
->GET_UPPER_NAME(ID)
->FROMTEST;
->//
+------+--------------------+
|ID|GET_UPPER_NAME(ID)|
+------+--------------------+
|100|KERRY|
|101|JIMMY|
+------+--------------------+
2rowsinset(0.00sec)
mysql>DELIMITER;
mysql>setgloballog_bin_trust_function_creators=0;
QueryOK,0rowsaffected(0.00sec)
mysql>SELECTID,
->GET_UPPER_NAME(ID)
->FROMTEST;
ERROR1418(HY000):ThisfunctionhasnoneofDETERMINISTIC,NOSQL,orREADSSQLDATAinitsdeclarationandbinaryloggingisenabled(you*might*wanttousethelesssafelog_bin_trust_function_creatorsvariable)
mysql>






那么为什么MySQL有这样的限制呢?因为二进制日志的一个重要功能是用于主从复制,而存储函数有可能导致主从的数据不一致。所以当开启二进制日志后,参数log_bin_trust_function_creators就会生效,限制存储函数的创建、修改、调用。那么此时如何解决这个问题呢?官方文档介绍如下,具体可以参考23.7BinaryLoggingofStoredPrograms

IfyoudonotwanttorequirefunctioncreatorstohavetheSUPERprivilege(forexample,ifalluserswiththeCREATEROUTINEprivilegeonyoursystemareexperiencedapplicationdevelopers),setthegloballog_bin_trust_function_creatorssystemvariableto1.Youcanalsosetthisvariablebyusingthe--log-bin-trust-function-creators=1optionwhenstartingtheserver.Ifbinaryloggingisnotenabled,log_bin_trust_function_creatorsdoesnotapply.SUPERisnotrequiredforfunctioncreationunless,asdescribedpreviously,theDEFINERvalueinthefunctiondefinitionrequiresit.

Ifafunctionthatperformsupdatesisnondeterministic,itisnotrepeatable.Thiscanhavetwoundesirableeffects:

·Itwillmakeaslavedifferentfromthemaster.

·Restoreddatawillbedifferentfromtheoriginaldata.

Todealwiththeseproblems,MySQLenforcesthefollowingrequirement:Onamasterserver,creationandalterationofafunctionisrefusedunlessyoudeclarethefunctiontobedeterministicortonotmodifydata.Twosetsoffunctioncharacteristicsapplyhere:

·TheDETERMINISTICandNOTDETERMINISTICcharacteristicsindicatewhetherafunctionalwaysproducesthesameresultforgiveninputs.ThedefaultisNOTDETERMINISTICifneithercharacteristicisgiven.Todeclarethatafunctionisdeterministic,youmustspecifyDETERMINISTICexplicitly.

·TheCONTAINSSQL,NOSQL,READSSQLDATA,andMODIFIESSQLDATAcharacteristicsprovideinformationaboutwhetherthefunctionreadsorwritesdata.EitherNOSQLorREADSSQLDATAindicatesthatafunctiondoesnotchangedata,butyoumustspecifyoneoftheseexplicitlybecausethedefaultisCONTAINSSQLifnocharacteristicisgiven.

·

1:如果数据库没有使用主从复制,那么就可以将参数log_bin_trust_function_creators设置为1。

mysql>setgloballog_bin_trust_function_creators=1;

这个动态设置的方式会在服务重启后失效,所以我们还必须在my.cnf中设置,加上log_bin_trust_function_creators=1,这样就会永久生效。

2:明确指明函数的类型,如果我们开启了二进制日志,那么我们就必须为我们的function指定一个参数。其中下面几种参数类型里面,只有DETERMINISTIC,NOSQL和READSSQLDATA被支持。这样一来相当于明确的告知MySQL服务器这个函数不会修改数据。

1DETERMINISTIC不确定的

2NOSQL没有SQl语句,当然也不会修改数据

3READSSQLDATA只是读取数据,当然也不会修改数据

4MODIFIESSQLDATA要修改数据

5CONTAINSSQL包含了SQL语句

mysql>showvariableslike'log_bin_trust_function_creators';
+---------------------------------+-------+
|Variable_name|Value|
+---------------------------------+-------+
|log_bin_trust_function_creators|OFF|
+---------------------------------+-------+
1rowinset(0.00sec)
mysql>DROPFUNCTIONGET_UPPER_NAME;
QueryOK,0rowsaffected(0.00sec)
mysql>DELIMITER//
mysql>CREATEFUNCTIONGET_UPPER_NAME(emp_idINT)
->RETURNSVARCHAR(12)
->READSSQLDATA
->BEGIN
->RETURN(SELECTUPPER(NAME)FROMTESTWHEREID=emp_id);
->END
->//
QueryOK,0rowsaffected(0.01sec)
mysql>DELIMITER;
mysql>SELECTID,
->GET_UPPER_NAME(ID)
->FROMTEST;
+------+--------------------+
|ID|GET_UPPER_NAME(ID)|
+------+--------------------+
|100|KERRY|
|101|JIMMY|
+------+--------------------+
2rowsinset(0.00sec)




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: