MySQL Cluster には、トランザクションの処理に関していくつかの制限があります。これらには、次のものが含まれます。
トランザクション分離レベル
NDBCLUSTER
ストレージエンジンは、READ COMMITTED
トランザクション分離レベルのみをサポートします。(たとえば、InnoDB
はREAD COMMITTED
、READ UNCOMMITTED
、REPEATABLE READ
、およびSERIALIZABLE
をサポートします。)これがクラスタデータベースのバックアップとリストアに与える影響については、セクション18.5.3.4「MySQL Cluster バックアップのトラブルシューティング」を参照してください。)-
トランザクションと BLOB または TEXT カラム
NDBCLUSTER
は、MySQL から認識できるテーブルに MySQL のBLOB
またはTEXT
データ型のいずれかを使用するカラム値の一部のみを格納します。BLOB
またはTEXT
の残りの部分は、MySQL からアクセスできない別の内部テーブルに格納されます。これに関連して、これらの型のカラムを含むテーブルに対してSELECT
ステートメントを実行するときに常に注意すべき問題が 2 つ発生します。MySQL Cluster テーブルからの
SELECT
の場合:SELECT
にBLOB
またはTEXT
カラムが含まれる場合は、READ COMMITTED
トランザクション分離レベルが読み取りロック付きの読み取りに変換されます。これは一貫性を保証するために行われます。-
一意キーのルックアップを使用して
BLOB
またはTEXT
データ型のいずれかを使用するカラムを取得し、1 つのトランザクション内で実行されるSELECT
の場合は、共有読み取りロックがトランザクションの期間中 (つまり、トランザクションがコミットまたは中止されるまで) そのテーブルに保持されます。インデックスまたはテーブルスキャンを使用するクエリーでは、
BLOB
またはTEXT
カラムを含むNDB
テーブルが対象であっても、この問題は発生しません。たとえば、次の
CREATE TABLE
ステートメントによって定義されたテーブルt
について考えます。CREATE TABLE t ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT NOT NULL, c INT NOT NULL, d TEXT, INDEX i(b), UNIQUE KEY u(c) ) ENGINE = NDB,
t
に対する次のクエリーでは、1 つ目のクエリーが主キールックアップを使用し、2 つ目が一意キールックアップを使用しているため、いずれも共有読み取りロックが発生します。SELECT * FROM t WHERE a = 1; SELECT * FROM t WHERE c = 1;
しかし、ここに示す 4 つのクエリーでは、いずれも共有読み取りロックは発生しません。
SELECT * FROM t WHERE b 1; SELECT * FROM t WHERE d = '1'; SELECT * FROM t; SELECT b,c WHERE a = 1;
その理由は、これら 4 つのクエリーのうち、1 つ目はインデックススキャンを使用し、2 つ目と 3 つ目はテーブルスキャンを使用し、4 つ目は (主キールックアップを使用していますが)
BLOB
またはTEXT
カラムの値を取得していないためです。BLOB
またはTEXT
カラムを取得する一意キールックアップを使用するクエリーを回避するか、このようなクエリーを回避できない場合はトランザクションのコミットをできるだけあとで行うようにすると、共有読み取りロックによる問題を最小限に抑えることができます。
-
ロールバック 部分的なトランザクションおよびトランザクションの部分的なロールバックはありません。重複キーまたは同様のエラーが発生すると、トランザクション全体がロールバックされます。
この動作は、個々のステートメントをロールバックできる
InnoDB
などのほかのトランザクション対応のストレージエンジンと異なります。 -
トランザクションとメモリー使用量 この章の別の場所で説明したように、MySQL Cluster では大規模なトランザクションが適切に処理されません。多数の操作を含む 1 つの大規模なトランザクションを実行するより、少数の操作を含む複数の小規模なトランザクションを実行する方が適切です。特に考慮すべき点は、大規模なトランザクションが非常に大量のメモリーを必要とすることです。このため、いくつかの MySQL ステートメントのトランザクション動作に対して次のリストに示すような影響があります。
TRUNCATE TABLE
は、NDB
テーブルに対して使用した場合、トランザクションになりません。TRUNCATE TABLE
でテーブルを空にできない場合は、成功するまでこれを再実行する必要があります。DELETE FROM
(WHERE
句が内場合も含む) は、トランザクションになります。テーブルに非常に多くの行が含まれる場合は、複数のDELETE FROM ... LIMIT ...
ステートメントを使用して削除操作を「ひとまとめに」すると、パフォーマンスが向上することがあります。テーブルを空にすることが目的である場合は、代わりにTRUNCATE TABLE
を使用することをお勧めします。-
LOAD DATA ステートメント
LOAD DATA INFILE
は、NDB
テーブルに使用した場合、トランザクションになりません。重要LOAD DATA INFILE
ステートメントを実行すると、NDB
エンジンは通信ネットワークの利用率が高くなるように不規則な間隔でコミットを実行します。このようなコミットが発生するタイミングを事前に知ることはできません。 ALTER TABLE とトランザクション
ALTER TABLE
の一部としてNDB
テーブルをコピーする場合、コピーの作成はトランザクションになりません。(いずれにしても、コピーが削除されたときにこの操作はロールバックされます。)
トランザクションと COUNT() 関数 MySQL Cluster レプリケーションを使用する場合、スレーブでの
COUNT()
関数のトランザクション一貫性は保証されません。つまり、1 つのトランザクション内でテーブル内の行数を変更する一連のステートメント (INSERT
、DELETE
、またはその両方) をマスターで実行しているときに、スレーブでSELECT COUNT(*) FROM
クエリーを実行すると、中間の結果が返される可能性があります。これは、table
SELECT COUNT(...)
がダーティー読み取りを行うために発生し、NDB
ストレージエンジンのバグではありません。(詳細は、Bug #31321 を参照してください。)