PowerPoint プレゼンテーション

Similar documents
はじめに コースの概要と目的条件分岐の方法や複雑な集計の手法など SQL のコーディングの幅を広げるためのテクニックについて説明します また パフォーマンスを考慮した記述方法や正しい結果を取得するための記述方法などについても あわせて説明します 本コースでは 実践的な SQL の記述手法を広く浅く紹

第 2 章 問合せの基本操作 この章では データベースから情報を検索する際に使用する SELECT コマンド および SELECT コマンドと 同時に使用する句について説明します 1. 問合せとは 2. 基本的な問合せ 3. 列の別名 4. 重複行を一意にする 5. 検索行の絞込み 6. 文字パター

Oracle活用実践演習コース

第 1 章 条件分岐 この章では 条件に応じて処理を分岐する方法について説明します 1. CASE 式で複雑な条件分岐を実現 2. 関数を使用した条件分岐 3. MERGE 文による条件に応じた DML の実行

橡ExCtrlPDF.PDF

PowerPoint プレゼンテーション

プレポスト【問題】

…l…b…g…‘†[…N…v…“…O…›…~…fi…OfiÁŸ_

mysql56_load_r2

橡実践Oracle Objects for OLE

DB12.1 Beta HandsOn Seminar

第 5 章 結合 結合のパフォーマンスに影響を与える結合の種類と 表の結合順序について内部動作を交えて 説明します 1. 結合処理のチューニング概要 2. 結合の種類 3. 結合順序 4. 結合処理のチューニングポイント 5. 結合関連のヒント

アジェンダ ORACLE MASTER Oracle Database 11g 概要 11g SQL 基礎 Ⅰ 試験紹介 ポイント解説 Copyright 2011 Oracle. All rights reserved. 2

Chapter Two

領域サイズの見積方法

Freelance Graphics - Œ³‚è1

目次 1 集計関数 / 分析関数とは 2 集計関数 / 分析関数のパフォーマンス効果 3 ケーススタディグループ小計やクロス集計を計算するランキングを表示する前月比較を表示する累計を計算する移動平均を計算する構成比を計算する Oracle8i SQL Oracle8i Oracle Oracle C

7-1- 基 RDB に関する基礎知識 1 独立行政法人情報処理推進機構

リレーショナルデータベース入門 SRA OSS, Inc. 日本支社 Copyright 2008 SRA OSS, Inc. Japan All rights reserved. 1

1,.,,,., RDBM, SQL. OSS,, SQL,,.

DUCTION はじめての人のための トランザクション入門 TO INTRO- TRANS- 日本 PostgreSQL ユーザ会第 35 回 PostgreSQL 勉強会 2017 年 5 月 27 日 ACTION 坂田哲夫 (NTT OSS センタ ) 1

~~~~~~~~~~~~~~~~~~ wait Call CPU time 1, latch: library cache 7, latch: library cache lock 4, job scheduler co

早分かりS2Dao

内容 Visual Studio サーバーエクスプローラで学ぶ SQL とデータベース操作... 1 サーバーエクスプローラ... 4 データ接続... 4 データベース操作のサブメニューコンテキスト... 5 データベースのプロパティ... 6 SQL Server... 6 Microsoft

Microsoft PowerPoint - db03-5.ppt

Microsoft PowerPoint - 講義補助資料2017.pptx

第 2 章 PL/SQL の基本記述 この章では PL/SQL プログラムの基本的な記述方法について説明します 1. 宣言部 2. 実行部 3. 例外処理部

PHP 分科会 '11/11 OpenSource 協議会 System i 2011/11/25

Microsoft PowerPoint - 3-Forms-Others.ppt

Microsoft PowerPoint pptx

Microsoft Word - Android_SQLite講座_画面800×1280

PA4

Oracle Direct Seminar <Insert Picture Here> 効果的な集計処理ことはじめ 日本オラクル株式会社

PowerPoint Presentation

A Dynamic Mobility Histogram Construction Method Based on Markov Chains

BC4J...4 BC4J Association JSP BC4J JSP OC4J

eラーニング資料 e ラーニングの制作目標 データベース編 41 ページデータベースの基本となる概要を以下に示す この内容のコースで eラーニングコンテンツを作成予定 データベース管理 コンピュータで行われる基本的なデータに対する処理は 次の 4 種類です 新しいデータを追加する 既存のデータを探索

untitled

PostgreSQL SQL チューニング入門 ~ Explaining Explain より ~ 2012 年 11 月 30 日 株式会社アシスト 田中健一朗

1 トランザクション管理

3. XML, DB, DB (AP). DB, DB, AP. RDB., XMLDB, XML,.,,.,, (XML / ), XML,,., AP. AP AP AP 検索キー //A=1 //A=2 //A=3 返却 XML 全体 XML 全体 XML 全体 XMLDB <root> <A

Microsoft PowerPoint - KeySQL50_10g_vlo2.ppt

D1印刷用.PDF

Chapter Two

このドキュメントに記載されている情報 (URL 等のインターネット Web サイトに関する情報を含む ) は 将来予告なしに変更することがあります このドキュメントに記載された内容は情報提供のみを目的としており 明示または黙示に関わらず これらの情報についてマイクロソフトはいかなる責任も負わないもの

Slide 1

_02_3.ppt

Oracle Direct Seminar <Insert Picture Here> 試験対策ポイント解説 11g SQL 基礎 Ⅰ 日本オラクル株式会社

Oracle Application Expressの機能の最大活用-インタラクティブ・レポート

PowerPoint -O80_REP.PDF

Dolteng Scaffoldに対する機能追加とマスタ-ディテールScaffoldの紹介

tkk0408nari

PowerPoint Presentation

Chapter Two

S2Dao入門

<4D F736F F D204F C B838B82C B838B8EE88F878F912E646F6378>

_02-4.ppt

PostgreSQL 9.4 評価検証報告 SRA OSS, Inc. 日本支社高塚遙 :55 ~ 16:30 PostgreSQL 9.4 最新情報セミナー Copyright 2014 SRA OSS, Inc. Japan All rights reserved. 1

,, create table drop table alter table

日本オラクル株式会社

MySQL Server 5.0 Load Data ベンチマーク

データベース 【1:データベースシステムとは】

--

Microsoft PowerPoint - MySQL-backup.ppt

はじめに コースの概要と目的 Oracle をより効率的に使用するための SQL のチューニング方法について説明します また 索引の有無 SQL の 記述方法がパフォーマンスにどのように影響するのかを実習を通して理解します 受講対象者 アプリケーション開発者 / データベース管理者の方 前提条件 S

Microsoft PowerPoint - Lite10g_SyncArchitecture.ppt

Microsoft Word - SQL.rtf

スライド 1

Oracle Database 12cでのSQL*LoaderのExpress Modeによるロード

Windowsユーザーの為のOracle Database セキュリティ入門

MaxGauge_診断分析プロセス

DumpCollection IT Exam Training online / Bootcamp PDF and Testing Engine, study and practice

はじめに 本書では GridDB Advanced Edition における SQL の記述方法および 注意事項について記載しています GridDB Advanced Edition をご使用になる前に 必ずお読みください なお 本書で説明する機能は GridDB Advanced Edition

Oracle 入門 ~ 研修受講後のスキルアップサポート ~ 対応バージョン :Oracle 10gR1 ~ 12cR1 本資料は アシスト Oracle 研修をご受講いただいたお客様からのご質問や 研修ではご案内できなかった情報などを FAQ にまとめたものです 研修受講後のスキルアップの一助とし

Oracle Database 10g Release 2を使用したデータベース・パフォーマンス

第 7 章 ユーザー データ用表領域の管理 この章では 表や索引を格納するユーザー データ用表領域の作成や 作成後のメンテナンスに ついて解説します 1. ユーザー データ用表領域の管理概要 2. ユーザー データ用表領域作成時の考慮事項 3. ユーザー データ用表領域の作成 4. ユーザー データ

Agenda

Wiki Wiki Wiki...

Oracle Database Connect 2017 JPOUG

SRA OSS, Inc. のご紹介 1999 年より PostgreSQL サポートを中心に OSS ビジネスを開始 2005 年に現在の形に至る 主なビジネス PostgreSQL, Zabbix などの OSS のサポート コンサルティング 導入構築 PowerGres ファミリーの開発 販売

以下の事項は 弊社の一般的な製品の方向性に関する概要を説明するものです また 情報提供を唯一の目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ( 確約 ) するものではないため 購買決定を行う際の判断材料になさらな

052-XML04/fiÁ1-part3-’ÓŠ¹

Exam : 1z0-882 日本語 (JPN) Title : Oracle Certified Professional, MySQL 5.6 Developer Vendor : Oracle Version : DEMO 1 / 4 Get Latest & Valid 1z0-882-JP

Chapter Two

標準化 補足資料

1 ex01.sql ex01.sql ; user_id from (select user_id ;) user_id * select select (3+4)*7, SIN(PI()/2) ; (1) select < > from < > ; :, * user_id user_name

橡j_Oracle_whitepaper.PDF

Sequel のすすめ 私が SQL を嫌いな理由 とみたまさひろ RubyHiroba Sequel のすすめ - 私が SQL を嫌いな理由 Powered by Rabbit 2.0.7


復習 (SQL 文 ) 3/6 復習 (SQL 文 ) 4/6 表の作成 CREATE TABLE...; 表の削除 DROP TABLE テーブル名 ; 表内のデータが全て消えてしまう. 表内のデータを得る SELECT 列名 FROM 表名...; 表にデータを挿入する. INSERT INTO

Oracle9i

TopLink å SampleClient.java... 5 Ò readallsample() querysample() cachesample() Ç..

cmpsys13w14-15_database.ppt

Copyright 2018 CO-Sol Inc. All Rights Reserved. 2 自己紹介 + 所属会社紹介 五十嵐一俊 ( いがらしかずとし ) Oracle Exadata の DBA 業務に従事 ORACLE MASTER Platinum 12c 保持 執筆記事 コーソル

Oracle Database から Aurora & Redshift に移行するための実践ガイド

Oracle XML DB によるスケーラビリティおよびパフォーマンス検証 - MML v.3.0

データセンターの効率的な資源活用のためのデータ収集・照会システムの設計

計算機システム概論 システム構成技術 2011/5/11 門林雄基

SQL Server 2012 自習書シリーズ No.16 ロックと読み取り一貫性 Published: 2008 年 5 月 31 日 SQL Server 2012 更新版 : 2012 年 9 月 30 日有限会社エスキューエル クオリティ

pg_monz 監視アイテム一覧 :Template App PostgreSQL Template App PostgreSQL アプリケーション LLD アイテムトリガー監視タイプ更新間隔ヒストリトレンドデフォルト説明ステータス pg.get pgsql.get.pg.bgwriter Zabb

Transcription:

MySQL のロックについて JPOUG> SET EVENTS 20140907 2014/09/07 平塚貞夫 Revision 2 1

自己紹介 DB エンジニアをやっています 専門は Oracle Database と MySQL オープンソースソフトウェアの導入支援をしています 仕事の割合は Oracle:MySQL:PostgreSQL=1:2:7 くらいです Twitter:@sh2nd はてな :sh2 写真は実家で飼っているミニチュアダックスのオス アトムです 2

本日のお題 3

想定外のデッドロック MySQL の InnoDB ストレージエンジンに対して 2 つのトランザクションを以下の順番で実行するとデッドロックが発生します 1:REPEATABLE_READ 2:REPEATABLE_READ 1:UPDATE:DELETE FROM emp WHERE empno = 7784 (1:UPDATE:COUNT=0) 2:UPDATE:DELETE FROM emp WHERE empno = 7786 (2:UPDATE:COUNT=0) 1:UPDATE:INSERT INTO emp (empno, ename) VALUES (7784, 'steve') 2:UPDATE:INSERT INTO emp (empno, ename) VALUES (7786, 'bill') (1:UPDATE:COUNT=1) (2:UPDATE:COUNT=0) (2:com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction) 2:ABORT 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) このデッドロックの発生メカニズムを理解するために InnoDB のロックアーキテクチャについて確認していきます 4

