MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  ...  /  バイナリロギングでの安全および安全でないステートメントの判断

17.2.1.3 バイナリロギングでの安全および安全でないステートメントの判断

MySQL レプリケーションでのステートメントの「安全性」とは、ステートメントベースの形式を使用してステートメントとその効果を正しくレプリケートできるかどうかを指します。 これがステートメントに当てはまる場合、ステートメントは安全と言い、そうでない場合は安全でないと言います。

一般的に、ステートメントが決定的である場合は安全であり、そうでない場合は安全ではありません。 ただし、特定の非決定的関数は「安全でない」と見なされません (このセクションの後半の安全でないと見なされない非決定的関数。を参照してください)。 また、浮動小数点数学関数 (ハードウェア依存) からの結果を使用するステートメントは、常に安全でないと見なされます (セクション17.5.1.12「レプリケーションと浮動小数点値」を参照してください)。

安全および安全でないステートメントの処理.  ステートメントは、ステートメントが安全と見なされるかどうかに応じて、およびバイナリロギング形式 (すなわち、binlog_format の現在の値) に基づいて異なる方法で処理されます。

  • 行ベースロギングを使用する場合、安全および安全でないステートメントの扱いに違いはありません。

  • 混合形式ロギングを使用する場合、安全でないとフラグされたステートメントは行ベース形式を使用してログが記録され、安全と見なされたステートメントはステートメントベース形式を使用してログが記録されます。

  • ステートメントベースロギングを使用する場合、安全でないとフラグされたステートメントはこの結果に警告を生成します。 安全なステートメントは通常どおりにログが記録されます。

安全でないとフラグされた各ステートメントは警告を生成します。 このようなステートメントがソースで多数実行された場合、エラーログファイルが過剰に大きくなる可能性があります。 これを防ぐために、MySQL には警告抑制メカニズムがあります。 50 秒間に 50 回を超える最新の ER_BINLOG_UNSAFE_STATEMENT 警告が 50 回生成されると、警告抑制が有効になります。 有効になっているときは、これによってこのような警告がエラーログに書き込まれることはありません。代わりに、このタイプの警告が 50 個生成されるたびに、「最後の警告が N 回、最近の S 秒間に繰り返されました」との注記がエラーログに書き込まれます。 50 個の最近のこのような警告が 50 秒以内に発行されるかぎり、これが継続します。頻度がこのしきい値を下回ると、再度通常どおりに警告ログが記録されます。 警告抑止は、ステートメントベースロギングでステートメントの安全がどのように判断されるか、および警告がクライアントにどのように送信されるかに影響しません。 MySQL クライアントは引き続きこのようなステートメントごとに 1 つの警告を受け取ります。

詳細については、セクション17.2.1「レプリケーション形式」を参照してください。

