成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

mysql中RR與幻讀的相關問題

本篇文章給大家帶來了關于mysql的相關知識,其中主要介紹了關于RR與幻讀的相關內容,包括了MVCC原理、RR產生幻讀、RR解決幻讀等等內容,下面一起來看一下,希望對大家有幫助。

mysql中RR與幻讀的相關問題

程序員必備接口測試調試工具:立即使用
Apipost = Postman + Swagger + Mock + Jmeter
Api設計、調試、文檔、自動化測試工具
后端、前端、測試,同時在線協作,內容實時同步

推薦學習:mysql視頻教程

一、前言

本文圍繞這三個話題展開學習 RR 如何解決幻讀?

mysql中RR與幻讀的相關問題

  • MVCC 原理

  • 實驗:RR 與 幻讀

  • 案例:死鎖

先來回顧下 MySQL中 InnoDB 支持的四種事務隔離 和 并發事務所帶來的一些問題:

mysql中RR與幻讀的相關問題

  • 讀未提交:能讀到一個事務的中間過程,違背了 ACID 特性,存在臟讀的問題,基本不會用到。

  • 讀提交:表示如果其他事務已經提交,那么就可以看到。在生產環境中用的并不多。

  • 可重復讀:默認級別,使用最多的一種。其特點是有 Gap 鎖(間隙鎖)。

  • 可串行化:所有的實現都是通過鎖來實現的。

并發事務處理也會帶來一些問題:臟讀、不可重復讀、幻讀

  • 臟讀:一個事務正在對一條記錄做修改,在這個事務完成并提交前,這條記錄的數據就處于不一致狀態。

  • 不可重復讀:一個事務按相同查詢條件前后兩次讀取,讀出的數據不一致(修改、刪除)。

  • 幻讀:一個事務內按相同的查詢條件重新查詢數據,卻發現其他事務插入了滿足其查詢條件的新數據。

本文脈絡梳理: RR 為了更快并發,引入 MVCC,但有幻讀的可能,為解決幻讀,引入 Gap 鎖,Gap 可能造成死鎖。

二、MVCC 原理

MVCC(多版本控制): 指數據庫中為了實現高并發的數據訪問,對數據進行多版本處理,并通過事務的可見性來保證事務能看到自己應該看到的數據版本。

MVCC 最大的好處是讀不加鎖,讀寫不沖突。

在 OLTP (On-Line Transaction Processing)應用中,讀寫不沖突很重要,幾乎所有 RDBMS 都支持 MVCC。

注意:MVCC 只在 讀提交RC 和 可重復讀RR 兩種隔離級別下工作。

注意:MVCC 只在 讀提交RC 和 可重復讀RR 兩種隔離級別下工作。

注意:MVCC 只在 讀提交RC 和 可重復讀RR 兩種隔離級別下工作。

(1)MVCC 多版本實現

MySQL 實現 MVCC 機制的時候,是基于 undo log 多版本鏈條 + ReadView 機制。

  • undo log 多版本鏈: 每一次對數據庫的修改,都會在 undo log 日志中記錄當前修改記錄的事務號及修改前數據狀態的存儲地址(即 ROLL_PTR),以便在必要的時候可以回滾到老的數據版本。

  • ReadView 機制: 在多版鏈的基礎上,控制事務讀取的可見性。(主要區別是:RC 和 RR)

這里不著重探究原理,但要有大概的概念:undo log 多版本鏈 和 ReadView 機制。

針對 undo log 多版本鏈,舉個栗子:

  • 一個讀事務查詢到當前記錄,而最新的事務還未提交。

  • 根據原子性,讀事務看不到最新數據,但可以去回滾段中找到老版本的數據,這樣就生成了多個版本。

針對 ReadView 機制: 基于 undo log 多版本鏈實現,不同事務隔離有不同處理 :

  • RC 級別的事務: 可見性比較高,它可以看到已提交的事務的所有修改。

  • RR 級別的事務: 一個讀事務中,不管其他事務對這些數據做了什么修改,以及是否提交,只要自己不提交,查詢的數據結果就不會變。

這是如何做到的呢?

RC讀提交: 每一條讀操作語句都會獲取一次 ReadView,每次更新之后,都會獲取數據庫中最新的事務提交狀態,也就可以看到最新提交的事務了,即每條語句執行都會更新其可見性視圖。

RR可重復讀: 開啟事務時不會獲取 ReadView,只有發起第一個快照讀時才會獲取 ReadView。

