Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

外部キー制約に伴うロックの小話

22.239 visualizaciones

Publicado el

mysql,innodb,foreign key

Publicado en: Ingeniería
  • Hi there! I just wanted to share a list of sites that helped me a lot during my studies: .................................................................................................................................... www.EssayWrite.best - Write an essay .................................................................................................................................... www.LitReview.xyz - Summary of books .................................................................................................................................... www.Coursework.best - Online coursework .................................................................................................................................... www.Dissertations.me - proquest dissertations .................................................................................................................................... www.ReMovie.club - Movies reviews .................................................................................................................................... www.WebSlides.vip - Best powerpoint presentations .................................................................................................................................... www.WritePaper.info - Write a research paper .................................................................................................................................... www.EddyHelp.com - Homework help online .................................................................................................................................... www.MyResumeHelp.net - Professional resume writing service .................................................................................................................................. www.HelpWriting.net - Help with writing any papers ......................................................................................................................................... Save so as not to lose
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Follow the link, new dating source: ❶❶❶ http://bit.ly/2Qu6Caa ❶❶❶
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Sex in your area is here: ❶❶❶ http://bit.ly/2Qu6Caa ❶❶❶
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí

外部キー制約に伴うロックの小話

  1. 1. 外部キー制約に伴う ロックの小話 2015/2/13 「外部キー Night」 @ichirin2501(いちりんちゃん) 1
  2. 2. はじめに 2 検証環境 ・MySQL 5.5.28 ・ストレージエンジン InnoDB ・トランザクション分離レベル REPEATABLE-READ, READ-COMMITTED ! 時間の都合上インデックスの話は割愛
  3. 3. スライドの内容 ロックおさらい
 ・共有と排他ロックについて
 ・共有と排他ロックの順序によるデッドロック例 外部キー制約に伴うロックの挙動について
 ・基本的なロックのかかり方
 ・シャドーロックの紹介(注意)
 ・シャドーロックによる外部キー制約時の影響 3
  4. 4. ロックおさらい(簡易) • 共有ロック(LOCK_S)
 共有ロック同士は互いにブロックしない
 例:SELECT LOCK IN SHARE MODE • 排他ロック(LOCK_X)
 何も受け付けないぞ、排他
 例:INSERT(成功), UPDATE, DELETE,
  SELECT FOR UPDATE X S X Conflict Conflict S Conflict Compatible 4 大きく分けてロックは2種類
  5. 5. 5 > BEGIN; > SELECT * FROM player
  WHERE id = 100
  LOCK IN SHARE MODE; > BEGIN; トランザクションA トランザクションB 共有と排他順によるデッドロック例
  6. 6. 6 > BEGIN; > SELECT * FROM player
  WHERE id = 100
  LOCK IN SHARE MODE; > BEGIN; > SELECT * FROM player WHERE id = 100 FOR UPDATE; Player.id(100)に
 共有ロックが取られてるため、
 待たされる トランザクションA トランザクションB 共有と排他順によるデッドロック例 待たされる
  7. 7. 7 > BEGIN; > SELECT * FROM player
  WHERE id = 100
  LOCK IN SHARE MODE; > BEGIN; > SELECT * FROM player WHERE id = 100 FOR UPDATE; > SELECT * FROM player WHERE id = 100 FOR UPDATE; DeadLock !!! Player.id(100)に
 共有ロックが取られてるため、
 待たされる排他->共有ロックなら デッドロックにならない トランザクションA トランザクションB 共有と排他順によるデッドロック例 待たされる
  8. 8. 外部キー制約によるロック (基本編) 8 簡単に検証 1. 外部キー制約の共有ロックを確認 2. 共有->排他順によるデッドロック例
 (外部キー制約ver) これだけは押さえておく ・INSERT時に外部キー制約される側(親)に
  共有ロックがかかる
  9. 9. テーブル定義の例 key Extra id PRIMARY AUTO-INCR player KEY-INDEX item KEY-INDEX key Extra id PRIMARY AUTO-INCR key Extra id PRIMARY Player Item PlayerItem 外部キー制約する側(子) 9 外部キー制約される側(親)
  10. 10. > BEGIN; > INSERT INTO player_item
 (player,item) VALUES(100, 2000); > BEGIN; トランザクションA トランザクションB 10 外部キー制約により、
 Player.id(100), Item.id(2000)
 に対して共有ロックを獲得 外部キーで共有ロックがかかるのを確認 >
  11. 11. > BEGIN; > INSERT INTO player_item
 (player,item) VALUES(100, 2000); > BEGIN; > SELECT * FROM player WHERE id = 100 FOR UPDATE; トランザクションA トランザクションB 11 外部キー制約により、
 Player.id(100), Item.id(2000)
 に対して共有ロックを獲得 Player.id(100)に
 共有ロックが取られてるため、
 待たされる 外部キーで共有ロックがかかるのを確認 > 待たされる
  12. 12. 12 > BEGIN; > BEGIN; > UPDATE player SET XXX = YYY WHERE id = 100; DeadLock !!! 共有->排他順によるデッドロック例(外部キーver) トランザクションA トランザクションB > INSERT INTO player_item
 (player,item) VALUES(100, 2000); > SELECT * FROM player WHERE id = 100 FOR UPDATE; Player.id(100)に
 共有ロックが取られてるため、
 待たされる 待たされる
  13. 13. 外部キー制約によるロック (シャドーロック編) • シャドーロックとは
 クエリが待たされたときなどでも
 部分的にロックを獲得する現象のこと • 注意:私が勝手に呼んでるロック現象です • 外部キーに関わらず、IN, BETWEENなど
 複数行ロックするようなクエリの場合にも発生
 (今回は外部キー制約に伴う部分のみを紹介) 13
  14. 14. 部分的にロックを取ってしまう原因 InnoDBのINSERTの挙動(簡易) 14 1. テーブルロック確認 2. インデックスを順番に作成 3. 外部キー制約なら共有ロック 4. 他TXからロックの影響確認と
 同時にロック(uniq制限チェックなど諸々) 5. インデックス作成完了 待たされるポイント 各々の処理でロックを 確定してしまう => シャドーロックになる => インデックス定義依存
  15. 15. 同じクエリで検証してみる key Extra id PRIMARY AUTO-INCR player KEY-INDEX item KEY-INDEX PlayerItem CREATE TABLE `player_item` ( … KEY `idx_item` (`item`), KEY `idx_player` (`player`), … ); 15 CREATE TABLE `player_item` ( … KEY `idx_player` (`player`), KEY `idx_item` (`item`), … ); case1 case2 item,playerは外部キー 同じクエリで検証 case1: item -> player のindex順 case2: player -> item のindex順
  16. 16. > BEGIN; > SELECT * FROM player
 WHERE id = 100 FOR UPDATE; > BEGIN; トランザクションA トランザクションB 16 case1:item -> player の順でindex定義
  17. 17. > BEGIN; > SELECT * FROM player
 WHERE id = 100 FOR UPDATE; > BEGIN; > INSERT INTO player_item
 (player,item) VALUES(100,2000); トランザクションA トランザクションB 17 • Player.id(100)に排他ロックが
 取られてるため待たされる • シャドーロックでitem.id(2000)に
 対して共有ロック獲得済み case1:item -> player の順でindex定義 待たされる
  18. 18. > BEGIN; > SELECT * FROM player
 WHERE id = 100 FOR UPDATE; > BEGIN; > INSERT INTO player_item
 (player,item) VALUES(100,2000); トランザクションA トランザクションB 18 • Player.id(100)に排他ロックが
 取られてるため待たされる • シャドーロックでitem.id(2000)に
 対して共有ロック獲得済み case1:item -> player の順でindex定義 待たされる > SELECT * FROM item
 WHERE id = 2000 FOR UPDATE; DeadLock !!!
  19. 19. > BEGIN; > SELECT * FROM player
 WHERE id = 100 FOR UPDATE; > BEGIN; 19 case2:player -> item の順でindex定義 トランザクションA トランザクションB
  20. 20. > BEGIN; > SELECT * FROM player
 WHERE id = 100 FOR UPDATE; > BEGIN; > INSERT INTO player_item
 (player,item) VALUES(100,2000); 20 • Player.id(100)に排他ロックが
 取られてるため待たされる • item.id(2000)に対しては
 共有ロックを取ってない
 (取る前にPlayer.idで止まった) case2:player -> item の順でindex定義 トランザクションA トランザクションB 待たされる
  21. 21. > BEGIN; > SELECT * FROM player
 WHERE id = 100 FOR UPDATE; > BEGIN; > INSERT INTO player_item
 (player,item) VALUES(100,2000); > SELECT * FROM item
 WHERE id = 2000 FOR UPDATE; 21 > 待たされない! • Player.id(100)に排他ロックが
 取られてるため待たされる • item.id(2000)に対しては
 共有ロックを取ってない
 (取る前にPlayer.idで止まった) case2:player -> item の順でindex定義 トランザクションA トランザクションB 待たされる
  22. 22. 補足:ロックは食いつく 22 検証 ・INSERTでDuplicateEntryになったときの
  ロック獲得状況の確認 ちなみに、DuplicateEntry時など
 失敗したら共有ロックになることが知られている
 (成功時は排他ロック)
  23. 23. Uniq制限のあるテーブル定義 key Extra id PRIMARY token UNIQ-INDEX item KEY-INDEX PlayerToken 外部キー制約する側(子) 23 CREATE TABLE `player_token` ( … PRIMARY KEY (`id`), UNIQUE KEY `idx_token` (`token`), KEY `idx_item` (`item`), … ); idがplayer.idの外部キー itemがitem.idの外部キー id -> token -> itemのindex順
  24. 24. > BEGIN; > INSERT INTO player_token (id,item,token) VALUES (100,1000, ABCD ); > BEGIN; トランザクションA 24 トランザクションB INSERTでDuplicateEntryになったとき >
  25. 25. > BEGIN; > INSERT INTO player_token (id,item,token) VALUES (100,1000, ABCD ); > BEGIN; > INSERT INTO player_token
 (id,item,token) VALUES (200,2000, ABCD ); トランザクションA 25 トランザクションB シャドーロックでPlayer.id(200)
 の共有ロックは獲得済み。
 Item.id(2000)の前にtokenの
 uniq制限でひっかかる INSERTでDuplicateEntryになったとき 待たされる > id -> token -> itemのindex順
  26. 26. > BEGIN; > INSERT INTO player_token (id,item,token) VALUES (100,2000, ABCD ); > BEGIN; > INSERT INTO player_token
 (id,item,token) VALUES (200,2000, ABCD ); > COMMIT; トランザクションA 26 トランザクションB > (Duplicate Entry ) > DuplicateEntryになったものの、
 トランザクションが解除されたわけ
 ではない。Player.id(200)の 共有ロックは獲得済み INSERTでDuplicateEntryになったとき id -> token -> itemのindex順
  27. 27. > BEGIN; > INSERT INTO player_token (id,item,token) VALUES (100,2000, ABCD ); > BEGIN; > INSERT INTO player_token
 (id,item,token) VALUES (200,2000, ABCD ); > COMMIT; トランザクションA, A 27 トランザクションB > BEGIN; > (Duplicate Entry ) > DuplicateEntryになったものの、
 トランザクションが解除されたわけ
 ではない。Player.id(200)の 共有ロックは獲得済み INSERTでDuplicateEntryになったとき > SELECT * FROM item WHERE id = 2000 FOR UPDATE; id -> token -> itemのindex順
  28. 28. > BEGIN; > INSERT INTO player_token (id,item,token) VALUES (100,2000, ABCD ); > BEGIN; > INSERT INTO player_token
 (id,item,token) VALUES (200,2000, ABCD ); > COMMIT; トランザクションA, A 28 トランザクションB > BEGIN; > SELECT * FROM player WHERE id = 200 FOR UPDATE; > (Duplicate Entry ) > DuplicateEntryになったものの、
 トランザクションが解除されたわけ
 ではない。Player.id(200)の 共有ロックは獲得済み INSERTでDuplicateEntryになったとき > SELECT * FROM item WHERE id = 2000 FOR UPDATE; 待たされる id -> token -> itemのindex順
  29. 29. まとめ • 共有->排他のロック順はデッドロックの原因 • 外部キー制約があるとINSERT時に親に共有ロック • クエリが待たされてる状態でも
 部分的にロックは獲得される(シャドーロック) • 外部キー制約の共有ロック順序はテーブル定義依存 • 外部キー制約を付けるならINSERT前に排他ロック 29

×