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

mysql的MVCC多版本并發(fā)控制的實現

 更新時間:2021年04月12日 11:10:11   作者:myseries  
這篇文章主要介紹了mysql的MVCC多版本并發(fā)控制的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1 什么是MVCC

MVCC全稱是: Multiversion concurrency control,多版本并發(fā)控制,提供并發(fā)訪問數據庫時,對事務內讀取的到的內存做處理,用來避免寫操作堵塞讀操作的并發(fā)問題。

舉個例子,程序員A正在讀數據庫中某些內容,而程序員B正在給這些內容做修改(假設是在一個事務內修改,大概持續(xù)10s左右),A在這10s內 則可能看到一個不一致的數據,在B沒有提交前,如何讓A能夠一直讀到的數據都是一致的呢?

有幾種處理方法,第一種: 基于鎖的并發(fā)控制,程序員B開始修改數據時,給這些數據加上鎖,程序員A這時再讀,就發(fā)現讀取不了,處于等待情況,只能等B操作完才能讀數據,這保證A不會讀到一個不一致的數據,但是這個會影響程序的運行效率。還有一種就是:MVCC,每個用戶連接數據庫時,看到的都是某一特定時刻的數據庫快照,在B的事務沒有提交之前,A始終讀到的是某一特定時刻的數據庫快照,不會讀到B事務中的數據修改情況,直到B事務提交,才會讀取B的修改內容。

一個支持MVCC的數據庫,在更新某些數據時,并非使用新數據覆蓋舊數據,而是標記舊數據是過時的,同時在其他地方新增一個數據版本。因此,同一份數據有多個版本存儲,但只有一個是最新的。

MVCC提供了 時間一致性的 處理思路,在MVCC下讀事務時,通常使用一個時間戳或者事務ID來確定訪問哪個狀態(tài)的數據庫及哪些版本的數據。讀事務跟寫事務彼此是隔離開來的,彼此之間不會影響。假設同一份數據,既有讀事務訪問,又有寫事務操作,實際上,寫事務會新建一個新的數據版本,而讀事務訪問的是舊的數據版本,直到寫事務提交,讀事務才會訪問到這個新的數據版本。

MVCC有兩種實現方式,第一種實現方式是將數據記錄的多個版本保存在數據庫中,當這些不同版本數據不再需要時,垃圾收集器回收這些記錄。這個方式被PostgreSQL和Firebird/Interbase采用,SQL Server使用的類似機制,所不同的是舊版本數據不是保存在數據庫中,而保存在不同于主數據庫的另外一個數據庫tempdb中。第二種實現方式只在數據庫保存最新版本的數據,但是會在使用undo時動態(tài)重構舊版本數據,這種方式被Oracle和MySQL/InnoDB使用。

2、InnoDB的MVCC實現機制

  MVCC可以認為是行級鎖的一個變種,它可以在很多情況下避免加鎖操作,因此開銷更低。MVCC的實現大都都實現了非阻塞的讀操作,寫操作也只鎖定必要的行。InnoDB的MVCC實現,是通過保存數據在某個時間點的快照來實現的。一個事務,不管其執(zhí)行多長時間,其內部看到的數據是一致的。也就是事務在執(zhí)行的過程中不會相互影響。下面我們簡述一下MVCC在InnoDB中的實現。

  InnoDB的MVCC,通過在每行記錄后面保存兩個隱藏的列來實現:一個保存了行的創(chuàng)建時間,一個保存行的過期時間(刪除時間),當然,這里的時間并不是時間戳,而是系統(tǒng)版本號,每開始一個新的事務,系統(tǒng)版本號就會遞增。在RR隔離級別下,MVCC的操作如下:

select操作。

InnoDB只查找版本早于(包含等于)當前事務版本的數據行??梢源_保事務讀取的行,要么是事務開始前就已存在,或者事務自身插入或修改的記錄。

行的刪除版本要么未定義,要么大于當前事務版本號??梢源_保事務讀取的行,在事務開始之前未刪除。

insert操作。將新插入的行保存當前版本號為行版本號。

delete操作。將刪除的行保存當前版本號為刪除標識。