如果使用當前讀,都會獲取新的 ReadView,也能看到更新的數據。

(2)快照讀與當前讀

在 MVCC 并發控制中,讀操作 可以分為兩類:

快照讀:讀取的是記錄的可見版本(有可能是歷史版本), 不用加鎖 。

操作:簡單的 SELECT 操作。

當前讀:讀取的是記錄的最新版本,并且當前讀返回的記錄,都會加鎖,保證其他事務不會再并發修改這條記錄。

操作:特殊讀操作、新增/更新/刪除操作。

-- 對應 SQL 如下: -- 1. 特殊讀操作 SELECT ... FOR UPDATE SELECT ... LOCK IN SHARE MODE  -- 共享鎖 -- 2. 新增:INSERT  -- 3. 更新:UPDATE -- 4. 刪除:DELETE
登錄后復制

結合 ReadView 機制來區分:快照讀 和 當前讀:

快照讀: 在一個事務里,只有發起第一個快照讀時才會獲取 ReadView,之后的讀操作不會再獲取。

當前讀: 每次讀操作都會獲取 ReadView。

三、實驗:RR 與幻讀

面試題:在 RR 事務隔離級別下,事務A查詢一條數據,事務B新增一條數據,事務A能看到事務B的數據嘛?

mysql中RR與幻讀的相關問題

這個問題比較模糊,但大致考察點我們知曉是 RR 與 幻讀,可以將問題分為兩類:

什么情況下,RR 產生幻讀?(能看到數據)

答案:當前讀(SELECT..FOR UDPDATE、SELECT … LOCK IN SHARE MODE)

什么情況下,RR 解決幻讀?(不能看到數據)

答案:加鎖、快照讀

注意: 不可重復讀 重點在于 UPDATA 和 DELETE,而幻讀的重點在于 INSERT。

它們之間最大的區別:是如何通過鎖機制來解決它們產生的問題。

這里說的鎖只是使用悲觀鎖機制。

再來回顧下:幻讀

-- 舉個栗子:有這樣一個查詢 SQL SELECT * FROM user WHERE id < 10;
登錄后復制

在同一個事務下,T1時刻查詢出來 4 條數據,T2時刻查詢出來 8 條數據。這就產生了幻讀。

在同一個事務下,T1時刻查詢出來 8 條數據,T2時刻查詢出來 4 條數據。這就產生了幻讀。

實驗準備如下: 動手實踐起來

