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

一文解析MySQL的MVCC實(shí)現(xiàn)原理

 更新時(shí)間:2022年08月16日 09:24:21   作者:一燈架構(gòu)  
這篇文章主要介紹了MySQL的MVCC實(shí)現(xiàn)原理,MVCC全稱是Multi-Version?Concurrency?Control是一種并發(fā)控制的方法,通過(guò)維護(hù)一個(gè)數(shù)據(jù)的多個(gè)版本,減少讀寫操作的沖突

1. 什么是MVCC

MVCC全稱是Multi-Version Concurrency Control(多版本并發(fā)控制),是一種并發(fā)控制的方法,通過(guò)維護(hù)一個(gè)數(shù)據(jù)的多個(gè)版本,減少讀寫操作的沖突。

如果沒(méi)有MVCC,想要實(shí)現(xiàn)同一條數(shù)據(jù)的并發(fā)讀寫,還要保證數(shù)據(jù)的安全性,就需要操作數(shù)據(jù)的時(shí)候加讀鎖和寫鎖,這樣就降低了數(shù)據(jù)庫(kù)的并發(fā)性能。

有了MVCC,就相當(dāng)于把同一份數(shù)據(jù)生成了多個(gè)版本,在操作的開(kāi)始各生成一個(gè)快照,讀寫操作互不影響。無(wú)需加鎖,也實(shí)現(xiàn)數(shù)據(jù)的安全性和事務(wù)的隔離性。

事務(wù)的四大特性中隔離性就是基于MVCC實(shí)現(xiàn)的。

說(shuō)MVCC的實(shí)現(xiàn)原理之前,先說(shuō)一下事務(wù)的隔離級(jí)別。

2. 事務(wù)的隔離級(jí)別

說(shuō)隔離級(jí)別之前,先說(shuō)一下并發(fā)事務(wù)產(chǎn)生的問(wèn)題

臟讀: 一個(gè)事務(wù)讀到其他事務(wù)未提交的數(shù)據(jù)。

不可重復(fù)讀: 相同的查詢條件,多次查詢到的結(jié)果不一致,即讀到其他事務(wù)提交后的數(shù)據(jù)。

幻讀: 相同的查詢條件,多次查詢到的結(jié)果不一致,即讀到其他事務(wù)提交后的數(shù)據(jù)。

不可重復(fù)讀與幻讀的區(qū)別是: 不可重復(fù)讀是讀到了其他事務(wù)執(zhí)行update、delete后的數(shù)據(jù),而幻讀是讀到其他事務(wù)執(zhí)行insert后的數(shù)據(jù)。

再說(shuō)一下事務(wù)的四大隔離級(jí)別:

Read UnCommitted(讀未提交): 讀到其他事務(wù)未提交的數(shù)據(jù),會(huì)出現(xiàn)臟讀、不可重復(fù)讀、幻讀。

Read Committed(讀已提交): 讀到其他事務(wù)已提交的數(shù)據(jù),解決了臟讀,會(huì)出現(xiàn)不可重復(fù)讀、幻讀。

Repeatable Read(可重復(fù)讀): 相同的條件,多次讀取到的結(jié)果一致。解決了臟讀、不可重復(fù)讀,會(huì)出現(xiàn)幻讀。

Serializable(串行化): 所有事務(wù)串行執(zhí)行,解決了臟讀、不可重復(fù)讀、幻讀。

隔離級(jí)別臟讀不可重復(fù)讀幻讀
讀未提交會(huì)會(huì)會(huì)
讀已提交不會(huì)會(huì)會(huì)
可重復(fù)讀不會(huì)不會(huì)會(huì)
串行化不會(huì)不會(huì)不會(huì)

MVCC只在Read CommittedRepeatable Read兩個(gè)隔離級(jí)別下起作用,因?yàn)?strong>Read UnCommitted隔離級(jí)別下,讀寫都不加鎖,Serializable隔離級(jí)別下,讀寫都加鎖,也就不需要MVCC了。

再談一下Undo log日志。

