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

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

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

1. 什么是MVCC

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

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

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

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

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

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

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

臟讀: 一個事務(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ù)。

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

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

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

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

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

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

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

再談一下Undo log日志。

3. Undo Log(回滾日志)

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

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

作用:

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

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

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

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

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

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

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

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

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

例如:select

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

4.2 隱藏字段

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

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

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

4.3 版本鏈

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

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

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

image-20220814230054004.png

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

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

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

image-20220814230233034.png

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

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

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

image-20220814230426413.png

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

4.4 Read View(讀視圖)

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

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

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

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

min_trx_id :m_ids中最小的ID

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

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

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

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

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

5. 不同隔離級別下可見性分析

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

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

5.1 READ COMMITTED(讀已提交)

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

SET session TRANSACTION ISOLATION LEVEL READ COMMITTED;

image-20220815155838874.png

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

image-20220815160030220.png

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

屬性
m_ids1,2
min_limit_id1
max_limit_id3
creator_trx_id1

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

image-20220815160452959.png

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

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

屬性
m_ids1
min_limit_id1
max_limit_id3
creator_trx_id1

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

image-20220815174212106.png

符號規(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

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

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

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

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

SET session TRANSACTION ISOLATION LEVEL REPEATABLE READ;

image-20220815192509582.png

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

image-20220815160030220.png

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

屬性
m_ids1,2
min_limit_id1
max_limit_id3
creator_trx_id1

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

image-20220815160452959.png

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

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

屬性
m_ids1,2
min_limit_id1
max_limit_id3
creator_trx_id1

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

image-20220815174212106.png

符號規(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ù)讀隔離級別下,相同的查詢條件,兩次查詢到的結(jié)果相同,也就是解決了可重復(fù)讀的問題,是通過復(fù)用原有的讀視圖的方式解決的。

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

相關(guān)文章

  • windows 10 下安裝mysql 5.7.17的簡單筆記

    windows 10 下安裝mysql 5.7.17的簡單筆記

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

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

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

    MySQL?Online?DDL原理解析

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

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

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

    MySql修改密碼后phpMyAdmin無法登陸的解決方法

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

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

    這幾天有一臺MySQL數(shù)據(jù)庫服務(wù)器出現(xiàn)了頻繁的掉線情況,通過排查,并沒有排查出哪個網(wǎng)站被攻擊,百思不得其解中的時候,群里有個朋友說是因?yàn)槲④汯B967723造成的,網(wǎng)上搜索了一下,果然很多人都是這樣的問題,都是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í)過MYSQL,臨時快速上手,盡快的去學(xué)習(xí)項(xiàng)目需要PostgREST
    2023-04-04
  • 淺析MySQL replace into 的用法

    淺析MySQL replace into 的用法

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

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

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

    mysql 查詢數(shù)據(jù)庫中的存儲過程與函數(shù)的語句

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

最新評論

龙南县| 尼木县| 宜宾县| 确山县| 晋城| 西林县| 满洲里市| 二手房| 海晏县| 东乡族自治县| 静乐县| 余姚市| 得荣县| 班玛县| 沾益县| 册亨县| 巴南区| 大关县| 丘北县| 靖安县| 上栗县| 尚志市| 双辽市| 祁连县| 蕉岭县| 阳泉市| 聂拉木县| 昌都县| 祁东县| 梅河口市| 宜兴市| 昌都县| 莱西市| 娱乐| 汉川市| 沛县| 周至县| 永和县| 建阳市| 衡阳市| 砚山县|