従業員テーブル emp( 従業員 ) テーブルを用いて確認していきます empno( 社員番号 ) ename( 社員名 ) job( 職種 ),mgr( 上司の社員番号 ) hiredate( 入社日 ) sal( 給料 ) comm( 歩合給 ) deptno( 部門番号 ) +-------+--------+-----------+------+------------+---------+---------+--------+ empno ename job mgr hiredate sal comm deptno +-------+--------+-----------+------+------------+---------+---------+--------+ 7369 smith clerk 7902 1980-12-17 800.00 NULL 20 7499 allen salesman 7698 1981-02-20 1600.00 300.00 30 7521 ward salesman 7698 1981-02-22 1250.00 500.00 30 7566 jones manager 7839 1981-04-02 2975.00 NULL 20 7654 martin salesman 7698 1981-09-28 1250.00 1400.00 30 7698 blake manager 7839 1981-05-01 2850.00 NULL 30 7782 clark manager 7839 1981-06-09 2450.00 NULL 10 7788 scott analyst 7566 1987-04-19 3000.00 NULL 20 7839 king president NULL 1981-11-17 5000.00 NULL 10 7844 turner salesman 7698 1981-09-08 1500.00 0.00 30 7876 adams clerk 7788 1987-05-23 1100.00 NULL 20 7900 james clerk 7698 1981-12-03 950.00 NULL 30 7902 ford analyst 7566 1981-12-03 3000.00 NULL 20 7934 miller clerk 7782 1982-01-23 1300.00 NULL 10 +-------+--------+-----------+------+------------+---------+---------+--------+ empno カラムにプライマリインデックス job カラムに非ユニークインデックスを作成してあります 5

