14.5.3 Locks Set by Different SQL Statements in InnoDB
生活随笔
收集整理的這篇文章主要介紹了
14.5.3 Locks Set by Different SQL Statements in InnoDB
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
14.5.3 Locks Set by Different SQL Statements in InnoDB通過不同的SQL語句設(shè)置的鎖 在InnoDB中一個(gè)鎖定讀, 一個(gè)UPDATE 或者一個(gè)DELETE 通常設(shè)置record locks 在每個(gè)Index record 他不管是否有WHERE 條件在與距離 會(huì)排除記錄。InnoDB 不記住準(zhǔn)確的WHERE 條件, 只是知道哪個(gè)index range 是被掃描。locks通常是 next-key locks 也堵塞inserts 到"gap" 在那個(gè)記錄前。然而,區(qū)間鎖可以顯示的關(guān)閉,這將導(dǎo)致 next-key locking不能被使用如果一個(gè)secondary index 是用于一個(gè)搜索,index record locks 會(huì)被設(shè)置為排他。InnoDB 也會(huì)檢索相應(yīng)的clustered index records 在它們上面設(shè)置鎖如果你沒有合適的索引用于你的語句,MySQL 必須掃描整個(gè)表來處理語句,表的每行記錄都會(huì)被鎖定,從而阻止其他用于所有的插入到這個(gè)表。創(chuàng)建好的索引是重要的,這樣你的查詢不會(huì)掃描很多的記錄對(duì)于SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE, 鎖是需要的對(duì)于掃描的記錄期望被釋放對(duì)于記錄不符合納入結(jié)果集的( 比如,如果你不滿足給定的WHERE 條件的標(biāo)準(zhǔn)).然而, 在一些例子中,記錄可能不會(huì)被立即鎖定 因?yàn)橐粋€(gè)結(jié)果集和他的原始資料的關(guān)系是丟失了再查詢執(zhí)行時(shí)。比如,在一個(gè)UNION 掃描的(被鎖定的)的記錄從一個(gè)表可能會(huì)被插入到一個(gè)臨時(shí)表 InnoDB 設(shè)置鎖的特定類型:1.SELECT ... FROM 是一個(gè)一致性讀, 從數(shù)據(jù)庫讀取快照 沒有設(shè)置鎖除非事務(wù)隔離是設(shè)置為SERIALIZABLE對(duì)于SERIALIZABLE level,搜索設(shè)置共享的next-key locks 在index records.然而,只有Index record lock 是需要的 用于語句 鎖定記錄使用一個(gè)unique index 來搜索唯一行2.SELECT ... FROM ... LOCK IN SHARE MODE 設(shè)置共享next-key locks 在所有的搜索遇到的index 記錄。然而, 只有一個(gè)index record lock 是需要的用于語句 鎖定記錄使用一個(gè)unique index 來搜索唯一的記錄3.SELECT ... FROM ... FOR UPDATE 設(shè)置一個(gè)排他的 next-key lock 在每條搜索遇到的記錄。然而, 只有一個(gè)Index record lock 是需要的用于語句 locks rows 使用一個(gè)唯一索引來搜搜唯一的記錄4.對(duì)于搜搜遇到的index records,SELECT ... FROM ... FOR UPDATE 堵塞其他會(huì)話 執(zhí)行SELECT ... FROM ... LOCK IN SHARE MODE或者 在某些事物蛤蜊級(jí)別。一致性讀 會(huì)忽略任何鎖定5.UPDATE ... WHERE ... 設(shè)置一個(gè)排他的e next-key lock 在每個(gè)記錄。然而, 只有一個(gè)Index record 鎖是需要的用于語句當(dāng)locks row 是使用一個(gè)唯一索引來進(jìn)行唯一搜索6.當(dāng)UPDATE 協(xié)議一個(gè)clustered index record, 隱式的鎖是被設(shè)置影響secondary index records.UPDATE 操作也會(huì)設(shè)置shared locks 在影響的secondary index records 當(dāng)執(zhí)行重復(fù)的檢查掃描7.DELETE FROM ... WHERE ... 設(shè)置一個(gè)排他的 next-key lock 在每個(gè)搜索遇到的記錄然而,只有一個(gè)index record lock 是需要的用于語句 lock rows 使用一個(gè)唯一索引來搜索一個(gè)唯一的記錄8.在插入行之前,一種區(qū)間鎖類型被稱為insert intention gap lock 被設(shè)置。lock 表明意向插入以這種方式多個(gè)事務(wù)插入到相同的index gap 不需要相互等待如果他們不是插入相同的位置。假設(shè)有index record 值為4和7,單獨(dú)的事務(wù)嘗試插入值5和6 每個(gè)lock 區(qū)間在4和7 使用插入意向鎖來得到排他鎖在插入的記錄,但是不會(huì)相互堵塞 因?yàn)橛涗浭遣粵_突的如果一個(gè)重復(fù)的key錯(cuò)誤發(fā)生,一個(gè)共享鎖在重復(fù)的index上被設(shè)置。這個(gè)共享的鎖可以導(dǎo)致死鎖 有多個(gè)會(huì)話嘗試插入相同的記錄 如果另外的會(huì)話已經(jīng)有一個(gè)排他鎖。這個(gè)可以發(fā)生如果另外的會(huì)話刪除記錄 ,假設(shè)一個(gè)InnoDB 表t1 有下面的結(jié)構(gòu):CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;現(xiàn)在假設(shè)有3個(gè)會(huì)話執(zhí)行下面操作按順序:Session 1: START TRANSACTION;
INSERT INTO t1 VALUES(1);Session 2:START TRANSACTION;
INSERT INTO t1 VALUES(1); --hangSession 3: START TRANSACTION;
INSERT INTO t1 VALUES(1);Session 1: ROLLBACK;Session 1的第一個(gè)操作 需要的排他鎖用于記錄,session 2和session 3 都導(dǎo)致一個(gè)重復(fù)鍵錯(cuò)誤 他們都請(qǐng)求一個(gè)共享鎖用于記錄。當(dāng)session 1回滾, 它釋放他的排他鎖在記錄上 共享鎖請(qǐng)求對(duì)于session 2和3 是被授予。在這個(gè)時(shí)間點(diǎn),sessions 2 and 3 deadlock: 兩者都不能獲得一個(gè)排他鎖用于記錄 因?yàn)楣蚕礞i被其他持有類似的情況發(fā)生 如果表已經(jīng)包含一個(gè)只為1 ,然后3個(gè)會(huì)話執(zhí)行相同的操作:mysql> select * from t1;
+---+
| i |
+---+
| 1 |
+---+
1 row in set (0.00 sec)Session 1: START TRANSACTION;
DELETE FROM t1 WHERE i = 1;
Session 2: START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 3: START TRANSACTION;
INSERT INTO t1 VALUES(1);
Session 1: COMMIT;首先session 1 操作需要一個(gè)排他鎖用于記錄。 session 2 和session 3 操作都導(dǎo)致一個(gè)重復(fù)鍵錯(cuò)誤他們都請(qǐng)求記錄的排他鎖。當(dāng)session 1提交, 他釋放他的排他鎖在記錄上 session 2和session 3請(qǐng)求的共享鎖被授權(quán)。在這個(gè)時(shí)間點(diǎn),session 2和session 3死鎖兩者都不能獲得一個(gè)排他鎖對(duì)于記錄 因?yàn)楣蚕礞i被另外一個(gè)人持有1.?INSERT ... ON DUPLICATE KEY UPDATE 不同一個(gè)簡單的插入 一個(gè)排他next-key lock 而不是一個(gè)共享鎖2.REPLACE 是像一個(gè)INSERT 如果沒有沖突在一個(gè)唯一鍵。否則,一個(gè)排他的next-key lock是放置在replaces 的記錄上3.INSERT INTO T SELECT ... FROM S WHERE ... 設(shè)置一個(gè)排他鎖 record lock(沒有間隙鎖) 在每個(gè)插入的記錄。如果事務(wù)隔離級(jí)別是READ COMMITTED,或者 innodb_locks_unsafe_for_binlog 是被啟用的 且事務(wù)隔離級(jí)別不是SERIALIZABLE,CREATE TABLE ... SELECT ... 執(zhí)行SELECT YOU shared next-key locks或者作為一個(gè)一致性讀,和 INSERT ... SELECT. 當(dāng)初始化一個(gè)先前指定的 AUTO_INCREMENT 列在一個(gè)表上,InnoDB 設(shè)置一個(gè)排他鎖在 索引相關(guān)自增列的尾部。
轉(zhuǎn)載于:https://www.cnblogs.com/zhaoyangjian724/p/6199050.html
總結(jié)
以上是生活随笔為你收集整理的14.5.3 Locks Set by Different SQL Statements in InnoDB的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: String类型的学习
- 下一篇: SQL Server中的SQL语句优化与