DETERMINISTIC, NO SQL ou READS SQL DATA dans sa déclaration et la journalisation binaire est activée

107

Lors de l'importation de la base de données dans mysql, j'ai l'erreur suivante:

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)

Je ne sais pas quelles choses je dois changer. Quelqu'un peut-il m'aider à résoudre ce problème?

ASR
la source

Réponses:

237

Il existe deux façons de résoudre ce problème:

  1. Exécutez ce qui suit dans la console MySQL:

    SET GLOBAL log_bin_trust_function_creators = 1;

  2. Ajoutez ce qui suit au fichier de configuration mysql.ini:

    log_bin_trust_function_creators = 1;

Le paramètre assouplit la vérification des fonctions non déterministes. Les fonctions non déterministes sont des fonctions qui modifient les données (c'est-à-dire qui ont des instructions de mise à jour, d'insertion ou de suppression). Pour plus d'informations, voir ici .

Veuillez noter que si la journalisation binaire n'est PAS activée, ce paramètre ne s'applique pas.

Journalisation binaire des programmes stockés

Si la journalisation binaire n'est pas activée, log_bin_trust_function_creators ne s'applique pas.

log_bin_trust_function_creators

Cette variable s'applique lorsque la journalisation binaire est activée.

La meilleure approche est une meilleure compréhension et une meilleure utilisation des déclarations déterministes pour les fonctions stockées. Ces déclarations sont utilisées par MySQL pour optimiser la réplication et c'est une bonne chose de les choisir avec soin pour avoir une réplication saine.

DETERMINISTIC Une routine est considérée comme «déterministe» si elle produit toujours le même résultat pour les mêmes paramètres d'entrée et NON DETERMINISTIC dans le cas contraire. Ceci est principalement utilisé avec le traitement de chaînes ou mathématiques, mais sans s'y limiter.

NON DÉTERMINISTE À l' opposé de "DETERMINISTIQUE". " Si ni DETERMINISTIC ni NOT DETERMINISTIC n'est indiqué dans la définition de routine, la valeur par défaut est NOT DETERMINISTIC. Pour déclarer qu'une fonction est déterministe, vous devez spécifier DETERMINISTIC explicitement. ". Il semble donc que si aucune déclaration n'est faite, MySQl traitera la fonction comme "NON DÉTERMINISTE". Cette déclaration du manuel est en contradiction avec une autre déclaration d'un autre domaine du manuel qui dit que: "Lorsque vous créez une fonction stockée, vous devez déclarer qu'elle est déterministe ou qu'elle ne modifie pas les données. Sinon, cela peut être dangereux pour la récupération ou la réplication de données. Par défaut, pour qu'une instruction CREATE FUNCTION soit acceptée, au moins une des données DETERMINISTIC, NO SQL ou READS SQL DATA doit être spécifiée explicitement. Sinon, une erreur se produit "

J'ai personnellement une erreur dans MySQL 5.5 s'il n'y a pas de déclaration, donc je mets toujours au moins une déclaration de "DETERMINISTIC", "NOT DETERMINISTIC", "NO SQL" ou "READS SQL DATA" quelles que soient les autres déclarations que je peux avoir.

LISE LES DONNÉES SQL Ceci indique explicitement à MySQL que la fonction lira UNIQUEMENT les données des bases de données, ainsi, elle ne contient pas d'instructions qui modifient les données, mais elle contient des instructions SQL qui lisent les données (eq SELECT).

MODIFIES SQL DATA Ceci indique que la routine contient des instructions qui peuvent écrire des données (par exemple, elle contient des instructions UPDATE, INSERT, DELETE ou ALTER).

NO SQL Ceci indique que la routine ne contient aucune instruction SQL.

CONTAINS SQL Cela indique que la routine contient des instructions SQL, mais ne contient pas d'instructions qui lisent ou écrivent des données. C'est la valeur par défaut si aucune de ces caractéristiques n'est donnée explicitement. Des exemples de telles instructions sont SELECT NOW (), SELECT 10 + @ b, SET @x = 1 ou DO RELEASE_LOCK ('abc'), qui exécutent mais ne lisent ni n'écrivent des données.

Notez qu'il existe des fonctions MySQL qui ne sont pas sûres déterministes, telles que: NOW (), UUID (), etc., qui sont susceptibles de produire des résultats différents sur différentes machines, donc une fonction utilisateur contenant de telles instructions doit être déclarée comme NON DÉTERMINISTE . En outre, une fonction qui lit des données à partir d'un schéma non répliqué est clairement NONDETERMINISTIQUE. *