InnoDB の設計思想 6

トランザクション処理概念と技法 InnoDB は トランザクション処理概念と技法 という本の内容を参考にして実装されています "The book by Jim Gray and Andreas Reuter, Transaction processing, from about year 1992, is the best reference. Much of InnoDB has been written according to the instructions in that book. - Heikki Tuuri" (http://lists.mysql.com/mysql/107555) 洋書は購入可能です 和書は中古で手に入れるしかないと思います 7

ファントムリード ファントムリードとは 他のトランザクションによって INSERT されたレコードが自分のトランザクションで見えてしまう現象のことです READ COMMITTED の場合にファントムリードが発生する例です 1:READ_COMMITTED 2:READ_COMMITTED 1:QUERY:SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 ORDER BY empno (empno ename job mgr hiredate sal comm deptno ) (7782 clark manager 7839 1981-06-09 2452.00 null 10 ) (7788 scott analyst 7566 1987-04-19 3002.00 null 20 ) (1:QUERY) 2:UPDATE:INSERT INTO emp (empno, ename) VALUES (7785, 'steve') (2:UPDATE:COUNT=1) 2:COMMIT 1:QUERY:SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 ORDER BY empno (empno ename job mgr hiredate sal comm deptno ) (7782 clark manager 7839 1981-06-09 2452.00 null 10 ) (7785 steve null null null null null null ) (7788 scott analyst 7566 1987-04-19 3002.00 null 20 ) (1:QUERY) 8

ファントムリードを防ぐ トランザクション分離レベルの定義によれば ファントムリードは SERIALIZABLE 以外のトランザクション分離レベルで発生する可能性があります 分離レベルダーティリードファジーリードファントムリード READ UNCOMMITTED 可能性あり可能性あり可能性あり READ COMMITTED 発生しない可能性あり可能性あり REPEATABLE READ (InnoDB のデフォルト ) 発生しない 発生しない 可能性あり (InnoDBでは発生しない) SERIALIZABLE 発生しない発生しない発生しない 本書の第 7 章でトランザクション分離性における課題としてファントムリードが挙げられており それに対処するために述語ロック 粒度ロック キー範囲ロック 後方キーロックや前方キーロックといった技法が紹介されています 多くの DBMS がデフォルトのトランザクション分離レベルを READ COMMITTED に設定していますが 本書の内容を参考にして実装された InnoDB は より高いトランザクション分離性を実現することを目指しているように見受けられます 9

ファントムリードを防ぐ例その 1 InnoDB でトランザクション分離レベルが REPEATABLE READ の場合は ファントムリードを防ぐことが可能です なお REPEATABLE READ はファントムリードが発生することを許容していますが DBMS 側の都合により発生しない場合でも定義上の問題はありません 1:REPEATABLE_READ 2:READ_COMMITTED 1:QUERY:SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 ORDER BY empno (empno ename job mgr hiredate sal comm deptno ) (7782 clark manager 7839 1981-06-09 2452.00 null 10 ) (7788 scott analyst 7566 1987-04-19 3002.00 null 20 ) (1:QUERY) 2:UPDATE:INSERT INTO emp (empno, ename) VALUES (7785, 'steve') (2:UPDATE:COUNT=1) 2:COMMIT 1:QUERY:SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 ORDER BY empno (empno ename job mgr hiredate sal comm deptno ) (7782 clark manager 7839 1981-06-09 2452.00 null 10 ) (7788 scott analyst 7566 1987-04-19 3002.00 null 20 ) (1:QUERY) 10

ファントムリードを防ぐ例その 2 SELECT 文に LOCK IN SHARE MODE あるいは FOR UPDATE 句を付与して明示的にロックを取得することができます これをロッキングリードと呼びます REPEATABLE READ でロッキングリードを行うことによっても ファントムリードを防ぐことが可能です この場合は他のトランザクションによる INSERT が待たされます 1:REPEATABLE_READ 2:READ_COMMITTED 1:QUERY:SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 ORDER BY empno LOCK IN SHARE MODE (empno ename job mgr hiredate sal comm deptno ) (7782 clark manager 7839 1981-06-09 2452.00 null 10 ) (7788 scott analyst 7566 1987-04-19 3002.00 null 20 ) (1:QUERY) 2:UPDATE:INSERT INTO emp (empno, ename) VALUES (7785, 'steve') (2:UPDATE:COUNT=0) (2:java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction) 2:ABORT 1:QUERY:SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 ORDER BY empno (empno ename job mgr hiredate sal comm deptno ) (7782 clark manager 7839 1981-06-09 2452.00 null 10 ) (7788 scott analyst 7566 1987-04-19 3002.00 null 20 ) (1:QUERY) 11

MVCC 方式とロック方式 トランザクション分離性を実現する方式として MVCC(Multi-Version Concurrency Control) 方式とロック方式があります MVCC 方式では SELECT 文が共有ロックを取得せず 他のトランザクションによる更新があった場合は UNDO を用いて更新前のデータを見せます ロック方式では先行する SQL 文が共有ロックまたは排他ロックを取得し 他のトランザクションが排他ロックを取得して行う更新を待たせます (1)SELECT (3)SELECT (1)SELECT / DML (2)DML UNDO (2)DML MVCC 方式 ロック方式 12

MVCC 方式とロック方式の使い分け InnoDB が MVCC 方式とロック方式をどのように使い分けているのかを以下に示します REPEATABLE READ 以上でネクストキーロックというものを取得するところ それから SERIALIZABLE で SELECT 文が共有ロックを取得するところが特徴です 分離レベル SELECT LOCK IN SHARE MODE Oracle Database の場合は以下のようになります FOR UPDATE / DML READ COMMITTED 文単位の MVCC 共有レコードロック排他レコードロック REPEATABLE READ トランザクション単位の MVCC 共有ネクストキーロック 排他ネクストキーロック SERIALIZABLE 共有ネクストキーロック共有ネクストキーロック排他ネクストキーロック 分離レベル SELECT LOCK IN SHARE MODE FOR UPDATE / DML READ COMMITTED 文単位の MVCC ( なし ) 排他レコードロック (SET TRANSACTION READ ONLY) SERIALIZABLE トランザクション単位の MVCC トランザクション単位の MVCC ( なし ) ( 禁止 ) ( なし ) 排他レコードロック ( シリアル化エラーあり ) 13

ここまでのまとめ InnoDB は トランザクション処理概念と技法 という本の内容を参考にして実装されており ファントムリードを防ぐことを目指しているように見受けられます ファントムリードを防ぐためには トランザクション単位の MVCC を実行するか あるいはネクストキーロックというものを取得します 14

InnoDB のロックアーキテクチャ 15

テーブルの構造 InnoDB は プライマリインデックスのリーフノードにデータを格納するクラスタインデックス構造を採用しています Oracle Database で言う索引構成表です プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 16

インデックスの構造 プライマリインデックス以外のインデックスのことを セカンダリインデックスと呼びます セカンダリインデックスはリーフノードにプライマリキーの値を格納しており セカンダリインデックスを走査したあとプライマリインデックスを走査することで目的のレコードを取得します セカンダリインデックス プライマリインデックス analyst (7788) manager (7698) manager (7782) president (7839) 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) Oracle Database の場合はインデックスのリーフノードにレコードの物理的な位置を示す ROWID を格納しており インデックスを 2 回走査することはありません

