MySQL参数log_bin_trust_function_creators介绍
2017-10-09 17:02
411 查看
MySQL的有个参数log_bin_trust_function_creators,官方文档对这个参数的介绍、解释如下所示:
log_bin_trust_function_creators
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有这样的限制呢?因为二进制日志的一个重要功能是用于主从复制,而存储函数有可能导致主从的数据不一致。所以当开启二进制日志后,参数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语句
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 |
简单介绍一下,当二进制日志启用后,这个变量就会启用。它控制是否可以信任存储函数创建者,不会创建写入二进制日志引起不安全事件的存储函数。如果设置为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就会生效,限制存储函数的创建、修改、调用。那么此时如何解决这个问题呢?官方文档介绍如下,具体可以参考
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)
相关文章推荐
- SQL创建函数不成功的问题-log_bin_trust_function_creators参数研究
- mysql 创建函数set global log_bin_trust_function_creators=TRUE;
- mysql 创建函数set global log_bin_trust_function_creators=TRUE;
- 函数相关参数 log_bin_trust_function_creators
- mysql 创建函数set global log_bin_trust_function_creators=TRUE;
- mysql----------mysql5.7.11导入sql文件的时候报错log_bin_trust_function_creators
- MySql DETERMINISTIC log_bin_trust_function_creators 自定义函数执行时报错
- Amazon RDS MySQL数据库还原时 log_bin_trust_function_creators 错误解决办法
- MySQL创建Function时报的1418错误代号解决办法 log_bin_trust_function_creators
- log_bin_trust_function_creators
- log_bin_trust_function_creators错误!
- log_bin_trust_function_creators变量解释
- [MySQL] you *might* want to use the less safe log_bin_trust_function_creators variable
- mysql 关于log_bin_trust_function_creators变量
- log_bin_trust_function_creators和max_allowed_packet
- log_bin_trust_function_creators变量解释
- you *might* want to use the less safe log_bin_trust_function_creators variable
- 如何在开启了log-bin的MySQL Server中创建FUNCTION
- log_bin_trust_function_creators & max_allowed_packet
- MySQL 参数浅析之 sql_log_bin