宣言にDETERMINISTIC、NO SQL、またはREADS SQL DATAがあり、バイナリロギングが有効になっている


107

mysqlでデータベースをインポートしているときに、次のエラーが発生しました。

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)

どのような変更が必要かわかりません。これを解決する方法を誰かが助けてくれますか?

回答:


236

これを修正するには2つの方法があります。

  1. MySQLコンソールで以下を実行します。

    SET GLOBAL log_bin_trust_function_creators = 1;

  2. mysql.ini構成ファイルに以下を追加します。

    log_bin_trust_function_creators = 1;

この設定により、非決定的関数のチェックが緩和されます。非決定的関数は、データを変更する関数です(つまり、更新、挿入、または削除ステートメントがあります)。詳細については、こちらをご覧ください

バイナリログが有効になっていない場合、この設定は適用されないことに注意してください。

ストアドプログラムのバイナリログ

バイナリログが有効になっていない場合、log_bin_trust_function_creatorsは適用されません。

log_bin_trust_function_creators

この変数は、バイナリロギングが有効な場合に適用されます。

最善のアプローチは、ストアド関数の確定的宣言をよりよく理解して使用することです。MySQLはこれらの宣言を使用してレプリケーションを最適化します。これらの宣言を慎重に選択して、正常なレプリケーションを実現することをお勧めします。

DETERMINISTIC ルーチンは、同じ入力パラメーターに対して常に同じ結果を生成する場合は「決定的」と見なされ、それ以外の場合はDETERMINISTICと見なされません。これは主に文字列または数学処理で使用されますが、それに限定されません。

確定的 ではない「確定的」の反対。" ルーチン定義でDETERMINISTICもNOT DETERMINISTICも指定されていない場合、デフォルトはNOT DETERMINISTICです。関数が決定的であることを宣言するには、DETERMINISTICを明示的に指定する必要があります。 " したがって、ステートメントが作成されない場合、MySQlは関数を「NOT DETERMINISTIC」として扱います。マニュアルからのこの発言は、マニュアルの他の領域からの他の発言と矛盾しています:「ストアドファンクションを作成するときは、確定的であること、またはデータを変更しないことを宣言する必要があります。それ以外の場合は、データの回復や複製には安全でない可能性があります。デフォルトでは、CREATE FUNCTIONステートメントを受け入れるには、DETERMINISTIC、NO SQL、またはREADS SQL DATAの少なくとも1つを明示的に指定する必要があります。そうでない場合、エラーが発生します "

宣言がない場合、MySQL 5.5で個人的にエラーが発生したため、他の宣言に関係なく、常に「DETERMINISTIC」、「NOT DETERMINISTIC」、「NO SQL」、または「READS SQL DATA」の少なくとも1つの宣言を置きます。

READS SQL DATA これは、関数がデータベースからのみデータを読み取ることをMySQLに明示的に伝えます。したがって、データを変更する命令は含まれませんが、データを読み取るSQL命令(eq SELECT)が含まれます。

MODIFIES SQL DATA これは、ルーチンにデータを書き込む可能性のあるステートメントが含まれていることを示します(たとえば、UPDATE、INSERT、DELETE、またはALTER命令が含まれています)。

NO SQL これは、ルーチンにSQLステートメントが含まれていないことを示します。

CONTAINS SQL これは、ルーチンにはSQL命令が含まれているが、データを読み書きするステートメントは含まれていないことを示します。これらの特性が明示的に指定されていない場合、これがデフォルトです。そのようなステートメントの例は、SELECT NOW()、SELECT 10 + @ b、SET @x = 1またはDO RELEASE_LOCK( 'abc')で、実行されますが、データの読み取りも書き込みも行われません。

異なるマシンで異なる結果を生成する可能性が高い、NOW()、UUID()などの確定的安全ではないMySQL関数があるため、そのような命令を含むユーザー関数はNOT DETERMINISTICとして宣言する必要があることに注意してください。 。また、レプリケートされていないスキーマからデータを読み取る関数は明らかにNONDETERMINISTICです。*