レコードロック InnoDB はインデックス上のレコードをロックすることでレコードロックを行います プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 7788(scott) に対するレコードロック 18

ギャップロック InnoDB ではインデックス上のレコードとレコードの間がロックされることがあります これをギャップロックと呼びます ロック方式でファントムリードを防ぐには 現時点で存在しないレコードをロックする必要があります ギャップロックは存在しないレコードを低コストでロックするために導入された仕組みです プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 7788(scott) の手前に対するギャップロック 19

ネクストキーロック レコードロックとその手前のギャップロックを合わせて ネクストキーロックと呼びます プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 7788(scott) に対するネクストキーロック 20

ロックの範囲 SELECT LOCK IN SHARE MODE SELECT FOR UPDATE や DML を実行すると InnoDB はインデックス上で走査したレコードに対してレコードロック ギャップロックまたはネクストキーロックを取得します 検索条件に合致したレコードに対してではなく 走査したレコードに対してロックを取得するというところが特徴です InnoDB はあくまで MySQL のストレージエンジンであり 検索時にすべての検索条件を把握できているわけではないことが要因の一つだと考えられます 21

ここまでのまとめ InnoDB はクラスタインデックス構造を採用しています インデックス上のレコードをロックすることでレコードロックを行います ファントムリードを防ぐために レコードとレコードの間をロックする仕組みが導入されています インデックス上で走査したレコードに対してロックを取得します 22