show variables like 'transaction_isolation'; -- 事務隔離級別 RR select version();                            -- 版本 8.0.16 show variables like '%storage_engine%';      -- 引擎 InnoDB -- 1. 手動開啟事務提交 begin;  -- 開始事務 commit; -- 提交事務 -- 2. 創建表 CREATE TABLE IF NOT EXISTS `student` ( `id` INT NOT NULL COMMENT '主鍵 id', `name` VARCHAR(50) NOT NULL COMMENT '名字', `age` TINYINT NOT NULL COMMENT '年齡', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT '學生表'; -- 3. 新增數據用于實驗 INSERT INTO student (id, name, age) VALUES (5, 'kunkun', 14); INSERT INTO student (id, name, age) VALUES (30, 'ikun', 18);
登錄后復制

(1)RR 產生幻讀

實驗如下: 測試當前讀

實驗一:先 SELECT,再 SELECT … FOR UPDATE

實驗二:先 SELECT,再 UPDATE (不會產生幻讀)

實驗一:先 SELECT,再 SELECT … FOR UPDATE

-- 事務A: BEGIN; SELECT * FROM student WHERE id < 30; SELECT * FROM student WHERE id < 30 FOR UPDATE;  -- 等待事務B commit 后再執行 -- SELECT * FROM student WHERE id < 30 LOCK IN SHARE MODE; COMMIT; -- 事務B: BEGIN; INSERT INTO student (id, name, age) VALUES (20, 'wulikun', 16); COMMIT;
登錄后復制

發生情況如下圖所示:

mysql中RR與幻讀的相關問題

實驗記錄如下圖所示:

mysql中RR與幻讀的相關問題

現象結論: 當使用當前讀(SELECT … FOR UPDATE)會產生幻讀。

同樣使用 SELECT … LOCK IN SHARE MODE; 會產生幻讀。

mysql中RR與幻讀的相關問題

實驗二:先 SELECT,再 UPDATE

-- 事務A: BEGIN; SELECT * FROM student WHERE id < 30; UPDATE student SET name = 'zhiyin' WHERE id = 5;  -- 等待事務B commit 后再執行 SELECT * FROM student WHERE id < 30; COMMIT; -- 事務B: BEGIN; INSERT INTO student (id, name, age) VALUES (20, 'wulikun', 16); COMMIT;
登錄后復制

發生情況如下圖所示:

mysql中RR與幻讀的相關問題

實驗記錄如下圖所示:

mysql中RR與幻讀的相關問題

現象結論: 當前讀(UPDATE)不會產生幻讀。同樣 INSERT / DELETE 均不會。

mysql中RR與幻讀的相關問題

(2)RR 解決幻讀

實驗如下:

  • 實驗一:快照讀

  • 實驗二:加鎖(更新不存在的記錄)

  • 實驗三:加鎖(SELECT … FOR UPDATE)

實驗一:快照讀,普通 SELECT

-- 事務A: BEGIN; SELECT * FROM student; SELECT * FROM student;  -- 等待事務B commit 后再執行 COMMIT; -- 事務B: BEGIN; INSERT INTO student (id, name, age) VALUES (20, 'wulikun', 16); COMMIT;
登錄后復制

發生情況如下圖所示:

mysql中RR與幻讀的相關問題

實驗記錄如下圖所示:

mysql中RR與幻讀的相關問題

現象結論: 在 RR 事務隔離級別下,只有快照讀(SELECT)不會出現幻讀。沒有當前讀。

實驗二:加鎖 ,(更新不存在的記錄)

在 RR 隔離級別下,事務 A 使用 UPDATE 加鎖,事務 B 無法在這之間插入新數據,這樣事務 A在 UPDATE 前后讀的數據保持一致,避免了幻讀。

-- 事務A: BEGIN; SELECT * FROM student; UPDATE student SET name = 'wulikunkun' WHERE id = 18; -- 記錄不存在,產生間隙鎖 (5, 30)。 COMMIT; -- 事務B: BEGIN; INSERT INTO student (id, name, age) VALUES (10, 'zhiyin', 16); -- 需要等待事務A結束。 COMMIT; -- 事務C: BEGIN; INSERT INTO student (id, name, age) VALUES (40, 'zhiyin你太美', 32); COMMIT; -- 查詢數據庫中當前有哪些鎖 SELECT INDEX_NAME,LOCK_TYPE,LOCK_MODE,LOCK_STATUS,LOCK_DATA FROM performance_schema.data_locks;
登錄后復制

發生情況如下圖所示:

mysql中RR與幻讀的相關問題

實驗記錄如下圖所示:

mysql中RR與幻讀的相關問題

現象結論:

一開始先加 臨鍵鎖Next-key lock,鎖范圍為 (5,30]。

因為是唯一索引,且更新的記錄不存在,臨鍵鎖退化成 間隙鎖Gap,最終鎖范圍為 (5,30)。其余的記錄不受影響。

實驗三:加鎖(SELECT … FOR UPDATE)

-- 事務A: BEGIN; SELECT * FROM student; SELECT * FROM student WHERE id < 5 FOR UPDATE; COMMIT; -- 事務B: BEGIN; INSERT INTO student (id, name, age) VALUES (4, 'zhiyin', 4); -- 需要等待事務A結束。 COMMIT; -- 事務C: BEGIN; INSERT INTO student (id, name, age) VALUES (5, 'zhiyin你太美', 32); -- 插入成功 COMMIT; -- 查詢數據庫中當前有哪些鎖 SELECT INDEX_NAME,LOCK_TYPE,LOCK_MODE,LOCK_STATUS,LOCK_DATA FROM performance_schema.data_locks;
登錄后復制

發生情況如下圖所示:

mysql中RR與幻讀的相關問題

實驗記錄如下圖所示:

mysql中RR與幻讀的相關問題

現象結論:

先加 臨鍵鎖Next-key lock,鎖范圍為 (-∞,5]。

所以,id < 5 和 id = 5 的數據都插入不進去。

拓展:Gap 鎖(間隙鎖)

根據 官方文檔 可知:

  • 鎖是加在索引上的。

  • 記錄鎖: 行鎖,只會鎖定一條記錄。

  • 間隙鎖 :是在索引記錄之間的間隙上的鎖,區間為前開后開 (,)。

  • 臨鍵鎖(Next-Key Lock): 由 記錄鎖 和 間隙鎖Gap 組合起來。

  • 加鎖的基本單位是 臨鍵鎖,其加鎖區間為前開后閉 (,]。

  • 索引上的等值查詢,給唯一索引加鎖的時候,如果滿足條件,臨鍵鎖 退化為 行鎖。

  • 索引上的等值查詢,給唯一索引加鎖的時候,如果不滿足條件,臨鍵鎖 退化為 間隙鎖。注意,非等值查詢是不會優化的。

推薦學習:mysql視頻教程

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
成人人妻小说AV| 成人免费A级毛片无码片在线播放| 中国BBW50成熟| 在线观看AV网站永久免费观看| 宅男666在线永久免费观看| 18日韩xxxx| 播放灌醉水嫩大学生国内精品| 北条麻妃国产九九九精品视频 | 性VIDEOSTV另类极品| 亚洲成AⅤ人片久青草影院| 亚洲中文字幕无码一区| 2023国产精品一卡2卡三卡| 成 人 黄 色 网 站 ·大| 国产精品美女乱子伦高潮| 精品日产A一卡2卡三卡4卡乱| 老湿机香蕉久久久久久| 人妻精品久久久久中文字幕| 天天躁日日躁狠狠躁裸体| 亚洲AV无码专区国产乱码4SE | 无码免费无线观看在线视频| 亚洲国产成人无码电影| 18禁黄网站禁片免费观看香港| 扒开双腿猛进入喷水高潮叫声 | 不收费的十大免费好用的软件| 高清无码国产黄色视频人爽人一区二区| 国产无套内射普通话对白 | 国产乱子伦精品免费无码专区| 精品亚洲国产成人蜜臀优播AV| 内射老妇BBWX0C0CK| 少妇人妻互换不带套| 亚洲精品无码久久久久牙蜜区| 97精品伊人久久大香线蕉app| 国产AⅤ精品福利一区二区三区| 精品国产AV 无码一区二区三区| 妺妺窝人体色聚色窝www视频| 色综合色天天久久婷婷基地| 亚洲精品无码AV人在线播放| BGMBGMBGM老太太HD| 国产精品乱码久久久久软件| 久久人人爽人人爽人人片DVD| 日本牲交大片免费观看| 亚洲成在人线AV自拍| A级毛片免费无码观看、、| 国产麻豆剧传媒精品国产AV| 免费无码又爽又刺激高潮的动态图 | 久久婷婷五月综合色国产免费观看| 日本熟老太日本老熟网站| 亚洲成AV人片无码迅雷下载 | 欧美亚洲日韩不卡在线在线观看 | 狠狠色丁香久久婷婷综| 欧美色欧美亚洲高清在线观看| 小雪尝禁果又粗又大的中国地图| 中文字幕一本性无码| 国产精品普通话国语对白露脸| 老熟女重囗味HDXX70星空| 天天爽夜夜爽人人爽| 自偷自拍亚洲综合精品麻豆| 国产美女精品一区二区三区| 欧美疯狂做受XXXX高潮小说| 亚洲AV无码成人网站在线观看 | 欧洲亚洲1卡二卡三卡2021| 亚洲AV无码国产一区二区三区四| CAOPOREN超碰最新地址| 精品国产18久久久久久| 三级无码在钱AV无码在钱| 一二三四视频社区在线| 国产成人无码A在线观看不卡| 浪潮国产AV一区二区熟女| 无码人妻一区二区三区AV| AV片在线观看免费| 精品国产一区二区三区香蕉 | 国产AV无码专区亚洲AV麻豆丫| 乱人伦中文视频在线| 亚洲AV激情无码专区在线播放| 被多男摁住灌浓精| 久久人人爽人人爽人人AV| 午老司机午夜福利视频| 波多野结衣无内裤护士| 亂倫近親相姦中文字幕| 亚洲AV日韩综合一区尤物| 尝到了甜头两人每天都会想方设法 | 亚洲H成年动漫在线观看网站| 粗大挺进亲女H晓晓| 妺妺窝人体色WWW国产馆在线| 亚洲AV综合色一区二区三区 | 无码专区中文字幕无码野外| 宝贝腿开大点我添添公视频免费 | 亚洲AV无码一区二区二三区入口| 东北大坑续集1至60| 欧美人妻体内射射| 野花韩国高清免费神马| 黑人xxx欧美性爱| 无码国产玉足脚交久久2020| 成人爽A毛片免费网站美国| 欧美成人性生活视频| 伊人色综合九久久天天蜜桃| 狠狠色噜噜狠狠狠狠蜜桃 | 国产乱子伦一区二区三区=| 人人妻人人躁人人爽精品| 中文字幕在线观看| 久久男人AV资源网站无码 | 精品国产污污免费网站AⅤ| 无码人妻精品一区二区三区久久 | 激情综合丁香五月| 无码人妻av一区二区三区毛片| 豆奶视频在线观看免费高清版| 秋霞国产午夜伦午夜福利片| 91精品人妻一区二区三区蜜桃 | 中文字幕人妻互换激情| 久久久久久人妻精品一区| 亚洲精品国产AV成拍色拍婷婷| 国产精选午睡沙发系列999| 婷婷五月综合色视频| 疯狂做受ⅩXXX高潮欧美| 日日AV拍夜夜添久久免费| 唱歌的大姐姐也想做| 日本熟妇色丰满少妇wwwww色| BGMBGMBGM欧美XX| 欧美性猛交XXXX黑人猛交| AV一本久道久久波多野结衣| 欧美激情国产精品视频一区二区| 最新中文AV岛国无码免费播放| 两对夫妻一起旅游互换的说说句子| 亚洲中文精品久久久久久| 久久成人国产精品| 亚洲性爱一区二区| 久久久午夜精品福利内容| 亚洲自偷自偷偷色无码中文| 久久精品国产亚洲AV麻豆甜| 亚洲日本乱码在线观看| 久久久G0G0午夜无码精品| 亚洲中文字幕无码专区| 老熟女高潮一区二区三区| √天堂中文最新版在线中文| 妺妺窝人体色www在线观看婚闹| 77777欧美毛片777777| 欧美日韩精品一区二区在线视频| JAVASCRIPT中国免费| 人妻中文字幕AV无码专区| 成熟老年妇女毛茸茸| 熟女亚洲综合精品伊人久久| 国产电影在免费播放在线观看| 无遮挡无码H纯肉动漫在线观看| 国产色在线 | 日韩| 亚洲精品一区二区三浪潮AV | 色婷婷综合激情综在线播放| 国产SUV精品一区二区69| 性欧美丰满熟妇XXXX性| 精品久久久久久久无码人妻热| 亚洲中文字幕无码不卡电影| 免费无码又爽又刺激动态图| VPSWINDOWS另类极品| 色欲AV综合久久一区二区三区| 国产精品成人无码视频| 亚洲AV永久无码精品久久麻豆| 久久精品日日躁夜夜躁| 重生后我抛弃了负心公主| 人妻人人澡人人添人人爽人人玩| 丰满少妇高潮在线播放不卡| 亚洲 成人 无码 在线观看| 久久国产乱子精品免费女| 最新无码国产在线视频2021| 日本ZLJZLJZLJZLJ喷| 国产乱子伦精品免费无码专区| 亚洲精品乱码久久久久久不卡| 蜜桃AV无码免费看永久| 成·人免费午夜无码视频| 小SAO货撅起屁股扒开GIF动| 久久久精品午夜免费不卡| 99亚洲精品卡2卡三卡4卡2卡| 少妇人妻精品一区二区三区| 狠狠色噜噜狠狠狠7777奇米| 中国老B亂伦AV| 色WWW亚洲国产阿娇| 好爽好湿好硬好大免费视频 | 亚洲精品无码AV人在线播放| 女人两腿扒开图片大全| 国产99视频精品免费视频36| 亚洲精品成人无码中文毛片| 欧美精品视频一区二区三区| 国产成在线观看免费视频成本人| 亚洲欧美高清一区二区三区| 欧美交换配乱吟粗大免费看| 国产精品国产精品偷麻豆| 亚洲欧洲AV综合色无码| 欧洲熟妇色XXXXX老妇| 国产精品自产拍在线18禁| 一区二区在线视频| 日韩人妻在线一区二区三区 | 国产成人无码免费看片软件| 亚洲女同精品一区二区| 人妻少妇HEYZO无码专区| 国精产品一二二区传媒有哪些| 性欧美玩弄性少妇HD| 乌克兰少妇VIDEOS高潮| 老师黑色双开真丝旗袍恩施MBA| 肥臀浪妇太爽了快点再快点| 亚洲中文字幕无码专区| 少妇肉欲小说200篇| 理论片午午伦夜理片影院|