ルーチンの性質の評価は、作成者の「誠実さ」に基づいています。MySQLは、DETERMINISTICと宣言されたルーチンに非決定的な結果を生成するステートメントがないことを確認しません。ただし、ルーチンを誤って宣言すると、結果やパフォーマンスに影響を与える可能性があります。非決定的ルーチンをDETERMINISTICとして宣言すると、オプティマイザが誤った実行プランを選択するため、予期しない結果が生じる可能性があります。確定的ルーチンをNONDETERMINISTICとして宣言すると、使用可能な最適化が使用されなくなり、パフォーマンスが低下する可能性があります。


バックグラウンドで何が起こったか説明してくれませんか?
ASR

2
データベースにデータを変更する機能があると思います(更新、挿入、または削除ステートメントがあります)。詳細については、こちらを参照してください:dev.mysql.com/doc/refman/5.0/en/stored-programs-logging.html
Donal

1
常にバックアップを取る必要があります
Donal

スーパー特権が必要です!
フェリペモラレス

これを試しましたが、それでも非決定論的な問題が発生しました、他の提案?ありがとう
エドウィンベルメホ2018

40
  • ストアドファンクションを作成するときは、確定的であること、またはデータを変更しないことを宣言する必要があります。それ以外の場合は、データの回復や複製には安全でない可能性があります。

  • デフォルトでは、CREATE FUNCTIONステートメントを受け入れるには、DETERMINISTIC、NO SQL、またはREADS SQL DATAの少なくとも1つを明示的に指定する必要があります。そうでない場合、エラーが発生します。

この問題を修正するには、After ReturnおよびBefore Beginステートメントに次の行を追加します。

READS SQL DATA
DETERMINISTIC

例えば ​​:

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

この問題の詳細についてお読みくださいここに


これREADS SQL DATAは、設定が3つの中で最も制限が少ないため機能します。関数がNO SQLまたはDETERMINISTICカテゴリに該当する場合、関数を変更してパフォーマンスを向上させることができます。一方、この設定READS SQL DATAはエラーが発生しにくい傾向もあります。したがって、誤って使用した場合、NO SQLまたはDETERMINISTIC誤った結果が得られる可能性があります。
ジョナサン

SunnyS.M @、などのような恐ろしい説明は、この問題は、復帰後、次の行を追加し、前の文を開始SQL DATA DETERMINISTIC.To修正を読み取ります
メリーランドハイダー・アリ・カーン

4

ドナルドのコメントに続いて:

この変数は、バイナリロギングが有効な場合に適用されます。

私がしなければならなかったすべては:

  1. my.cnfのlog_binを無効化(#log_bin)
  2. mysqlを再起動します
  3. DBのインポート
  4. log_binを有効にする
  5. mysqlを再起動します

これでインポートの問題が解消されます。

(その後、プログラマーのコードを見直して改善を提案します)


3

関数が確定的である場合、確定的であると宣言しても安全です。「DETERMINISTIC」キーワードの場所は次のとおりです。

ここに画像の説明を入力してください


2

Windows 10では

この問題を解決するには、次のようにします。

  1. my.iniに移動し、[mysqld]の下に次の2行を追加します

    skip-log-bin
    log_bin_trust_function_creators = 1
  2. MySQLサービスを再起動します


これを行った後、スレーブでエラーが発生しましたGot fatal error 1236 from master when reading data from binary log: 'Binary log is not open'
Ramratan Gupta

0

関数の定義者を設定してみてください!

だから代わりに

CREATE FUNCTION get_pet_owner

あなたは何かに似たものを書きます

CREATE DEFINER=procadmin@% FUNCTION get_pet_owner

これは、ユーザーprodacminが関数/手順を作成する権利を持っている場合に機能するはずです。

私の場合、MySQL Workbenchで生成されたときに機能しましたが、SQLスクリプトとして直接実行すると機能しませんでした。上記の変更を行うことで問題が修正されました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.