REPEATABLE READ におけるロック範囲 23

プライマリインデックスに対する等価検索 SELECT * FROM emp WHERE empno = 7788 FOR UPDATE 以下のロックが取得されます 7788(scott) に対するレコードロック ファントムリードが発生する余地はないため ギャップロックは取得されません プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 24

プライマリインデックスに対する IN 検索 SELECT * FROM emp WHERE empno IN (7782, 7788) FOR UPDATE 以下のロックが取得されます 7782(clark) 7788(scott) に対するレコードロック IN 検索は 等価検索を複数回実行することと同じです プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 25

プライマリインデックスに対する範囲検索 SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 FOR UPDATE 以下のロックが取得されます 7782(clark) に対するレコードロック 7788(scott) 7839(king) に対するネクストキーロック 範囲検索の場合はリーフノードのリスト構造を走査し 7839(king) まで走査して止まります そのため一つ先の 7839(king) に対してもネクストキーロックが取得されます ロックの範囲が広くなることに注意が必要です プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 26

プライマリインデックスに対する範囲検索 + 追加条件 SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 AND ename LIKE '%t' FOR UPDATE 以下のロックが取得されます 7782(clark) に対するレコードロック 7788(scott) 7839(king) に対するネクストキーロック 7782(clark) と 7839(king) は追加条件に合致しませんが ロックは取得されたままとなります プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 27

