地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【MySQL】ギャップロックの次のレコードロックをMySQL 8.0から取らなくなった?

タイトルの通り。MySQL 5.7の時に「あ、そこもロック取るんだ」って思っていたやつが8.0から挙動が変わったのか見てみる。8.0.36を使ってます。リピータブルリードで検証。

mysql> SHOW VARIABLES LIKE '%isolation%';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.02 sec)

こんなテーブルでこんなレコードが入っているとする。

mysql> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `col_pk` int NOT NULL AUTO_INCREMENT,
  `col2` int DEFAULT NULL,
  `col3` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`col_pk`),
  KEY `col2` (`col2`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
1 row in set (0.01 sec)

mysql> select * from t1;
+--------+------+------+
| col_pk | col2 | col3 |
+--------+------+------+
|      1 |   10 | AAA  |
|      6 |   60 | ZZZ  |
+--------+------+------+
2 rows in set (0.00 sec)

この状態でギャップロックをTxAでかけていく

mysql> begin; select * from t1 where col_pk > 3 and col_pk < 5 for update;
Query OK, 0 rows affected (0.00 sec)

Empty set (0.00 sec)

ロックの状態はこう。PK=6とGapロックがかかっている。

mysql> select * from performance_schema.data_locks\G
*************************** 1. row ***************************
               ENGINE: INNODB
       ENGINE_LOCK_ID: 281472607349976:1068:281472493736880
ENGINE_TRANSACTION_ID: 1824
            THREAD_ID: 48
             EVENT_ID: 33
        OBJECT_SCHEMA: mydb
          OBJECT_NAME: t1
       PARTITION_NAME: NULL
    SUBPARTITION_NAME: NULL
           INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 281472493736880
            LOCK_TYPE: TABLE
            LOCK_MODE: IX
          LOCK_STATUS: GRANTED
            LOCK_DATA: NULL
*************************** 2. row ***************************
               ENGINE: INNODB
       ENGINE_LOCK_ID: 281472607349976:2:4:3:281472493733888
ENGINE_TRANSACTION_ID: 1824
            THREAD_ID: 48
             EVENT_ID: 33
        OBJECT_SCHEMA: mydb
          OBJECT_NAME: t1
       PARTITION_NAME: NULL
    SUBPARTITION_NAME: NULL
           INDEX_NAME: PRIMARY
OBJECT_INSTANCE_BEGIN: 281472493733888
            LOCK_TYPE: RECORD
            LOCK_MODE: X,GAP
          LOCK_STATUS: GRANTED
            LOCK_DATA: 6
2 rows in set (0.00 sec)

この状態では 1<PK<5へのINSERTはできない

mysql> insert into t1(col_pk,col2,col3) values (2,20,'AAA');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

PK=6もロックを取るのがMySQLのリピータブルリードの仕様(ファジーリードを防ぐための仕組み)だと思っていたのだが普通にアップデートができてしまった。

mysql> begin; UPDATE t1 SET col3='DDD' WHERE col_pk=6;
Query OK, 0 rows affected (0.01 sec)

Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t1;
+--------+------+------+
| col_pk | col2 | col3 |
+--------+------+------+
|      1 |   10 | AAA  |
|      6 |   60 | DDD  |
+--------+------+------+
2 rows in set (0.00 sec)

PK=6をDELETEしてもギャップが広がるわけではない

mysql> delete from t1 where col_pk = 6;
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1(col_pk,col2,col3) values (7,20,'AAA');
Query OK, 1 row affected (0.01 sec)

追記

教えていただき解決しました!!ありがとうございます!8.0.18での対応

bugs.mysql.com

上記で対応された話ということでした。

【旅行記】秋田旅行

週末に行ってきた。大館市までは大体4.5時間くらいで中距離運転という感じ。2週間で1200kmくらいの運転をした。楽しい。乗っている車が6月で丸10年になる。比較的丁寧に運転しているというのもあって大きな故障とかもなく乗れている。いい車。

鉱山の見学で見つけたやつ。命に関わる分野の場合は手順をきちんと守るの大事だよなぁとなった。

【MySQL】ネクストキーロックとファントムリード

ネクスキーロックとは

MySQLネクスキーロック(Next-Key Lock)は、InnoDBストレージエンジンが使用するロックの一種で、トランザクション処理中のデータの整合性を保つために使用されます。これは、行レベルのロックとギャップロックの組み合わせであり、特定の範囲のレコードに対する他のトランザクションによる挿入を防ぐことが目的です。

softwarenote.info

ファントムリードとは

トランザクションAで一定範囲のレコードに対して処理を行っている途中で、トランザクションBでデータを追加・削除してコミットした場合、トランザクションAで幻影のようにデータが反映されるため、処理の結果が変わってしまう問題のこと。

Repeatable Readのファントムリード

ANSI/ISO SQL標準で定められている分離レベルではリピータブルリードの場合はファントムリードが発生しうる分離レベルとなっている。MySQLのinndbにおいてはこれが発生しない。これは上述しているネクスキーロックの仕組みで実現されている。トランザクションAが処理中にGapとネクストキーをロックしてしまうことでそもそも更新が発生しない。この分離レベルはアカデミックな分野でいうRepeatable Readではない。Snapshot Isolationとかその辺の単語で調べると多くヒットして理解がしやすい。

ja.wikipedia.org

qiita.com

www.infoq.com

【書評】Learning OpenTelemetryを読んだ

OpenTelemetryプロジェクトの共同設立者の一人である「Ted Young」が書いたOpenTelemetryの本。ちょうどOpenTelemetryを導入している時期というのもあってプロジェクトの設立者がどういったことを考えて進めているのかについて興味があったので読んでみた。

github.com

OpenTelemetryの導入までの一冊としても導入した後にさらに知りたい人にも良さそうな本であった。observabilityとはから始まりなぜOpenTelemetryが必要となったのかという背景の説明があったりと「なんとなく理解していたメリット」がこういった立場の方が言語化してくれたおかげで自分の中でもより一層しっくりきた。

特に良かったのは9章の「Chapter 9. Rolling Out Observability」でこの章ではテレメトリが観測可能性の重要な部分である一方で、組織、チーム、またはプロジェクトへの観測可能性の展開に自体が十分であるわけではないことを強調しています。この章は、観測可能性が組織を変革し、ソフトウェアのパフォーマンスがビジネスの健全性にどのように翻訳されるかについての共有言語と理解を提供する能力において真の価値があるという観点から、幅広いターゲットを対象に書かれています。

組織がオブザーバビリティを実装する際の戦略、組織のコミットメント、そして有意義な改善を達成するために単なるデータ収集を超える必要性を強調するための良いガイドとして自身の組織への直ぐに応用できそうと感じました。

以下はChatGPTによる要約

  • 観測可能性はデータ収集だけではなく、ソフトウェアシステムと組織プロセスを理解し改善する価値についてです。
  • 観測可能性を実装するには、プロセス、実践、および意思決定へのデータ使用方法に関する組織全体のコミットメントが必要です。
  • 展開時に検討すべき「観測可能性の3つの軸」を概説しています:深い対広い(システムの特定の部分から詳細な情報を収集するか、システム全体に関する多くのデータを最初に取得するか)、コードの書き換え対収集の書き換え(新しい計測ツールを既存または新しいサービスに追加する努力をするか、既存のデータを新しい形式に変換するか)、集中化対分散化(強力な中央観測可能性チームを作るか、より軽いタッチを使用するか)。
  • 組織が特定のニーズと課題に合わせて観測可能性戦略を調整することの重要性を示す事例研究が提示されています。
  • 明確な目標から始め、最も即座に価値を提供できる場所に努力を集中させ、徐々に組織全体に観測可能性の実践を拡大することの重要性を強調しています。
  • 観測可能性は信頼や透明性と同様の重要な価値観であり、より良いソフトウェアシステムとチームを構築するための手段として提示されています。

ナレッジベースや新旧システムでの移行の話は直ぐにでも取り組めそうなものなのでやっていく