MySQLのロックに関する調査メモ その2 - @ledsun blog の続きです。 概念だけ勉強しても理解に限度があります。 実際にロックを起こして観察してみました。
InnoDBのロックの範囲とネクストキーロックの話 - かみぽわーる を参考にしました。 MySQL Shellを起動しMySQLに接続します。
\connect --mysql --user root \use sandbox \sql
sandboxスキーマは練習用に作ってあったものを使い回しています。 テーブルを作成します。
CREATE TABLE `mysqlcasual` ( `id` int(11) NOT NULL AUTO_INCREMENT, `col1` int(11) NOT NULL, `col2` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `idx_col1` (`col1`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `mysqlcasual`(`col1`) VALUES (2),(4),(6),(8),(10),(12),(14),(16);
MySQL 5.7 以降では、ここからの手順が変わっています*1。
CREATE TABLE innodb_lock_monitor(a int) ENGINE=InnoDB;
の代わりに
SET GLOBAL innodb_status_output=ON; SET GLOBAL innodb_status_output_locks=ON;
します。 また、共有ロックではロックが表示されませんでした。
BEGIN; SELECT id, col1 FROM mysqlcasual WHERE col1 = 4 LOCK IN SHARE MODE;
の代わりに
BEGIN; SELECT id, col1 FROM mysqlcasual WHERE col1 = 4 FOR UPDATE;
を試しました。
SHOW ENGINE INNODB STATUS\G
を実行するとTRANSACTIONSセクションにロック情報が表示されました。
RECORD LOCKS space id 173 page no 4 n bits 80 index idx_col1 of table `sandbox`.`mysqlcasual` trx id 7717 lock_mode X Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 80000004; asc ;; 1: len 4; hex 80000002; asc ;;
RECORD LOCKS space id 173 page no 3 n bits 80 index PRIMARY of table `sandbox`.`mysqlcasual` trx id 7717 lock_mode X locks rec but not gap Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0 0: len 4; hex 80000002; asc ;; 1: len 6; hex 00000000162a; asc *;; 2: len 7; hex aa0000011e011d; asc ;; 3: len 4; hex 80000004; asc ;; 4: len 4; hex 80000000; asc ;;
インデックスレコードロック?
RECORD LOCKS space id 173 page no 4 n bits 80 index idx_col1 of table `sandbox`.`mysqlcasual` trx id 7717 lock_mode X locks gap before rec Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 80000006; asc ;; 1: len 4; hex 80000003; asc ;;
ギャップロック?
出力された情報の読み方が謎です。