192

While importing the database in mysql, I have got following error:

1418 (HY000) at line 10185: 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)

I don't know which things i need to change. Can any one help me how to resolve this?

Donal
  • 31,121
  • 10
  • 63
  • 72
ASR
  • 3,289
  • 3
  • 37
  • 65

8 Answers8

424

There are two ways to fix this:

  1. Execute the following in the MySQL console:

    SET GLOBAL log_bin_trust_function_creators = 1;

  2. Add the following to the mysql.ini configuration file:

    log_bin_trust_function_creators = 1;

The setting relaxes the checking for non-deterministic functions. Non-deterministic functions are functions that modify data (i.e. have update, insert or delete statement(s)). For more info, see here.

Please note, if binary logging is NOT enabled, this setting does not apply.

Binary Logging of Stored Programs

If binary logging is not enabled, log_bin_trust_function_creators does not apply.

log_bin_trust_function_creators

This variable applies when binary logging is enabled.

The best approach is a better understanding and use of deterministic declarations for stored functions. These declarations are used by MySQL to optimize the replication and it is a good thing to choose them carefully to have a healthy replication.

DETERMINISTIC A routine is considered “deterministic” if it always produces the same result for the same input parameters and NOT DETERMINISTIC otherwise. This is mostly used with string or math processing, but not limited to that.

NOT DETERMINISTIC Opposite of "DETERMINISTIC". "If neither DETERMINISTIC nor NOT DETERMINISTIC is given in the routine definition, the default is NOT DETERMINISTIC. To declare that a function is deterministic, you must specify DETERMINISTIC explicitly.". So it seems that if no statement is made, MySQl will treat the function as "NOT DETERMINISTIC". This statement from manual is in contradiction with other statement from another area of manual which tells that: " When you create a stored function, you must declare either that it is deterministic or that it does not modify data. Otherwise, it may be unsafe for data recovery or replication. By default, for a CREATE FUNCTION statement to be accepted, at least one of DETERMINISTIC, NO SQL, or READS SQL DATA must be specified explicitly. Otherwise an error occurs"

I personally got error in MySQL 5.5 if there is no declaration, so i always put at least one declaration of "DETERMINISTIC", "NOT DETERMINISTIC", "NO SQL" or "READS SQL DATA" regardless other declarations i may have.

READS SQL DATA This explicitly tells to MySQL that the function will ONLY read data from databases, thus, it does not contain instructions that modify data, but it contains SQL instructions that read data (e.q. SELECT).

MODIFIES SQL DATA This indicates that the routine contains statements that may write data (for example, it contain UPDATE, INSERT, DELETE or ALTER instructions).

NO SQL This indicates that the routine contains no SQL statements.

CONTAINS SQL This indicates that the routine contains SQL instructions, but does not contain statements that read or write data. This is the default if none of these characteristics is given explicitly. Examples of such statements are SELECT NOW(), SELECT 10+@b, SET @x = 1 or DO RELEASE_LOCK('abc'), which execute but neither read nor write data.

Note that there are MySQL functions that are not deterministic safe, such as: NOW(), UUID(), etc, which are likely to produce different results on different machines, so a user function that contains such instructions must be declared as NOT DETERMINISTIC. Also, a function that reads data from an unreplicated schema is clearly NONDETERMINISTIC. *