3. Undo Log(回滾日志)

Undo Log記錄的是邏輯日志,也就是SQL語(yǔ)句。

比如:當(dāng)我們執(zhí)行一條insert語(yǔ)句時(shí),Undo Log就記錄一條相反的delete語(yǔ)句。

作用:

  • 回滾事務(wù)時(shí),恢復(fù)到修改前的數(shù)據(jù)。
  • 實(shí)現(xiàn) MVCC 。

事務(wù)四大特性中原子性也是基于Undo Log實(shí)現(xiàn)的。

下面開(kāi)始談一下MVCC的實(shí)現(xiàn)原理。

4. MVCC的實(shí)現(xiàn)原理

4.1 當(dāng)前讀和快照讀

先普及一下什么是當(dāng)前讀和快照讀。

當(dāng)前讀: 讀取數(shù)據(jù)的最新版本,并對(duì)數(shù)據(jù)進(jìn)行加鎖。

例如:insert、update、delete、select for update、 select lock in share mode。

快照讀: 讀取數(shù)據(jù)的歷史版本,不對(duì)數(shù)據(jù)加鎖。

例如:select

MVCC是基于Undo Log、隱藏字段、Read View(讀視圖)實(shí)現(xiàn)的。

4.2 隱藏字段

先說(shuō)一下MySQL的隱藏字段,當(dāng)我們創(chuàng)建一張表時(shí),InnoDB引擎會(huì)增加2個(gè)隱藏字段。

DB_TRX_ID(最近一次提交事務(wù)的ID):修改表數(shù)據(jù)時(shí),都會(huì)提交事務(wù),每個(gè)事務(wù)都有一個(gè)唯一的ID,這個(gè)字段就記錄了最近一次提交事務(wù)的ID。

DB_ROLL_PTR(上個(gè)版本的地址):修改表數(shù)據(jù)時(shí),舊版本的數(shù)據(jù)都會(huì)被記錄到Undo Log日志中,每個(gè)版本的數(shù)據(jù)都有一個(gè)版本地址,這個(gè)字段記錄的就是上個(gè)版本的地址。

4.3 版本鏈

當(dāng)我們第一次往用戶表插入一條記錄時(shí),表數(shù)據(jù)和隱藏字段的值是下面這樣的:

insert into user (name,age) values ('一燈',1);

事務(wù)ID(DB_TRX_ID)是1,上個(gè)版本地址(DB_ROLL_PTR)是null。

image-20220814230054004.png

 第二次提交事務(wù),把用戶年齡加1。

update user set age=age+1 where id=1;

事務(wù)ID變成2,上個(gè)版本地址指向Undo Log中的記錄。

image-20220814230233034.png

第三次提交事務(wù),再把用戶年齡加1。

update user set age=age+1 where id=1;

事務(wù)ID變成3,上個(gè)版本地址指向Undo Log中事務(wù)ID為2的記錄。

image-20220814230426413.png

這樣表記錄和Undo Log歷史數(shù)據(jù)就組成了一個(gè)版本鏈。

4.4 Read View(讀視圖)

在事務(wù)中,執(zhí)行SQL查詢,就會(huì)生成一個(gè)讀視圖,是用來(lái)保證數(shù)據(jù)的可見(jiàn)性,即讀到Undo Log中哪個(gè)版本的數(shù)據(jù)。

快照讀一般是讀取的歷史版本的讀視圖,當(dāng)前圖會(huì)生成一個(gè)最新版本的讀視圖。

讀視圖是基于下面幾個(gè)字段實(shí)現(xiàn)的:

m_ids :當(dāng)前系統(tǒng)中活躍的事務(wù)ID集合,即未提交的事務(wù)。

min_trx_id :m_ids中最小的ID

max_trx_id :下一個(gè)要分配的事務(wù)ID

creator_trx_id: 當(dāng)前事務(wù)ID