L'évaluation de la nature d'une routine est basée sur «l'honnêteté» du créateur: MySQL ne vérifie pas qu'une routine déclarée DETERMINISTIC est exempte d'énoncés qui produisent des résultats non déterministes. Cependant, une mauvaise déclaration d'une routine peut affecter les résultats ou les performances. La déclaration d'une routine non déterministe comme DETERMINISTIC peut conduire à des résultats inattendus en obligeant l'optimiseur à faire des choix de plan d'exécution incorrects. La déclaration d'une routine déterministe comme NONDETERMINISTIC peut diminuer les performances en empêchant l'utilisation des optimisations disponibles.

Donal
la source
pouvez-vous m'expliquer ce qui s'est passé en arrière-plan?
ASR
2
Je soupçonne que la base de données a une fonction qui modifie les données (contient une instruction de mise à jour, d'insertion ou de suppression). Pour plus d'informations, voir ici: dev.mysql.com/doc/refman/5.0/en/stored-programs-logging.html
Donal
1
Vous devriez toujours faire des sauvegardes
Donal
il a besoin de super privilèges!
Felipe Morales
essayé ceci mais toujours obtenu le problème non déterministe, une autre suggestion? merci
Edwin Bermejo
40
  • Lorsque vous créez une fonction stockée, vous devez déclarer qu'elle est déterministe ou qu'elle ne modifie pas les données. Sinon, cela peut être dangereux pour la récupération ou la réplication de données.

  • Par défaut, pour qu'une instruction CREATE FUNCTION soit acceptée, au moins une des données DETERMINISTIC, NO SQL ou READS SQL DATA doit être spécifiée explicitement. Sinon, une erreur se produit:

Pour résoudre ce problème, ajoutez les lignes suivantes après retour et avant de commencer:

READS SQL DATA
DETERMINISTIC

Par exemple :

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

Pour plus de détails sur ce problème, veuillez lire ici

Sunny SM
la source
Cela fonctionne car le paramètre READS SQL DATAest le moins restrictif des trois. Si votre fonction appartient à la catégorie NO SQLou DETERMINISTIC, vous pouvez améliorer les performances en modifiant vos fonctions. D'autre part, le paramètre READS SQL DATAest également le moins sujet aux erreurs. Donc, si vous utilisez incorrectement NO SQLou DETERMINISTICvous pouvez obtenir des résultats incorrects.
Jonathan
@ SunnyS.M, Explication géniale comme READS SQL DATA DETERMINISTIC.Pour résoudre ce problème, ajoutez les lignes suivantes après le retour et l'instruction Avant de commencer:
Md Haidar Ali Khan
4

suite au commentaire de Donald:

Cette variable s'applique lorsque la journalisation binaire est activée.

Tout ce que j'avais à faire était:

  1. désactivé log_bin dans my.cnf (#log_bin)
  2. redémarrer mysql
  3. importer la base de données
  4. activer log_bin
  5. redémarrer mysql

Cela évite ce problème d'importation.

(Ensuite, je vais revoir le code du programmeur pour suggérer une amélioration)

Mayra Navarro
la source
3

Lorsque votre fonction est déterministe, vous pouvez la déclarer en toute sécurité comme déterministe. L'emplacement du mot clé "DETERMINISTIC" est le suivant.

entrez la description de l'image ici

Parc JongBum
la source
2

Sous Windows 10,

Je viens de résoudre ce problème en procédant comme suit.

  1. Accédez à my.ini et ajoutez ces 2 lignes sous [mysqld]

    skip-log-bin
    log_bin_trust_function_creators = 1
  2. redémarrer le service MySQL

Preetham
la source
après avoir fait cela, j'ai eu une erreur sur l'esclave -Got fatal error 1236 from master when reading data from binary log: 'Binary log is not open'
Ramratan Gupta
0

Essayez de définir le définisseur de la fonction!

Donc au lieu de

CREATE FUNCTION get_pet_owner

vous écrirez quelque chose comme

CREATE DEFINER=procadmin@% FUNCTION get_pet_owner

qui devrait fonctionner si l'utilisateur prodacmin a le droit de créer des fonctions / procédures.

Dans mon cas, la fonction fonctionnait lorsqu'elle était générée via MySQL Workbench mais ne fonctionnait pas lorsqu'elle était exécutée directement en tant que script SQL. Les modifications ci-dessus ont résolu le problème.

DevKingKev
la source