update操作。變?yōu)閕nsert和delete操作的組合,insert的行保存當前版本號為行版本號,delete則保存當前版本號到原來的行作為刪除標識。

  由于舊數據并不真正的刪除,所以必須對這些數據進行清理,innodb會開啟一個后臺線程執(zhí)行清理工作,具體的規(guī)則是將刪除版本號小于當前系統(tǒng)版本的行刪除,這個過程叫做purge。

3、簡單的小例子

create table yang( 
    id int primary key auto_increment, 
    name varchar(20));
}

  假設系統(tǒng)的版本號從1開始.

INSERT

  InnoDB為新插入的每一行保存當前系統(tǒng)版本號作為版本號.
  第一個事務ID為1;

start transaction;
insert into yang values(NULL,'yang') ;
insert into yang values(NULL,'long');
insert into yang values(NULL,'fei');
commit;

  對應在數據中的表如下(后面兩列是隱藏列,我們通過查詢語句并看不到)

SELECT

 InnoDB會根據以下兩個條件檢查每行記錄:
  a.InnoDB只會查找版本早于當前事務版本的數據行(也就是,行的系統(tǒng)版本號小于或等于事務的系統(tǒng)版本號),這樣可以確保事務讀取的行,要么是在事務開始前已經存在的,要么是事務自身插入或者修改過的.
  b.行的刪除版本要么未定義,要么大于當前事務版本號,這可以確保事務讀取到的行,在事務開始之前未被刪除.
 只有a,b同時滿足的記錄,才能返回作為查詢結果.

DELETE

 InnoDB會為刪除的每一行保存當前系統(tǒng)的版本號(事務的ID)作為刪除標識.
  看下面的具體例子分析:
  第二個事務,ID為2;

start transaction;
select * from yang;  //(1)
select * from yang;  //(2)
commit; 

假設1

  假設在執(zhí)行這個事務ID為2的過程中,剛執(zhí)行到(1),這時,有另一個事務ID為3往這個表里插入了一條數據;
  第三個事務ID為3;

start transaction;
insert into yang values(NULL,'tian');
commit;

  這時表中的數據如下:

  然后接著執(zhí)行事務2中的(2),由于id=4的數據的創(chuàng)建時間(事務ID為3),執(zhí)行當前事務的ID為2,而InnoDB只會查找事務ID小于等于當前事務ID的數據行,所以id=4的數據行并不會在執(zhí)行事務2中的(2)被檢索出來,在事務2中的兩條select 語句檢索出來的數據都只會下表:

 假設2

  假設在執(zhí)行這個事務ID為2的過程中,剛執(zhí)行到(1),假設事務執(zhí)行完事務3后,接著又執(zhí)行了事務4;
  第四個事務:

start   transaction;  
delete from yang where id=1;
commit;  

  此時數據庫中的表如下:

  接著執(zhí)行事務ID為2的事務(2),根據SELECT 檢索條件可以知道,它會檢索創(chuàng)建時間(創(chuàng)建事務的ID)小于當前事務ID的行和刪除時間(刪除事務的ID)大于當前事務的行,而id=4的行上面已經說過,而id=1的行由于刪除時間(刪除事務的ID)大于當前事務的ID,所以事務2的(2)select * from yang也會把id=1的數據檢索出來.所以,事務2中的兩條select 語句檢索出來的數據都如下:

UPDATE
  InnoDB執(zhí)行UPDATE,實際上是新插入了一行記錄,并保存其創(chuàng)建時間為當前事務的ID,同時保存當前事務ID到要UPDATE的行的刪除時間.

 假設3
  假設在執(zhí)行完事務2的(1)后又執(zhí)行,其它用戶執(zhí)行了事務3,4,這時,又有一個用戶對這張表執(zhí)行了UPDATE操作:
  第5個事務:

start  transaction;
update yang set name='Long' where id=2;
commit;

  根據update的更新原則:會生成新的一行,并在原來要修改的列的刪除時間列上添加本事務ID,得到表如下:

  繼續(xù)執(zhí)行事務2的(2),根據select 語句的檢索條件,得到下表:

  還是和事務2中(1)select 得到相同的結果.

