DETERMINISTIC, NO SQL oder READS SQL DATA in seiner Deklaration und binären Protokollierung ist aktiviert

107

Beim Importieren der Datenbank in MySQL wurde folgende Fehlermeldung angezeigt:

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)

Ich weiß nicht, welche Dinge ich ändern muss. Kann mir jemand helfen, wie ich das lösen kann?

ASR
quelle

Antworten:

236

Es gibt zwei Möglichkeiten, dies zu beheben:

  1. Führen Sie in der MySQL-Konsole Folgendes aus:

    SET GLOBAL log_bin_trust_function_creators = 1;

  2. Fügen Sie der Konfigurationsdatei mysql.ini Folgendes hinzu:

    log_bin_trust_function_creators = 1;

Die Einstellung lockert die Überprüfung auf nicht deterministische Funktionen. Nicht deterministische Funktionen sind Funktionen, die Daten ändern (dh Anweisungen aktualisieren, einfügen oder löschen). Weitere Informationen finden Sie hier .

Bitte beachten Sie, dass diese Einstellung nicht gilt, wenn die binäre Protokollierung NICHT aktiviert ist.

Binäre Protokollierung gespeicherter Programme

Wenn die binäre Protokollierung nicht aktiviert ist, gilt log_bin_trust_function_creators nicht.

log_bin_trust_function_creators

Diese Variable gilt, wenn die binäre Protokollierung aktiviert ist.

Der beste Ansatz ist ein besseres Verständnis und eine bessere Verwendung deterministischer Deklarationen für gespeicherte Funktionen. Diese Deklarationen werden von MySQL verwendet, um die Replikation zu optimieren, und es ist eine gute Sache, sie sorgfältig auszuwählen, um eine fehlerfreie Replikation zu erzielen.

DETERMINISTISCH Eine Routine gilt als „deterministisch“, wenn sie immer das gleiche Ergebnis für die gleichen Eingabeparameter liefert und ansonsten NICHT DETERMINISTISCH. Dies wird hauptsächlich bei der Verarbeitung von Zeichenfolgen oder Mathematik verwendet, ist jedoch nicht darauf beschränkt.

NICHT DETERMINISTISCH Gegenüber "DETERMINISTISCH". " Wenn in der Routinedefinition weder DETERMINISTIC noch NOT DETERMINISTIC angegeben ist, lautet der Standardwert NICHT DETERMINISTIC. Um zu deklarieren, dass eine Funktion deterministisch ist, müssen Sie DETERMINISTIC explizit angeben. " Wenn also keine Aussage gemacht wird, wird MySQl die Funktion als "NICHT DETERMINISTISCH" behandeln. Diese Aussage aus dem Handbuch steht im Widerspruch zu anderen Aussagen aus einem anderen Bereich des Handbuchs, in denen es heißt: "Wenn Sie eine gespeicherte Funktion erstellen, müssen Sie entweder deklarieren, dass sie deterministisch ist oder keine Daten ändert. Andernfalls ist die Datenwiederherstellung oder -replikation möglicherweise nicht sicher. Standardmäßig muss mindestens eine der Anweisungen DETERMINISTIC, NO SQL oder READS SQL DATA explizit angegeben werden, damit eine CREATE FUNCTION-Anweisung akzeptiert wird. Andernfalls tritt ein Fehler auf "

Ich persönlich habe in MySQL 5.5 einen Fehler erhalten, wenn es keine Deklaration gibt, daher habe ich immer mindestens eine Deklaration von "DETERMINISTIC", "NOT DETERMINISTIC", "NO SQL" oder "READS SQL DATA" eingefügt, unabhängig von anderen Deklarationen, die ich möglicherweise habe.

LESEN VON SQL-DATEN Dies teilt MySQL ausdrücklich mit, dass die Funktion NUR Daten aus Datenbanken liest. Sie enthält daher keine Anweisungen zum Ändern von Daten, sondern SQL-Anweisungen zum Lesen von Daten (eq SELECT).

MODIFIES SQL DATA Dies zeigt an, dass die Routine Anweisungen enthält, die Daten schreiben können (z. B. Anweisungen UPDATE, INSERT, DELETE oder ALTER).

NO SQL Dies zeigt an, dass die Routine keine SQL-Anweisungen enthält.

CONTAINS SQL Dies gibt an, dass die Routine SQL-Anweisungen enthält, jedoch keine Anweisungen zum Lesen oder Schreiben von Daten. Dies ist die Standardeinstellung, wenn keine dieser Eigenschaften explizit angegeben wird. Beispiele für solche Anweisungen sind SELECT NOW (), SELECT 10 + @ b, SET @x = 1 oder DO RELEASE_LOCK ('abc'), die Daten ausführen, aber weder lesen noch schreiben.

Beachten Sie, dass es MySQL-Funktionen gibt, die nicht deterministisch sicher sind, wie z. B. NOW (), UUID () usw., die auf verschiedenen Computern wahrscheinlich unterschiedliche Ergebnisse liefern. Daher muss eine Benutzerfunktion, die solche Anweisungen enthält, als NOT DETERMINISTIC deklariert werden . Außerdem ist eine Funktion, die Daten aus einem nicht replizierten Schema liest, eindeutig NONDETERMINISTISCH. * *