プライマリインデックスに対する等価検索 空振り SELECT * FROM emp WHERE empno = 7785 FOR UPDATE 以下のロックが取得されます 7788(scott) の手前に対するギャップロック 検索条件に合致した場合はレコードロックが取得されますが 空振りした場合はギャップロックが取得されます ロックの範囲が広くなることに注意が必要です プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 28

プライマリインデックスに対する範囲検索 空振り SELECT * FROM emp WHERE empno BETWEEN 7784 AND 7786 FOR UPDATE 以下のロックが取得されます 7788(scott) に対するネクストキーロック 範囲検索ではリーフノードのリスト構造を走査しますが この場合は 7788(scott) だけを走査して止まります 7788(scott) に対してネクストキーロックが取得されます プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 29

非ユニークインデックスに対する範囲条件 SELECT * FROM emp WHERE job BETWEEN 'analyst' AND 'manager' FOR UPDATE セカンダリインデックスに対する以下のロックが取得されます analyst(7788) manager(7698) manager(7782) president(7839) に対するネクストキーロック プライマリインデックスに対する以下のロックが取得されます 7698(blake) 7782(clark) 7788(scott) に対するレコードロック それぞれのインデックスに対してロックが取得されます セカンダリインデックス プライマリインデックス analyst (7788) manager (7698) manager (7782) president (7839) 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 30