讀視圖決定當(dāng)前事務(wù)能讀到哪個(gè)版本的數(shù)據(jù),從表記錄到Undo Log歷史數(shù)據(jù)的版本鏈,依次匹配,滿足哪個(gè)版本的匹配規(guī)則,就能讀到哪個(gè)版本的數(shù)據(jù),一旦匹配成功就不再往下匹配。

數(shù)據(jù)可見(jiàn)性規(guī)則:

  • DB_TRX_ID = creator_trx_id 如果這個(gè)版本數(shù)據(jù)的事務(wù)ID等于當(dāng)前事務(wù)ID,表示數(shù)據(jù)記錄的最后一次操作的事務(wù)就是當(dāng)前事務(wù),當(dāng)前讀視圖可以讀到這個(gè)版本的數(shù)據(jù)。
  • DB_TRX_ID < min_trx_id 如果這個(gè)版本數(shù)據(jù)的事務(wù)ID小于所有活躍事務(wù)ID,表示這個(gè)版本的數(shù)據(jù)不再被事務(wù)使用,即事務(wù)已提交,當(dāng)前讀視圖可以讀到這個(gè)版本的數(shù)據(jù)。
  • DB_TRX_ID >= max_trx_id 如果這個(gè)版本數(shù)據(jù)的事務(wù)ID大于等于下一個(gè)要分配的事務(wù)ID,表示有新事務(wù)更新了這個(gè)版本的數(shù)據(jù),這種情況下,當(dāng)前讀視圖不可以讀到這個(gè)版本的數(shù)據(jù)。
  • min_trx_id <= DB_TRX_ID < max_trx_id 如果這個(gè)版本數(shù)據(jù)的事務(wù)ID在當(dāng)前系統(tǒng)中活躍的事務(wù)ID集合(m_ids)里面,表示這個(gè)版本的數(shù)據(jù)被其他事務(wù)更新過(guò),當(dāng)前讀視圖不可以讀到這個(gè)版本的數(shù)據(jù)。 如果這個(gè)版本數(shù)據(jù)的事務(wù)ID不在當(dāng)前系統(tǒng)中活躍的事務(wù)ID集合(m_ids)里面,表示是在其他事務(wù)提交后創(chuàng)建的讀視圖,當(dāng)前讀視圖可以讀到這個(gè)版本的數(shù)據(jù)。

5. 不同隔離級(jí)別下可見(jiàn)性分析

在不同的事務(wù)隔離級(jí)別下,生成讀視圖的規(guī)則不同:

  • READ COMMITTED(讀已提交) :在事務(wù)中每一次執(zhí)行快照讀時(shí)都生成一個(gè)讀視圖,每個(gè)讀視圖中四個(gè)字段的值都是不同的。
  • REPEATABLE READ(可重復(fù)讀):僅在事務(wù)中第一次執(zhí)行快照讀時(shí)生成讀視圖,后續(xù)復(fù)用這個(gè)讀視圖。

5.1 READ COMMITTED(讀已提交)

設(shè)置MySQL隔離級(jí)別為讀已提交:

SET session TRANSACTION ISOLATION LEVEL READ COMMITTED;

image-20220815155838874.png

執(zhí)行兩個(gè)事務(wù),驗(yàn)證一下:

image-20220815160030220.png

事務(wù)1第一次查詢時(shí),會(huì)生成一個(gè)讀視圖,讀視圖的各個(gè)屬性如下:

屬性
m_ids1,2
min_limit_id1
max_limit_id3
creator_trx_id1

可見(jiàn)的版本鏈數(shù)據(jù)是:

image-20220815160452959.png

符號(hào)規(guī)則 DB_TRX_ID = creator_trx_id = 1,可以看到當(dāng)前版本的數(shù)據(jù)。

事務(wù)1第二次查詢時(shí),會(huì)生成一個(gè)新的讀視圖,讀視圖的各個(gè)屬性如下:

屬性
m_ids1
min_limit_id1
max_limit_id3
creator_trx_id1

可見(jiàn)的版本鏈數(shù)據(jù)是:

image-20220815174212106.png

