1. <i id="s6b2k"><small id="s6b2k"></small></i>
    <b id="s6b2k"><bdo id="s6b2k"></bdo></b>
  2. <wbr id="s6b2k"></wbr>

    mysql的MVCC多版本并發控制的實現_Mysql

    來源:腳本之家  責任編輯:小易  

    1 什么是MVCC

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

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

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

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

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

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

    2、InnoDB的MVCC實現機制

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

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

    select操作。

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

    行的刪除版本要么未定義,要么大于當前事務版本號。可以確保事務讀取的行,在事務開始之前未刪除。

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

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

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

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

    3、簡單的小例子

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

      假設系統的版本號從1開始.

    INSERT

      InnoDB為新插入的每一行保存當前系統版本號作為版本號.
      第一個事務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只會查找版本早于當前事務版本的數據行(也就是,行的系統版本號小于或等于事務的系統版本號),這樣可以確保事務讀取的行,要么是在事務開始前已經存在的,要么是事務自身插入或者修改過的.
      b.行的刪除版本要么未定義,要么大于當前事務版本號,這可以確保事務讀取到的行,在事務開始之前未被刪除.
     只有a,b同時滿足的記錄,才能返回作為查詢結果.

    DELETE

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

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

    假設1

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

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

      這時表中的數據如下:

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

     假設2

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

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

      此時數據庫中的表如下:

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

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

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

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

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

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

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

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

    您可能感興趣的文章:mysql多版本并發控制MVCC的實現

  3. 本文相關:
  4. 安裝和使用percona-toolkit來輔助操作mysql的基本教程
  5. 與mssql對比學習mysql的心得(一)--基本語法
  6. memcached的學習過程
  7. mysql insert的幾點操作(delayed,ignore,on duplicate key updat
  8. mysql查看與修改字符集的方法實例教程
  9. mysql以utf8存儲gbk輸出的實現方法提供
  10. 自用mysql自帶命令實現數據庫備份還原的方法
  11. mysql數據庫基于sysbench實現oltp基準測試
  12. 利用mysql系統數據庫做性能負載診斷的方法
  13. mysql內存及虛擬內存優化設置參數
  14. MySQL的多版本并發控制之什么是MVCC
  15. Mysql到底是怎么實現MVCC的
  16. 關于MySQL高并發處理機制是如何實現
  17. 請教一個mysql多用戶并發操作的問題
  18. mysql鎖能控制并發嗎
  19. mysql的單個連接支持并發執行sql嗎?
  20. mysql能不能實現多個不同的數據當同一個數據庫使用?
  21. mysql同時并發多個修改同一數據請求的問題?
  22. mysql事務隔離的問題?多線程并發怎么保證可靠
  23. mysql mvcc 加鎖是加在哪個版本
  24. 網站首頁網頁制作腳本下載服務器操作系統網站運營平面設計媒體動畫電腦基礎硬件教程網絡安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess數據庫文摘數據庫其它首頁mysql多版本并發控制mvcc的實現安裝和使用percona-toolkit來輔助操作mysql的基本教程與mssql對比學習mysql的心得(一)--基本語法memcached的學習過程mysql insert的幾點操作(delayed,ignore,on duplicate key updatmysql查看與修改字符集的方法實例教程mysql以utf8存儲gbk輸出的實現方法提供自用mysql自帶命令實現數據庫備份還原的方法mysql數據庫基于sysbench實現oltp基準測試利用mysql系統數據庫做性能負載診斷的方法mysql內存及虛擬內存優化設置參數mysql安裝圖解 mysql圖文安裝教程can""""t connect to mysql servwindows下mysql5.6版本安裝及配置mysql字符串截取函數substring的mysql創建用戶與授權方法mysql提示:the server quit withmysql——修改root密碼的4種方法mysql日期數據類型、時間類型使用mysql之timestamp(時間戳)用法mysql update語句的用法詳解淺談mysql 針對單張表的備份與還原mysql mycat 中間件安裝與使用mysql中文亂碼問題解決方案mysql longblob 類型存儲二進制數據 (修改mysql如何自動為查詢數據的結果編上序號詳mysql 5.7.15 安裝配置方法圖文教程(windmysql中的長事務示例詳解微信開發中mysql字符編碼問題mysql取出隨機數據mysql 數據庫常用命令 簡單超級實用版
    免責聲明 - 關于我們 - 聯系我們 - 廣告聯系 - 友情鏈接 - 幫助中心 - 頻道導航
    Copyright © 2017 www.yu113.com All Rights Reserved
    战天txt全集下载