非ユニークインデックスに対する等価条件 SELECT * FROM emp WHERE job = 'manager' FOR UPDATE セカンダリインデックスに対する以下のロックが取得されます manager(7698) manager(7782) に対するネクストキーロック president(7839) の手前に対するギャップロック プライマリインデックスに対する以下のロックが取得されます 7698(blake) 7782(clark) に対するレコードロック 非ユニークインデックスの場合は 等価条件であっても範囲条件に近い挙動となります また 一つ先の president(7839) に対してはネクストキーロックではなくギャップロックが取得されます セカンダリインデックス プライマリインデックス analyst (7788) manager (7698) manager (7782) president (7839) 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 31

非ユニークインデックスに対する等価条件 フルスキャン SELECT * FROM emp IGNORE INDEX (emp_job) WHERE job = 'manager' FOR UPDATE プライマリインデックスに対する以下のロックが取得されます 7698(blake) 7782(clark) 7788(scott) 7839(king) supremum に対するネクストキーロック InnoDB は走査したレコードに対してロックを取得するため SQL 実行計画が変化するとロックの範囲も変化します supremum とは 内部的に設けられている上限値のレコードです プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) supremum 32

ここまでのまとめ プライマリインデックスに対する等価検索の場合は レコードロックが取得されます プライマリインデックスに対する範囲検索の場合は 走査したレコードに対するレコードロックまたはネクストキーロックが取得されます また 一つ先のレコードまで走査します 検索が空振りした場合は ギャップロックまたはネクストキーロックが取得されます 非ユニークインデックスの場合は セカンダリインデックスとプライマリインデックスのそれぞれに対してロックが取得されます また 等価条件であっても範囲条件に近い挙動となります SQL 実行計画が変化するとロックの範囲も変化します 33

READ COMMITTED におけるロック範囲 34

プライマリインデックスに対する範囲検索 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 FOR UPDATE 以下のロックが取得されます 7782(clark) 7788(scott) 7839(king) に対するレコードロック SQL 文の完了時に以下のロックが解放されます 7839(king) に対するレコードロック READ COMMITTED はファントムリードを許容するため ギャップロックは取得されません また 検索条件に合致しなかったレコードに対するロックは SQL 文の完了時に解放されます プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 35

プライマリインデックスに対する範囲検索 + 追加条件 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 AND ename LIKE '%t' FOR UPDATE 以下のロックが取得されます 7782(clark) 7788(scott) 7839(king) に対するレコードロック SQL 文の完了時に以下のロックが解放されます 7782(clark) 7839(king) に対するレコードロック インデックスが関与しない追加条件についても 合致しなかったレコードに対するロックは SQL 文の完了時に解放されます プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 36

トランザクションの順番による挙動の違い 一時的に 7782(clark) 7839(king) に対するレコードロックを取得するため トランザクションの順番によって挙動が変わります 後続トランザクションは 7782(clark) のロックを取得することが可能です 1:READ_COMMITTED 2:READ_COMMITTED 1:QUERY:SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 AND ename LIKE '%t' FOR UPDATE (empno ename job mgr hiredate sal comm deptno ) (7788 scott analyst 7566 1987-04-19 3000.00 null 20 ) (1:QUERY) 2:QUERY:SELECT * FROM emp WHERE empno = 7782 FOR UPDATE (empno ename job mgr hiredate sal comm deptno ) (7782 clark manager 7839 1981-06-09 2450.00 null 10 ) (2:QUERY) 一方 7782(clark) のロックを取得している先行トランザクションがあると待たされます 2:READ_COMMITTED 1:READ_COMMITTED 2:QUERY:SELECT * FROM emp WHERE empno = 7782 FOR UPDATE (empno ename job mgr hiredate sal comm deptno ) (7782 clark manager 7839 1981-06-09 2450.00 null 10 ) (2:QUERY) 1:QUERY:SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7788 AND ename LIKE '%t' FOR UPDATE (1:QUERY) (1:java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction) 1:ABORT 37