符號(hào)規(guī)則 min_trx_id <= DB_TRX_ID < max_trx_id(1<=2<3),并且當(dāng)前數(shù)據(jù)版本的事務(wù)ID不在當(dāng)前系統(tǒng)中活躍的事務(wù)ID集合,可以看到當(dāng)前版本的數(shù)據(jù)。

image-20220815192630458.png

同一個(gè)事務(wù)內(nèi),相同的查詢條件,查詢到的數(shù)據(jù)不一致,查到了其他事務(wù)更新過(guò)的數(shù)據(jù),也就是出現(xiàn)了不可重復(fù)讀的情況。

再看一下,在可重復(fù)讀隔離級(jí)別下,是怎么解決這個(gè)問(wèn)題的。

5.2 REPEATABLE READ(可重復(fù)讀)

設(shè)置MySQL隔離級(jí)別為可重復(fù)讀:

SET session TRANSACTION ISOLATION LEVEL REPEATABLE READ;

image-20220815192509582.png

執(zhí)行兩個(gè)事務(wù),驗(yàn)證一下:

image-20220815160030220.png

事務(wù)1第一次查詢時(shí),會(huì)生成一個(gè)讀視圖,讀視圖的各個(gè)屬性如下:

屬性
m_ids1,2
min_limit_id1
max_limit_id3
creator_trx_id1

可見(jiàn)的版本鏈數(shù)據(jù)是:

image-20220815160452959.png

符號(hào)規(guī)則 DB_TRX_ID = creator_trx_id = 1,可以看到當(dāng)前版本的數(shù)據(jù)。

事務(wù)1第二次查詢時(shí),會(huì)復(fù)用原有的讀視圖,讀視圖的各個(gè)屬性如下:

屬性
m_ids1,2
min_limit_id1
max_limit_id3
creator_trx_id1

可見(jiàn)的版本鏈數(shù)據(jù)是:

image-20220815174212106.png

符號(hào)規(guī)則 min_trx_id <= DB_TRX_ID < max_trx_id(1<=2<3),并且當(dāng)前數(shù)據(jù)版本的事務(wù)ID在當(dāng)前系統(tǒng)中活躍的事務(wù)ID集合,所以是不可以看到當(dāng)前版本的數(shù)據(jù)。

image-20220815193850487.png

由此得知,可重復(fù)讀隔離級(jí)別下,相同的查詢條件,兩次查詢到的結(jié)果相同,也就是解決了可重復(fù)讀的問(wèn)題,是通過(guò)復(fù)用原有的讀視圖的方式解決的。