Assessment of the nature of a routine is based on the “honesty” of the creator: MySQL does not check that a routine declared DETERMINISTIC is free of statements that produce nondeterministic results. However, misdeclaring a routine might affect results or affect performance. Declaring a nondeterministic routine as DETERMINISTIC might lead to unexpected results by causing the optimizer to make incorrect execution plan choices. Declaring a deterministic routine as NONDETERMINISTIC might diminish performance by causing available optimizations not to be used.

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Donal
  • 31,121
  • 10
  • 63
  • 72
  • can u explain me what happened in background ? – ASR Sep 24 '14 at 11:19
  • 2
    I suspect the database has a function that modifies data (has an update, insert or delete statement in it). For more info, see here: http://dev.mysql.com/doc/refman/5.0/en/stored-programs-logging.html – Donal Sep 24 '14 at 11:31
  • 1
    You should always take backups – Donal Sep 24 '14 at 12:01
  • 1
    it need super privileges ! – fpilee Feb 22 '17 at 00:27
  • tried this but still got the non deterministic problem, any other suggestion? thanks – Edwin Bermejo Jul 23 '18 at 03:15
  • Refer to the answer written by Sunny S.M or mine – Park JongBum Oct 11 '18 at 05:34
  • You suggest 2 ways, but there are 3, no? The third is using the declarations you pointed latter. I used inserted the DETERMINISTIC declaration and it worked fine. Maybe you could write it more explicitly. – jpenna Oct 23 '18 at 03:22
  • 1
    @EdwinBermejo Didn't work for me with the `;` in the mysql.ini file. Removed it - and that worked. – Nik Sep 23 '20 at 09:53
  • I think that the current time is inserted in the binlog, thereby making NOW(), etc, produce the same value on the Replica as the Primary. (Contrast: SYSDATE()`) – Rick James Apr 27 '22 at 21:49
69
  • When you create a stored function, you must declare either that it is deterministic or that it does not modify data. Otherwise, it may be unsafe for data recovery or replication.

  • By default, for a CREATE FUNCTION statement to be accepted, at least one of DETERMINISTIC, NO SQL, or READS SQL DATA must be specified explicitly. Otherwise an error occurs:

To fix this issue add following lines After Return and Before Begin statement:

READS SQL DATA
DETERMINISTIC

For Example :

CREATE FUNCTION f2()
RETURNS CHAR(36) CHARACTER SET utf8
/*ADD HERE */
READS SQL DATA
DETERMINISTIC
BEGIN

For more detail about this issue please read Here

Sunny S.M
  • 5,768
  • 1
  • 38
  • 38
  • This works because the setting `READS SQL DATA` is the least restrictive of the three. If your function falls into the `NO SQL` or the `DETERMINISTIC` category, you may improve performance by modifying your functions. On the other hand, the setting `READS SQL DATA` is also the least error prone. So if you incorrectly use `NO SQL` or `DETERMINISTIC` you may get incorrect results. – Jonathan Dec 04 '15 at 21:57
  • @SunnyS.M,Awesome explanation as like READS SQL DATA DETERMINISTIC.To fix this issue add following lines After Return and Before Begin statement: – Md Haidar Ali Khan Nov 28 '18 at 08:27
  • Note that the MySQL manual states *"Assessment of the nature of a function is based on the honesty of the creator. MySQL does not check that a function declared DETERMINISTIC is free of statements that produce nondeterministic results"* – BadHorsie Oct 22 '20 at 16:02
  • I just wondering why I can't use `modifies sql data not deterministic` to make it run when I have a non-deterministic function? – MrZ Nov 01 '21 at 12:35
23

i use this command on ubuntu:

mysql -u root -p

and enter mysql server error and execute this command in mysql:

SET GLOBAL log_bin_trust_function_creators = 1;
amiirhoseinseif
  • 231
  • 2
  • 2
16

When your function is deterministic, you are safe to declare it to be deterministic. The location of "DETERMINISTIC" keyword is as follows.

enter image description here

Park JongBum
  • 1,245
  • 1
  • 16
  • 27
7

following Donald's comment:

This variable applies when binary logging is enabled.

All I had to do was:

  1. disabled log_bin in my.cnf (#log_bin)
  2. restart mysql
  3. import DB
  4. enable log_bin
  5. restart mysql

That step out that import problem.

(Then I'll review the programmer's code to suggest an improvement)

Mayra Navarro
  • 124
  • 2
  • 9
3

On Windows 10,

I just solved this issue by doing the following.

  1. Goto my.ini and add these 2 lines under [mysqld]

    skip-log-bin
    log_bin_trust_function_creators = 1
    
  2. restart MySQL service

Daniel Puiu
  • 962
  • 6
  • 21
  • 29
Preetham
  • 397
  • 1
  • 10
  • after doing this, I got error on slave - `Got fatal error 1236 from master when reading data from binary log: 'Binary log is not open'` – Ramratan Gupta May 24 '18 at 06:28
1

MySQL auto read the configuration from conf.d and mysql.conf.d directory. So create custom.cnf in the directory /etc/mysql/conf.d/ and add the following configs.

[mysqld]
log_bin_trust_function_creators=1

The root user permission is required to create and save the file. Then restart the MySQL server.

Madan Sapkota
  • 25,047
  • 11
  • 113
  • 117
0

Try setting the definer for the function!

So instead of

CREATE FUNCTION get_pet_owner

you will write something akin to

CREATE DEFINER=procadmin@% FUNCTION get_pet_owner

which ought to work if the user prodacmin has rights to create functions/procedures.

In my case the function worked when generated through MySQL Workbench but did not work when run directly as an SQL script. Making the changes above fixed the problem.

DevKingKev
  • 51
  • 1
  • 3