20

InnoDBエンジンが真のシリアル化可能な分離1を実装するのか、スナップショット分離を実装するのかは、 MySQLのドキュメントからは完全には明らかではありません。これは、紛らわしいことに「シリアル化可能」とも呼ばれます。どちらですか?

MySQL InnoDBがそうでない場合、完全に無料の本番品質のRDBMSはありますか?

1ここで​​、「真のシリアル化可能な分離」とは、SQL標準による読み取り異常だけでなく、書き込みスキュー異常も存在しないことを意味します。これについては、ここでさらに詳しく説明します。

4

5 に答える 5

13

アップデート:

コメントを参照してください。これはMySQL5.5で修正されているようです。これらの例では、まだテーブルロックがあり、インデックスの次のキーロックをだますことはできません。

オリジナル:

昨日あなたの質問を見つけました、そして私はInnoDbのMVCCseriabilityモデルについても疑問に思いました。

だから私はいくつかのテストを行いました。MySQL5.1.37。直列化可能性の問題の良いテストは、postgrESQL 9.0 MVCCドキュメントで提供されているものです。この章では、直列化可能分離と真の直列化可能性について、述語ロックが実行されていない場合の直列化可能性に関するMVCCモデルの制限を確認できます。

それでは、MySQLでテストしてみましょう。

CREATE TABLE t1 (
 class integer,
 value integer
) ENGINE=InnoDB;

INSERT INTO t1 (`class`,`value`) VALUES
  (1,10),
  (1,20),
  (2,100),
  (2,200);

次に、2つの異なる接続を開いて、2つの並列トランザクション(T1とT2)を作成します。

T1:

SET TRANSACTIOn ISOLATION LEVEL SERIALIZABLE;
BEGIN;
SELECT SUM(value) FROM t1 WHERE class = 1;

結果は30です。

T2:

 SET TRANSACTIOn ISOLATION LEVEL SERIALIZABLE;
 BEGIN;
 SELECT SUM(value) FROM t1 WHERE class = 2;

結果は300です。

次に、直列化可能性の問題が発生します。T1がT2からの選択を無効にする行を挿入した場合(ここではT2も同じことを行います)。

T1:

INSERT INTO t1 (`class`,`value`) VALUES (2,30);

==>待機中(ロックが設定されています)

T2:

INSERT INTO t1 (`class`,`value`) VALUES (1,300);

==>エラー1213(40001):ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再開してみてください

T1は挿入に成功し、t2にはロールバックがあり、直列化可能性が良好です。

これはPostgreSQL9.0では失敗します(9.1では状況が変わりますが、別の問題です)。実際、テーブルへの挿入を実行できるのは1つのトランザクションのみです。で挿入しようとしても。class=3

INSERT INTO t1 (`class`,`value`) VALUES (3,30);

待機中のロックと、問題が発生した場合のデッドロックが表示されます。MySQLに述語ロックがあるように見えます...しかし実際には、これはInnoDBの次のキーロックの実装です。

Innodbは、インデックスに対してもいくつかのギャップをロックして行ロックを実行します。ここでは、テーブルにインデックスがありません。MySQLがテーブルをロックすることを決定したようです。

それでは、次のキーのロックをテストして、これが直列化可能性を強制するかどうかを確認してみましょう。最初に実行中のトランザクションをロールバックします(T1)。次に、インデックスを作成します。

CREATE index t1class ON t1 (class);

次に、テストをやり直します。成功、直列化可能性は引き続き適用されます。朗報です。

しかし、インデックスが設定されていると、次のキーのロックと行のロックがインデックスで行われると思います。これは、並列トランザクションに影響を与えない場合に挿入を実行できるはずであることを意味します...そしてここに大きな問題があります。

T1:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
SELECT SUM(value) FROM t1 WHERE class = 1;

結果は30です。

T2:

 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
 BEGIN;
 SELECT SUM(value) FROM t1 WHERE class = 2;

結果は300です。

ここでは、T1に無関係な挿入を行います。これで、インデックスが作成され、これが成功します。

T1:

INSERT INTO t1 (`class`,`value`) VALUES (3,30);

どちらも挿入を実行できます(ここでは1つだけ作成しました)。これは正常です。予測ロックは適用されません。SELECTクエリは実行されていませんclass=3。次のキーのロックは、適切なインデックスを指定するとパフォーマンスが向上するように見えます(挿入にテーブルロックがない)。

次に、次のキーのロックに挿入しようとします。T2(class = 2)の選択に一致する行に:

T1:

INSERT INTO t1 (`class`,`value`) VALUES (2,30);

痛い。成功します!

T2:

INSERT INTO t1 (`class`,`value`) VALUES (1,300);

==>待っています。そこにはまだ鍵があります。うまくいけば。

T1:

COMMIT;

T2 :(ロックが解除されたところで挿入が行われます)

SELECT SUM(value) FROM t1 WHERE class = 2;
COMMIT;

ここにはまだ300があります。直列化可能性がなくなったようです。

select * from t1;
+-------+-------+
| class | value |
+-------+-------+
|     1 |    10 | 
|     1 |    20 | 
|     2 |   100 | 
|     2 |   200 | 
|     3 |    30 | <-- test
|     2 |    30 | <-- from trans1
|     1 |   300 | <-- from trans2 ERROR!
+-------+-------+

結果:並列トランザクションクエリに影響を与える行を挿入する前に、関連のない新しい行を挿入することにより、次のキーのロックメカニズムをスプーフィングしました。または、少なくともこれは私が私のテストから理解していることです。したがって、真の直列化可能性についてエンジンを信頼しないでくださいトランザクションに集計関数がある場合、最良の方法は、テーブルを手動でロックし、直列化可能性の問題を実際の1人だけの状況に変換することです。驚くことではありません。例における他の直列化可能性の問題は、制約の検証(操作後も量がまだ正であることを確認する)です。これらの場合にもロックを所有していますか。

于 2011-11-13T16:17:50.263 に答える
10

完全に無料の本番品質のRDBMSはありますか?

Postgresは、バージョン9.1以降、真のシリアル化可能な分離をサポートしています。それは確かに「完全に無料」と「生産品質」の両方の資格があります。

于 2011-12-12T18:01:23.620 に答える
1

「シリアル化可能な」トランザクションを使用していますか?確かに、「SET session TRANSACTIONISOLATIONLEVELSERIALIZABLE」を使用する必要があります。次のトランザクションだけでなく、セッション全体がシリアライズ可能になるようにします。

OSXで5.5.29でテストしています

また、T1に(3,30)を挿入しようとすると、クラスでインデックスを作成した後、トランザクションは待機し、ロック待機タイムアウト後に中止されます。(T2はまだ進行中です)

于 2013-04-21T17:02:24.340 に答える
-2

提供したリンクで詳細を読むと、要件の1つとして述べたように、「repeatable-read」モード(innodbのデフォルト)を使用すると、読み取りの異常がなくなると書かれています。また、2番目のリンクを読み取ると、書き込み異常の処理がエンドユーザーにシフトしているように見えます。記事では、 MySQLもサポートしているOracleのSelectforUpdateについて言及しています。これがあなたの要件を満たしているかどうかはわかりませんが、少し役立つはずです。

于 2011-06-08T01:22:31.733 に答える
-5

MySQLがシリアル化可能な分離を実装しているとは思いません。これは、私が理解しているように、ロールバックする機能を必要としますが、これは間違いなくサポートされていません。詳細については、こちらをお読みください

于 2011-06-07T18:22:46.567 に答える