2

ダミーテーブルを作成します。

CREATE TABLE `lock_test` (
  `name` varchar(32) NOT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB ;

私はそれをロックします:

LOCK TABLE lock_test write;

次に、もう一度ロックしようとします(同じクエリ)。2番目のロック要求は明らかにそこでハングします。

select * from INFORMATION_SCHEMA.INNODB_LOCKS;
select * from INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

両方とも空です(ゼロの結果を返します)-私はそれらが入力されることを期待していました。私にはPROCESS許可があります(表示PROCESSLISTはロックが機能していることを示しています)。

これらのテーブルに関して、スティックの端が完全に間違っていますか?情報スキーマプラグインとInnoDBエンジンが確実にインストールされています(SHOW PLUGINSを実行して確認)。

ありがとう

4

2 に答える 2

1

興味深いことに、「問題」は、テーブルを直接 2 回ロックしようとしたことでした。これは、そのテーブルにデータが入力されていないようです。互いに干渉する2つのトランザクションに変更したところ、期待どおりに機能しました。

于 2012-04-26T07:19:50.697 に答える
0

ありますautocommit = 1か?はいの場合、それが理由です。異なるレイヤーで行われる 2 種類のロックがあり、1 つは MySQL レイヤーで、もう 1 つはストレージ エンジン (InnoDB) レイヤーです。

MySQL docs から、Interaction of Table Locking and Transactions :

を呼び出すとLOCK TABLES、 InnoDB は内部で独自のテーブル ロックを取得し、MySQL は独自のテーブル ロックを取得します。InnoDB は次のコミットで内部テーブル ロックを解放しますが、MySQL がテーブル ロックを解放するには、 を呼び出す必要がありますUNLOCK TABLESInnoDB は の呼び出しの直後に内部テーブル ロックを解放し、デッドロックが非常に簡単に発生する可能性がautocommit = 1あるため、 は使用しないでください。InnoDB は、古いアプリケーションが不要なデッドロックを回避するのに役立つ場合、内部テーブル ロックをまったく取得しません。LOCK TABLESautocommit = 1

また、ドキュメントのこの部分 (最後の 2 段落) も確認してください: Locks Set by Different SQL Statements in InnoDB :

LOCK TABLESテーブル ロックを設定しますが、これらのロックを設定するのは InnoDB レイヤーより上位の MySQL レイヤーです。InnoDB は(デフォルト) および の場合にテーブル ロックを認識し、 InnoDB の上の MySQL レイヤーは行レベルのロックを認識します。innodb_table_locks = 1autocommit = 0

于 2012-04-25T00:42:27.490 に答える