最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文掌握MySQL唯一索引是如何加鎖的

 更新時間:2024年06月11日 10:16:52   作者:qxlxi  
這篇文章主要介紹了一文掌握MySQL唯一索引是如何加鎖的,本案例其實就是在主鍵索引上進行等值查詢,取決于查詢記錄是否存在,存在退化成記錄鎖,否則就是在索引樹中找到第一個大于該查詢記錄的記錄后,將改記錄的索引中的next-key lock退換成間隙鎖,需要的朋友可以參考下

首先我們要明確,加鎖的對象是索引,加鎖的基本單位是next-key lock,由記錄鎖和間隙鎖組成。next-key是前開后閉區(qū)間,間隙鎖是前開后開區(qū)間。根據(jù)不同的查詢條件next-key 可能會退化成記錄鎖或間隙鎖。

在能使用記錄鎖或者間隙鎖就能避免幻讀現(xiàn)象的場景下, next-key lock 就會退化成記錄鎖或間隙鎖。

數(shù)據(jù)準備

CREATE TABLE user (
id bigint NOT NULL AUTO_INCREMENT,
name varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
age int NOT NULL,
PRIMARY KEY (id),
KEY index_age (age) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

在這里插入圖片描述

唯一索引等值查詢

本案例其實就是在主鍵索引上進行等值查詢,取決于查詢記錄是否存在,存在退化成記錄鎖,否則就是在索引樹中找到第一個大于該查詢記錄的記錄后,將改記錄的索引中的next-key lock退換成間隙鎖。

記錄存在

當執(zhí)行如下 id=1的鎖,會給id=1的記錄jiashangX型的記錄鎖

BEGIN;
SELECT * from user where id = 1 for update;

在這里插入圖片描述

可以發(fā)現(xiàn)對,id=1的記錄加了記錄鎖。update user set age = 25 where id = 1; DELETE FROM user WHERE id = 1; 語句都會被阻塞。

圖中 LOCK_TYPE 中的 RECORD 表示行級鎖,而不是記錄鎖的意思
通過 LOCK_MODE 可以確認是 next-key 鎖,還是間隙鎖,還是記錄鎖:
如果 LOCK_MODE 為 X,說明是next-key 鎖;
如果 LOCK_MODE 為 X, REC_NOT_GAP,說明是記錄鎖;
如果 LOCK_MODE 為 X,GAP,說明是間隙鎖;

這里簡單聊下,為什么唯一索引下等值查詢就可以將next-key lock退化成記錄鎖,因為對指定行的操作加鎖,可以直接避免其他事務(wù)對該行的刪除、插入的時候,就可以避免幻讀問題。

在這里插入圖片描述

記錄不存在

好了上面主要說的是針對記錄存在,針對記錄不存在的唯一索引添加鎖。

BEGIN;
SELECT * from user where id = 2 for update;

在這里插入圖片描述

當LOCK_MODE是間隙鎖或者Next-key LOCK時,LOCK_DATA代表的就是鎖的右邊界,鎖的左邊界就是表中id為5的上一條記錄的id值,也就是1,所以本次間隙鎖的范圍就是(1,5)。當執(zhí)行INSERT INTOtest.user (id, name, age) VALUES (3, 'zhangsan2', 21); 會獲取鎖失敗,阻塞。

這里由一個疑問就是為什么唯一索引記錄不存在的情況下,會從next-key lock退化成間隙鎖。
其實這種情況僅靠間隙鎖就能解決?;米x的問題。
為什么不可以針對不存在的記錄加記錄鎖,鎖是加在索引上的,記錄不存在,自然沒辦法鎖住這條不存在的記錄。

唯一索引范圍查詢

針對唯一索引范圍查詢,會對掃描到的索引加next-key鎖

大于或者大于等于的范圍查詢

情況1:針對大于等于的范圍查詢,存在等值條件,那么該記錄索引中的next-key 退化成記錄鎖。

BEGIN;
SELECT * from user where id > 15  for update;

在這里插入圖片描述

1.首先找到的是id=20這一行,然后對該(15,20] 添加間隙鎖。
2.由于是范圍查詢,innodb存儲引擎中,有特殊的記錄標識最后一條記錄。supremum pseudo-record 所以掃描第二行的時候加的是(20,+8]的next- key
當對 16 17 18 19 20 以及20以上的記錄進行刪除 更新 插入操作時,會被阻塞。

>=情況

BEGIN;
SELECT * from user where id >= 15  for update;

在這里插入圖片描述

從圖中可以看到加了三個鎖,由于可以定位到id=15這樣記錄,所以針對ID=15的記錄添加的就是記錄鎖,而接著掃描的就是20這行記錄,對(15,20] 加間隙鎖,(20,+8)加間隙鎖。

從本案例中可以獲取當大于等于時,如果有等于就會針對等于的記錄加記錄鎖。

小于或者小于等于的范圍查詢

BEGIN;
SELECT * from user where id < 6  for update;

在這里插入圖片描述

針對「小于或者小于等于」的唯一索引范圍查詢,如果條件值的記錄不在表中,那么不管是「小于」還是「小于等于」的范圍查詢,掃描到終止范圍查詢的記錄時,該記錄中索引的 next-key 鎖會退化成間隙鎖,其他掃描的記錄,則是在這些記錄的索引上加 next-key 鎖。

< 情況

BEGIN;
SELECT * from user where id < 5  for update;

在這里插入圖片描述

非唯一索引等值查詢

對非唯一索引進行等值查詢的時候,因為存在兩個索引,一個是主鍵索引,一個是二級索引。所以在加鎖時,同時對這兩個索引都加鎖。但是對主鍵索引加鎖的時候,只有滿足查詢條件的記錄才會對主鍵索引加鎖。
非唯一性 二級索引、主鍵索引都加鎖
主鍵索引查詢 只針對主鍵索引加鎖

沒有加索引的查詢

如果鎖定讀查詢語句,沒有使用索引列作為查詢條件,或者查詢語句沒有走索引查詢,導(dǎo)致掃描是全表掃描。那么,每一條記錄的索引上都會加 next-key 鎖,這樣就相當于鎖住的全表,這時如果其他事務(wù)對該表進行增、刪、改操作的時候,都會被阻塞。

update和delete語句如果查詢條件不加索引,掃描方式也是全表掃描,對每一條記錄加next-key 鎖,相當于鎖住的全表。

BEGIN;
SELECT * from user where name = 'qxlxi'  for update;
update user set age = age + 1 WHERE name = 'qxlxi';
DELETE FROM user WHERE name = 'qxlxi';
select * from performance_schema.data_locks;

在這里插入圖片描述

在線上在執(zhí)行 update、delete、select … for update 等具有加鎖性質(zhì)的語句,一定要檢查語句是否走了索引,如果是全表掃描的話,會對每一個索引加 next-key 鎖,相當于把整個表鎖住了

小結(jié)

本篇主要從實操方面介紹是如何針對不同的查詢條件進行加鎖。當查詢條件是主鍵索引、普通索引 會出現(xiàn)各種不同的情況,但是總體上其實主要解決的就是通過next-key lock、gap lock,record lock,取避免可能出現(xiàn)幻讀的情況。

原則 1:加鎖的基本單位是 next-key lock,next-key lock 是前開后閉區(qū)間。
原則 2:查找過程中訪問到的對象才會加鎖。
優(yōu)化 1:索引上的等值查詢,給唯一索引加鎖的時候,next-key lock 退化為行鎖。
優(yōu)化 2:索引上的等值查詢,向右遍歷時且最后一個值不滿足等值條件的時候,next-key lock 退化為間隙鎖。
一個 bug:唯一索引上的范圍查詢會訪問到不滿足條件的第一個值為止。

到此這篇關(guān)于一文掌握MySQL唯一索引是如何加鎖的的文章就介紹到這了,更多相關(guān)MySQL唯一索引加鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql在項目中怎么選事務(wù)隔離級別

    mysql在項目中怎么選事務(wù)隔離級別

    Mysql默認的事務(wù)隔離級別是可重復(fù)讀,那互聯(lián)網(wǎng)項目中Mysql也是用默認隔離級別,但在項目中呢,下面我們就一起來了解一下
    2021-05-05
  • MySQL中給字段添加唯一約束的方式匯總

    MySQL中給字段添加唯一約束的方式匯總

    唯一約束是 MySQL 中用于限制字段的值不能重復(fù)的一種約束,它能保證數(shù)據(jù)表中指定字段的唯一性,防止重復(fù)數(shù)據(jù)插入,從而保障數(shù)據(jù)的有效性,本文給大家介紹了MySQL中給字段添加唯一約束的方式,需要的朋友可以參考下
    2025-12-12
  • Mysql中 unique列插入重復(fù)值該怎么解決呢

    Mysql中 unique列插入重復(fù)值該怎么解決呢

    本文給大家介紹mysql中unique列插入重復(fù)值的解決方案,主要基于mysql平臺,通過這些,可以做到一些新的功能和應(yīng)用。特此把本文本文分享給廣大開發(fā)人員
    2015-11-11
  • Mysql分區(qū)表的管理與維護

    Mysql分區(qū)表的管理與維護

    改變一個表的分區(qū)方案只需使用alter table 加 partition_options 子句就可以了。這篇文章主要介紹了Mysql分區(qū)表的管理與維護,非常不錯,感興趣的朋友一起學(xué)習(xí)吧,需要的朋友可以參考下
    2016-08-08
  • 深入理解MySQL事務(wù)的4種隔離級別

    深入理解MySQL事務(wù)的4種隔離級別

    本文主要介紹了MySQL事務(wù)的4種隔離級別,事務(wù)的4種隔離級別分別是讀未提交,讀已提交,可重復(fù)讀和串行化,具有一定的參考價值,感興趣的可以了解一下
    2022-04-04
  • php mysql localhost,127.0.0.1和ip區(qū)別

    php mysql localhost,127.0.0.1和ip區(qū)別

    localhost與127.0.0.1的區(qū)別是什么?相信有人會說是本地ip,曾有人說,用127.0.0.1比localhost好,可以減少一次解析??磥磉@個入門問題還有人不清楚,其實這兩者是有區(qū)別的
    2014-05-05
  • MySQL腳本轉(zhuǎn)換為StarRocks的完整指南

    MySQL腳本轉(zhuǎn)換為StarRocks的完整指南

    本指南詳細說明如何將MySQL數(shù)據(jù)庫腳本轉(zhuǎn)換為StarRocks兼容的格式,包括語法差異、數(shù)據(jù)類型映射、最佳實踐和常見問題解決方案,需要的朋友可以參考下
    2025-09-09
  • SQL group by去重復(fù)且按照其他字段排序的操作

    SQL group by去重復(fù)且按照其他字段排序的操作

    這篇文章主要介紹了SQL group by去重復(fù)且按照其他字段排序的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • mysql查找刪除表中重復(fù)數(shù)據(jù)方法總結(jié)

    mysql查找刪除表中重復(fù)數(shù)據(jù)方法總結(jié)

    在本篇文章中小編給大家整理了關(guān)于mysql查找刪除表中重復(fù)數(shù)據(jù)方法和相關(guān)知識點,需要的朋友們參考下。
    2019-05-05
  • mysql主從同步原理及應(yīng)用場景示例詳解

    mysql主從同步原理及應(yīng)用場景示例詳解

    這篇文章主要為大家介紹了mysql主從同步原理及應(yīng)用場景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08

最新評論

葫芦岛市| 喀什市| 兴和县| 文水县| 庄河市| 康马县| 阿克| 博客| 扬州市| 高青县| 信宜市| 福清市| 信丰县| 泉州市| 康乐县| 泾源县| 镇雄县| 科技| 宣恩县| 呼伦贝尔市| 佛山市| 青阳县| 陇西县| 武城县| 明星| 通州市| 渝中区| 都昌县| 锦屏县| 崇信县| 康保县| 南丰县| 宣威市| 阜南县| 钟山县| 托里县| 乌海市| 石嘴山市| 新巴尔虎左旗| 怀宁县| 长泰县|