プライマリインデックスに対する等価検索 空振り SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT * FROM emp WHERE empno = 7785 FOR UPDATE ロックは取得されません プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 38

プライマリインデックスに対する範囲検索 空振り SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED SELECT * FROM emp WHERE empno BETWEEN 7784 AND 7786 FOR UPDATE ロックは取得されません プライマリインデックス 7698 (blake) 7782 (clark) 7788 (scott) 7839 (king) 39

ここまでのまとめ READ COMMITTED の場合は ギャップロックは取得されません 走査したレコードに対するレコードロックが取得されますが 検索条件に合致しなかったレコードに対するロックは SQL 文の完了時に解放されます 検索が空振りした場合は ロックは取得されません 40

調査方法 41

InnoDB ロックモニタ MySQL 5.6.16 以降でパラメータ innodb_status_output_locks を有効にすると SHOW ENGINE INNODB STATUS コマンドでロックの状態を確認できます この機能のことを InnoDB ロックモニタと呼びます SET GLOBAL innodb_status_output_locks = ON SHOW ENGINE INNODB STATUS 実行例を以下に示します SELECT * FROM emp WHERE empno BETWEEN 7698 AND 7782 OR empno = 7835 FOR UPDATE 7835 は空振り RECORD LOCKS space id 342 page no 3 n bits 88 index `PRIMARY` of table `scott`.`emp` trx id 1857327 lock_mode X locks rec but not gap 7698(blake) に対するレコードロック Record lock, heap no 7 PHYSICAL RECORD: n_fields 10; compact format; info bits 0 0: len 4; hex 80001e12; asc ;; 10 進数で7698 RECORD LOCKS space id 342 page no 3 n bits 88 index `PRIMARY` of table `scott`.`emp` trx id 1857327 lock_mode X 7782(clark) と7788(scott) に対するネクストキーロック Record lock, heap no 8 PHYSICAL RECORD: n_fields 10; compact format; info bits 0 0: len 4; hex 80001e66; asc f;; 10 進数で7782 Record lock, heap no 9 PHYSICAL RECORD: n_fields 10; compact format; info bits 0 0: len 4; hex 80001e6c; asc l;; 10 進数で7788 RECORD LOCKS space id 342 page no 3 n bits 88 index `PRIMARY` of table `scott`.`emp` trx id 1857327 lock_mode X locks gap before rec 7839(king) の手前に対するギャップロック Record lock, heap no 10 PHYSICAL RECORD: n_fields 10; compact format; info bits 0 0: len 4; hex 80001e9f; asc ;; 10 進数で7839 42

本日のお題 ( 再 ) 43

デッドロックの発生メカニズム 1. TX1 の DELETE 文が空振りし 7788(scott) の手前のギャップロックを取得します 1:UPDATE:DELETE FROM emp WHERE empno = 7784 7698 (blake) 7782 (clark) 2. TX2 の DELETE 文が空振りし 7788(scott) の手前のギャップロックを取得します なおギャップロック同士は競合しません 2:UPDATE:DELETE FROM emp WHERE empno = 7786 7788 (scott) 7839 (king) 3. TX1 の INSERT 文が 7788(scott) の手前のギャップに対して挿入インテンションギャップロックの取得を試み TX2 のギャップロックと競合します 挿入インテンションギャップロックとは INSERT 文の実行時に取得される特殊なギャップロックです 挿入インテンションギャップロック同士は競合せず 通常のギャップロックと競合します 1:UPDATE:INSERT INTO emp (empno, ename) VALUES (7784, 'steve') 4. TX2 の INSERT 文が 7788(scott) の手前のギャップに対して挿入インテンションギャップロックの取得を試み TX1 のギャップロックと競合してデッドロックが発生します 2:UPDATE:INSERT INTO emp (empno, ename) VALUES (7786, 'bill') 44

宿題 対処方法を考えてみてください 45