@ledsun blog

無味の味は佳境に入らざればすなわち知れず

MySQLのロックに関する調査メモ その3

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     ;;

ギャップロック?

出力された情報の読み方が謎です。