到此這篇關(guān)于一問(wèn)解析MySQL的MVCC實(shí)現(xiàn)原理的文章就介紹到這了,更多相關(guān)MySQL MVCC實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • windows 10 下安裝mysql 5.7.17的簡(jiǎn)單筆記

    windows 10 下安裝mysql 5.7.17的簡(jiǎn)單筆記

    之前一直在Linux下用MySQL,安裝也很簡(jiǎn)單,今天試一下windows下安裝,發(fā)現(xiàn)有很多坑,今天小編通過(guò)本教程給大家記錄下,一起看看吧
    2016-12-12
  • SQL窗口函數(shù)OVER用法實(shí)例整理

    SQL窗口函數(shù)OVER用法實(shí)例整理

    做SQL題時(shí)碰到了over()函數(shù)不太理解,所以整理了下,下面這篇文章主要給大家介紹了關(guān)于SQL窗口函數(shù)OVER用法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • MySQL?Online?DDL原理解析

    MySQL?Online?DDL原理解析

    MySQL原生OnlineDDL通過(guò)允許在表可用的情況下執(zhí)行DDL操作,大大提升了數(shù)據(jù)庫(kù)的可用性,通過(guò)不同的執(zhí)行算法,如COPY、INPLACE和INSTANT,它支持在線修改數(shù)據(jù)庫(kù)結(jié)構(gòu),優(yōu)化了數(shù)據(jù)庫(kù)維護(hù)流程,本文給大家介紹MySQL?Online?DDL原理,感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • MYSQL刪除匿名用戶的方法(提高安全性)

    MYSQL刪除匿名用戶的方法(提高安全性)

    今天看教程的時(shí)候,發(fā)現(xiàn)了MYSQL匿名用戶可以導(dǎo)致網(wǎng)站數(shù)據(jù)等安全問(wèn)題,這里分享下mysql中刪除匿名用戶的步驟,方便需要的朋友
    2012-10-10
  • MySql修改密碼后phpMyAdmin無(wú)法登陸的解決方法

    MySql修改密碼后phpMyAdmin無(wú)法登陸的解決方法

    這篇文章主要為大家詳細(xì)介紹了MySql修改密碼后PhpMyAdmin無(wú)法登陸的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • php后臺(tái)經(jīng)常提示無(wú)法連接mysql 刷新后又可以訪問(wèn)的解決方法

    php后臺(tái)經(jīng)常提示無(wú)法連接mysql 刷新后又可以訪問(wèn)的解決方法

    這幾天有一臺(tái)MySQL數(shù)據(jù)庫(kù)服務(wù)器出現(xiàn)了頻繁的掉線情況,通過(guò)排查,并沒(méi)有排查出哪個(gè)網(wǎng)站被攻擊,百思不得其解中的時(shí)候,群里有個(gè)朋友說(shuō)是因?yàn)槲④汯B967723造成的,網(wǎng)上搜索了一下,果然很多人都是這樣的問(wèn)題,都是windows系統(tǒng)下安裝的MySQL造成的
    2011-05-05
  • PostgreSQL USAGE和SELECT權(quán)限案例深入分析

    PostgreSQL USAGE和SELECT權(quán)限案例深入分析

    這篇文章主要介紹了PostgreSQL USAGE和SELECT權(quán)限案例深入分析,因?yàn)轫?xiàng)目需求,需要學(xué)習(xí)PostgreSQL,本人之前學(xué)習(xí)過(guò)MYSQL,臨時(shí)快速上手,盡快的去學(xué)習(xí)項(xiàng)目需要PostgREST
    2023-04-04
  • 淺析MySQL replace into 的用法

    淺析MySQL replace into 的用法

    在向表中插入數(shù)據(jù)的時(shí)候,經(jīng)常遇到這樣的情況:1. 首先判斷數(shù)據(jù)是否存在; 2. 如果不存在,則插入;3.如果存在,則更新。
    2014-06-06
  • 如何使用Maxwell實(shí)時(shí)同步mysql數(shù)據(jù)

    如何使用Maxwell實(shí)時(shí)同步mysql數(shù)據(jù)

    這篇文章主要介紹了如何使用Maxwell實(shí)時(shí)同步mysql數(shù)據(jù),幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-04-04
  • mysql 查詢數(shù)據(jù)庫(kù)中的存儲(chǔ)過(guò)程與函數(shù)的語(yǔ)句

    mysql 查詢數(shù)據(jù)庫(kù)中的存儲(chǔ)過(guò)程與函數(shù)的語(yǔ)句

    mysql 查詢數(shù)據(jù)庫(kù)中的存儲(chǔ)過(guò)程與函數(shù)的語(yǔ)句,需要的朋友可以參考下。
    2011-05-05

最新評(píng)論

汉源县| 四子王旗| 宾川县| 岳阳市| 贞丰县| 莱西市| 台中市| 布尔津县| 含山县| 抚顺县| 互助| 永靖县| 绥阳县| 峨眉山市| 伊春市| 巴马| 天柱县| 乐安县| 乌鲁木齐市| 静安区| 洪雅县| 陈巴尔虎旗| 霞浦县| 泾阳县| 苍南县| 澄城县| 新巴尔虎右旗| 太仆寺旗| 永吉县| 齐河县| 康定县| 思茅市| 阳曲县| 绥滨县| 桃源县| 永福县| 丁青县| 平利县| 伊吾县| 阿鲁科尔沁旗| 元江|