MySQL 8.0 リファレンスマニュアル MySQL NDB Cluster 8.0 を含む

このページは機械翻訳したものです。

17.5.1.14 レプリケーションとシステム関数

一部の関数は条件によっては適切に複製されません。

ステートメントベースレプリケーションが有効のときに前述の制限に対する回避策として、問題のある関数結果をユーザー変数に保存して、後続のステートメントでその変数を参照する方法を使用できます。 たとえば、次の単一行 INSERT は、UUID() 関数を参照するため問題があります。

INSERT INTO t VALUES(UUID());

この問題を回避するには、代わりにこれを実行してください。

SET @my_uuid = UUID();
INSERT INTO t VALUES(@my_uuid);

このステートメントの連続は複製されます。@my_uuid の値が INSERT ステートメントの前にユーザー変数イベントとしてバイナリログに格納されて INSERT で使用できるためです。

同じ概念が複数行挿入に適用されますが、使用するのが面倒です。 2 行挿入の場合、このようにできます。

SET @my_uuid1 = UUID(); @my_uuid2 = UUID();
INSERT INTO t VALUES(@my_uuid1),(@my_uuid2);

ただし、行数が多いか不明の場合、この回避策は困難であるか実用的でありません。 たとえば、次のステートメントを個々のユーザー変数が各行に関連付けられているものに変換することはできません。

INSERT INTO t2 SELECT UUID(), * FROM t1;

ストアドファンクション内で、RAND() は、関数の実行中に 1 回だけ呼び出されるかぎり、正しく複製されます。 (関数実行タイムスタンプおよび乱数シードは、ソースとレプリカで同一の暗黙的な入力とみなすことができます。)

FOUND_ROWS()ROW_COUNT() 関数がステートメントベースレプリケーションを使用して複製されるときは、信頼性がありません。 回避策は、関数呼び出しの結果をユーザー変数に格納してから、INSERT ステートメントでこれを使用することです。 たとえば、mytable という名前のテーブルに結果を格納する場合は、普通は次のように実行するかもしれません。

SELECT SQL_CALC_FOUND_ROWS FROM mytable LIMIT 1;
INSERT INTO mytable VALUES( FOUND_ROWS() );

しかし、mytable を複製する場合は、次のように SELECT ... INTO を使用してから変数をテーブルに格納することをお勧めします。

SELECT SQL_CALC_FOUND_ROWS INTO @found_rows FROM mytable LIMIT 1;
INSERT INTO mytable VALUES(@found_rows);

このように、ユーザー変数はコンテキストの一部としてレプリケートされ、レプリカに正しく適用されます。

これらの関数は、MIXED モード使用時に行ベースレプリケーションを使用して自動的に複製され、STATEMENT モードで警告を生成します。 (Bug #12092、Bug #30244)