Die Bewertung der Art einer Routine basiert auf der „Ehrlichkeit“ des Erstellers: MySQL überprüft nicht, ob eine als DETERMINISTIC deklarierte Routine frei von Aussagen ist, die nicht deterministische Ergebnisse liefern. Eine falsche Deklaration einer Routine kann jedoch die Ergebnisse oder die Leistung beeinträchtigen. Das Deklarieren einer nichtdeterministischen Routine als DETERMINISTIC kann zu unerwarteten Ergebnissen führen, indem das Optimierungsprogramm falsche Ausführungsplanentscheidungen trifft. Das Deklarieren einer deterministischen Routine als NONDETERMINISTIC kann die Leistung beeinträchtigen, da verfügbare Optimierungen nicht verwendet werden.

Donal
quelle
Kannst du mir erklären, was im Hintergrund passiert ist?
ASR
2
Ich vermute, dass die Datenbank eine Funktion hat, die Daten ändert (enthält eine Anweisung zum Aktualisieren, Einfügen oder Löschen). Weitere Informationen finden Sie hier: dev.mysql.com/doc/refman/5.0/en/stored-programs-logging.html
Donal
1
Sie sollten immer Backups machen
Donal
es braucht super Privilegien!
Felipe Morales
versuchte dies, bekam aber immer noch das nicht deterministische Problem, irgendeinen anderen Vorschlag? danke
Edwin Bermejo
40
  • Wenn Sie eine gespeicherte Funktion erstellen, müssen Sie entweder deklarieren, dass sie deterministisch ist oder keine Daten ändert. Andernfalls ist die Datenwiederherstellung oder -replikation möglicherweise nicht sicher.

  • Standardmäßig muss mindestens eine der Anweisungen DETERMINISTIC, NO SQL oder READS SQL DATA explizit angegeben werden, damit eine CREATE FUNCTION-Anweisung akzeptiert wird. Andernfalls tritt ein Fehler auf:

Um dieses Problem zu beheben, fügen Sie die folgenden Zeilen hinzu: After Return und Before Begin-Anweisung:

READS SQL DATA
DETERMINISTIC

Zum Beispiel :

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

Weitere Informationen zu diesem Problem finden Sie hier

Sunny SM
quelle
Dies funktioniert, weil die Einstellung READS SQL DATAdie am wenigsten einschränkende der drei ist. Wenn Ihre Funktion in die Kategorie NO SQLoder fällt DETERMINISTIC, können Sie die Leistung verbessern, indem Sie Ihre Funktionen ändern. Andererseits ist die Einstellung READS SQL DATAauch am wenigsten fehleranfällig. Wenn Sie also falsch verwenden NO SQLoder DETERMINISTICfalsche Ergebnisse erhalten.
Jonathan
@ SunnyS.M, Awesome Erklärung wie READS SQL DATA DETERMINISTIC.Um dieses Problem zu beheben, fügen Sie folgende Zeilen nach Rückkehr und vor Beginn Anweisung:
Md Haidar Ali Khan
4

folgenden Donalds Kommentar:

Diese Variable gilt, wenn die binäre Protokollierung aktiviert ist.

Alles was ich tun musste war:

  1. deaktiviert log_bin in my.cnf (#log_bin)
  2. Starten Sie MySQL neu
  3. DB importieren
  4. Aktivieren Sie log_bin
  5. Starten Sie MySQL neu

Dieser Schritt aus dem Importproblem heraus.

(Dann werde ich den Code des Programmierers überprüfen, um eine Verbesserung vorzuschlagen.)

Mayra Navarro
quelle
3

Wenn Ihre Funktion deterministisch ist, können Sie sie mit Sicherheit als deterministisch deklarieren. Die Position des Schlüsselworts "DETERMINISTIC" lautet wie folgt.

Geben Sie hier die Bildbeschreibung ein

Park JongBum
quelle
2

Unter Windows 10

Ich habe dieses Problem gerade wie folgt gelöst.

  1. Gehen Sie zu my.ini und fügen Sie diese 2 Zeilen unter [mysqld] hinzu.

    skip-log-bin
    log_bin_trust_function_creators = 1
  2. Starten Sie den MySQL-Dienst neu

Preetham
quelle
nachdem ich dies getan hatte, bekam ich Fehler auf Sklave -Got fatal error 1236 from master when reading data from binary log: 'Binary log is not open'
Ramratan Gupta
0

Versuchen Sie den Definer für die Funktion einzustellen!

Also statt

CREATE FUNCTION get_pet_owner

Sie werden etwas Ähnliches schreiben

CREATE DEFINER=procadmin@% FUNCTION get_pet_owner

Dies sollte funktionieren, wenn der Benutzer prodacmin Rechte zum Erstellen von Funktionen / Prozeduren hat.

In meinem Fall funktionierte die Funktion beim Generieren über MySQL Workbench, aber nicht, wenn sie direkt als SQL-Skript ausgeführt wurde. Durch die obigen Änderungen wurde das Problem behoben.

DevKingKev
quelle