安全でないと見なされるステートメント.  次の特徴を持つステートメントは安全でないと見なされます。

  • レプリカで異なる値を返す可能性のあるシステム関数を含むステートメント.  これらの関数には、FOUND_ROWS(), GET_LOCK(), IS_FREE_LOCK(), IS_USED_LOCK(), LOAD_FILE(), MASTER_POS_WAIT(), RAND(), RELEASE_LOCK(), ROW_COUNT(), SESSION_USER(), SLEEP(), SYSDATE(), SYSTEM_USER(), USER(), UUID() および UUID_SHORT() が含まれます。

    安全でないと見なされない非決定的関数。.  これらの関数は決定的ではありませんが、ロギングおよびレプリケーション目的の場合は安全として処理されます: CONNECTION_ID()CURDATE()CURRENT_DATE()CURRENT_TIME()CURRENT_TIMESTAMP()CURTIME()LAST_INSERT_ID()LOCALTIME()LOCALTIMESTAMP()NOW()UNIX_TIMESTAMP()UTC_DATE()UTC_TIME()、および UTC_TIMESTAMP()

    詳細については、セクション17.5.1.14「レプリケーションとシステム関数」を参照してください。

  • システム変数への参照.  ほとんどのシステム変数は、ステートメントベース形式で正しく複製されません。 セクション17.5.1.39「レプリケーションと変数」を参照してください。 例外については、セクション5.4.4.3「混合形式のバイナリロギング形式」を参照してください。

  • UDF.  UDF が何をするかは制御できないため、それが安全でないステートメントを実行していると推定する必要があります。

  • 全文プラグイン.  このプラグインの動作は MySQL サーバーによって異なる場合があるため、それに基づくステートメントは結果が異なる場合があります。 このため、フルテキストプラグインに依存するすべてのステートメントは、MySQL で安全でないものとして扱われます。

  • トリガーまたはストアドプログラムは AUTO_INCREMENT カラムを持つテーブルを更新する。.  行の更新順序がソースとレプリカで異なる可能性があるため、これは安全ではありません。

    また、複合主キーを持つテーブルに、この複合キーの先頭カラムでない AUTO_INCREMENT カラムが含まれるテーブルに INSERT することは、安全ではありません。

    詳細については、セクション17.5.1.1「レプリケーションと AUTO_INCREMENT」を参照してください。

  • 複数の主キーまたは一意キーを持つテーブルでの INSERT ... ON DUPLICATE KEY UPDATE ステートメント.  複数の主キーまたは一意キーを持つテーブルに対して実行されるときのこのステートメントは、安全でないと見なされます (ストレージエンジンがキーをチェックする順番に影響されやすいですが、これは決定的でなく、さらに MySQL Server が更新する行の選択がこれに依存するためです)。

    複数の一意キーまたは主キーを持つテーブルに対する INSERT ... ON DUPLICATE KEY UPDATE ステートメントは、ステートメントベースのレプリケーションに対して安全でないとマークされます。 (Bug #11765650、Bug #58637)

  • LIMIT を使用する更新.  行の取得順序が指定されていないため、安全でないと見なされます。 セクション17.5.1.18「レプリケーションと LIMIT」を参照してください。

  • ログテーブルへのアクセスまたは参照.  システムログテーブルの内容は、ソースとレプリカで異なる場合があります。

  • トランザクション操作後の非トランザクション操作.  トランザクション内で、トランザクション読み取りまたは書き込み後に非トランザクション読み取りまたは書き込みを実行することを許可することは、安全でないと見なされます。

    詳細については、セクション17.5.1.35「レプリケーションとトランザクション」を参照してください。

  • セルフロギングテーブルへのアクセスまたは参照.  セルフロギングテーブルへのすべての読み取りと書き込みは、安全でないと見なされます。 トランザクション内で、セルフロギングテーブルへの読み取りまたは書き込みに続くステートメントも、安全でないと見なされます。

  • LOAD DATA ステートメント.  LOAD DATA は安全でないとみなされ、binlog_format=MIXED の場合、ステートメントは行ベースの形式で記録されます。 他の安全でないステートメントとは異なり、binlog_format=STATEMENT LOAD DATA で警告が生成されない場合。

  • XA トランザクション.  ソースでパラレルにコミットされた 2 つの XA トランザクションがレプリカで逆の順序で準備されている場合、安全に解決できないステートメントベースのレプリケーションでロック依存関係が発生する可能性があり、レプリケーションがレプリカのデッドロックで失敗する可能性があります。 binlog_format=STATEMENT が設定されている場合、XA トランザクション内の DML ステートメントに安全でないというフラグが付けられ、警告が生成されます。 binlog_format=MIXED または binlog_format=ROW が設定されている場合、XA トランザクション内の DML ステートメントは行ベースのレプリケーションを使用して記録され、潜在的な問題は存在しません。

  • 非決定的関数を参照する DEFAULT 句.  式のデフォルト値が非決定的関数を参照している場合、式を評価するステートメントはステートメントベースレプリケーションでは安全ではありません。 これには、INSERTUPDATEALTER TABLE などのステートメントが含まれます。 他のほとんどの安全でないステートメントとは異なり、このカテゴリのステートメントは行ベースの形式で安全にレプリケートできません。 binlog_formatSTATEMENT に設定されている場合、ステートメントはログに記録されて実行されますが、エラーログに警告メッセージが書き込まれます。 binlog_formatMIXED または ROW に設定されている場合、ステートメントは実行されず、エラーログにエラーメッセージが書き込まれます。 明示的なデフォルトの処理の詳細は、MySQL 8.0.13 での明示的なデフォルト処理 を参照してください。

追加情報については セクション17.5.1「レプリケーションの機能と問題」を参照してください。


関連キーワード:  ステートメント, ベース, トランザクション, ソース, 参照, 警告, 形式, バイナリ, テーブル, 関数