到此這篇關于mysql的MVCC多版本并發(fā)控制的實現的文章就介紹到這了,更多相關mysql MVCC多版本并發(fā)控制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL5.6下windows msi安裝詳細介紹

    MySQL5.6下windows msi安裝詳細介紹

    這篇文章主要介紹了MySQL5.6下windows msi安裝詳細介紹,介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下
    2016-08-08
  • MySQL數據導入導出的三種辦法總結

    MySQL數據導入導出的三種辦法總結

    當我們需要切換數據庫或備份數據時,導入和導出數據庫是一個常見的操作,下面這篇文章主要給大家介紹了關于MySQL數據導入導出的三種辦法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-05-05
  • MySQL 5.7.9 服務無法啟動-“NET HELPMSG 3534”的解決方法

    MySQL 5.7.9 服務無法啟動-“NET HELPMSG 3534”的解決方法

    這篇文章主要介紹了MySQL 5.7.9 服務無法啟動-“NET HELPMSG 3534”的解決方法,需要的朋友可以參考下
    2016-12-12
  • Mysql效率優(yōu)化定位較低sql的兩種方式

    Mysql效率優(yōu)化定位較低sql的兩種方式

    通過慢查詢日志定位那些執(zhí)行效率較低的 SQL 語句,用 --log-slow-queries[=file_name] 選項啟動時, mysqld 會 寫一個包含所有執(zhí)行時間超過 long_query_time 秒的 SQL 語句的日志文件,通過查看這個日志文件定位效率較低的 SQL
    2015-10-10
  • MySQL用戶賬戶管理和權限管理深入講解

    MySQL用戶賬戶管理和權限管理深入講解

    這篇文章主要給大家介紹了關于MySQL用戶賬戶管理和權限管理的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-12-12
  • 解決Mysql多行子查詢的使用及空值問題

    解決Mysql多行子查詢的使用及空值問題

    所謂多行子查詢,是指執(zhí)行查詢語句獲得的結果集中返回了多行數據的子查詢,今天通過本文給大家分享Mysql多行子查詢的使用及空值問題,感興趣的朋友一起看看吧
    2022-01-01
  • 查詢MySQL中的樹型表兩種方法

    查詢MySQL中的樹型表兩種方法

    在 MySQL中查詢樹型表(即具有層級結構的表)可以使用遞歸查詢或者使用嵌套集模型,下面介紹兩種方法查詢MySQL中的樹型表,感興趣的朋友一起看看吧
    2024-01-01
  • MySQL sysdate()函數的具體使用

    MySQL sysdate()函數的具體使用

    本文主要介紹了MySQL sysdate()函數的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • mysql設置更改root密碼、mysql服務器的連接、mysql常用命令的圖解

    mysql設置更改root密碼、mysql服務器的連接、mysql常用命令的圖解

    這篇文章主要介紹了mysql設置更改root密碼、mysql服務器的連接、mysql常用命令,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • MySQL中索引的優(yōu)化的示例詳解

    MySQL中索引的優(yōu)化的示例詳解

    索引是數據庫優(yōu)化最常用也是最重要的手段之一,通過索引通??梢詭椭脩艚鉀Q大多數的MySQL的性能優(yōu)化問題。本文主要來講講索引優(yōu)化的方法,希望對大家有所幫助
    2023-02-02

最新評論

柯坪县| 青田县| 呼伦贝尔市| 长阳| 伊金霍洛旗| 南平市| 论坛| 米林县| 黑河市| 南城县| 年辖:市辖区| 蕲春县| 永康市| 巴东县| 元朗区| 双峰县| 綦江县| 鄂尔多斯市| 祁阳县| 左权县| 稻城县| 双牌县| 无棣县| 玛纳斯县| 保靖县| 宁阳县| 嘉峪关市| 泰来县| 隆尧县| 巴马| 洛扎县| 望谟县| 云和县| 汾阳市| 澄城县| 县级市| 濮阳县| 锡林郭勒盟| 方城县| 宣化县| 桑植县|