日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

关于mysql行级锁中MVCC的一些理解

發布時間:2025/4/16 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于mysql行级锁中MVCC的一些理解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、MVCC簡介

MVCC (Multiversion Concurrency Control),即多版本并發控制技術,它使得大部分支持行鎖的事務引擎,不再單純的使用行鎖來進行數據庫的并發控制,取而代之的是把數據庫的行鎖與行的多個版本結合起來,只需要很小的開銷,就可以實現非鎖定讀,從而大大提高數據庫系統的并發性能

讀鎖:也叫共享鎖、S鎖,若事務T對數據對象A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S 鎖。這保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。

寫鎖:又稱排他鎖、X鎖。若事務T對數據對象A加上X鎖,事務T可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到T釋放A上的鎖。這保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A。

表鎖:操作對象是數據表。Mysql大多數鎖策略都支持(常見mysql innodb),是系統開銷最低但并發性最低的一個鎖策略。事務t對整個表加讀鎖,則其他事務可讀不可寫,若加寫鎖,則其他事務增刪改都不行。

行級鎖:操作對象是數據表中的一行。是MVCC技術用的比較多的,但在MYISAM用不了,行級鎖用mysql的儲存引擎實現而不是mysql服務器。但行級鎖對系統開銷較大,處理高并發較好。

一句話講,MVCC就是用?同一份數據臨時保留多版本的方式?的方式,實現并發控制。

這里留意到 MVCC 關鍵的兩個點:

  • 在讀寫并發的過程中如何實現多版本;
  • 在讀寫并發之后,如何實現舊版本的刪除(畢竟很多時候只需要一份最新版的數據就夠了);
  • 二、MVCC實現原理

    innodb MVCC主要是為Repeatable-Read事務隔離級別做的。在此隔離級別下,A、B客戶端所示的數據相互隔離,互相更新不可見

    了解innodb的行結構、Read-View的結構對于理解innodb mvcc的實現由重要意義

    innodb存儲的最基本row中包含一些額外的存儲信息 DATA_TRX_ID,DATA_ROLL_PTR,DB_ROW_ID,DELETE BIT

    • 6字節的DATA_TRX_ID 標記了最新更新這條行記錄的transaction id,每處理一個事務,其值自動+1

    • 7字節的DATA_ROLL_PTR 指向當前記錄項的rollback segment的undo log記錄,找之前版本的數據就是通過這個指針

    • 6字節的DB_ROW_ID,當由innodb自動產生聚集索引時,聚集索引包括這個DB_ROW_ID的值,否則聚集索引中不包括這個值.,這個用于索引當中
    • DELETE BIT位用于標識該記錄是否被刪除,這里的不是真正的刪除數據,而是標志出來的刪除。真正意義的刪除是在commit的時候

    具體的執行過程

    begin->用排他鎖鎖定該行->記錄redo log->記錄undo log->修改當前行的值,寫事務編號,回滾指針指向undo log中的修改前的行

    上述過程確切地說是描述了UPDATE的事務過程,其實undo log分insert和update undo log,因為insert時,原始的數據并不存在,所以回滾時把insert undo log丟棄即可,而update undo log則必須遵守上述過程

    下面分別以select、delete、 insert、 update語句來說明

    SELECT

    Innodb檢查每行數據,確保他們符合兩個標準:

    1、InnoDB只查找版本早于當前事務版本的數據行(也就是數據行的版本必須小于等于事務的版本),這確保當前事務讀取的行都是事務之前已經存在的,或者是由當前事務創建或修改的行

    2、行的刪除操作的版本一定是未定義的或者大于當前事務的版本號,確定了當前事務開始之前,行沒有被刪除

    符合了以上兩點則返回查詢結果。

    INSERT

    InnoDB為每個新增行記錄當前系統版本號作為創建ID。

    DELETE

    InnoDB為每個刪除行的記錄當前系統版本號作為行的刪除ID。

    UPDATE

    InnoDB復制了一行。這個新行的版本號使用了系統版本號。它也把系統版本號作為了刪除行的版本。

    說明

    insert操作時 “創建時間”=DB_ROW_ID,這時,“刪除時間 ”是未定義的;

    update時,復制新增行的“創建時間”=DB_ROW_ID,刪除時間未定義,舊數據行“創建時間”不變,刪除時間=該事務的DB_ROW_ID;

    delete操作,相應數據行的“創建時間”不變,刪除時間=該事務的DB_ROW_ID;

    select操作對兩者都不修改,只讀相應的數據

    三、對于MVCC的總結

    上述更新前建立undo log,根據各種策略讀取時非阻塞就是MVCC,undo log中的行就是MVCC中的多版本,這個可能與我們所理解的MVCC有較大的出入,一般我們認為MVCC有下面幾個特點:
    • 每行數據都存在一個版本,每次數據更新時都更新該版本
    • 修改時Copy出當前版本隨意修改,各個事務之間無干擾
    • 保存時比較版本號,如果成功(commit),則覆蓋原記錄;失敗則放棄copy(rollback)
    就是每行都有版本號,保存時根據版本號決定是否成功,聽起來含有樂觀鎖的味道,而Innodb的實現方式是:
    • 事務以排他鎖的形式修改原始數據
    • 把修改前的數據存放于undo log,通過回滾指針與主數據關聯
    • 修改成功(commit)啥都不做,失敗則恢復undo log中的數據(rollback)
    二者最本質的區別是,當修改數據時是否要排他鎖定,如果鎖定了還算不算是MVCC?? Innodb的實現真算不上MVCC,因為并沒有實現核心的多版本共存,undo log中的內容只是串行化的結果,記錄了多個事務的過程,不屬于多版本共存。但理想的MVCC是難以實現的,當事務僅修改一行記錄使用理想的MVCC模式是沒有問題的,可以通過比較版本號進行回滾;但當事務影響到多行數據時,理想的MVCC據無能為力了。 比如,如果Transaciton1執行理想的MVCC,修改Row1成功,而修改Row2失敗,此時需要回滾Row1,但因為Row1沒有被鎖定,其數據可能又被Transaction2所修改,如果此時回滾Row1的內容,則會破壞Transaction2的修改結果,導致Transaction2違反ACID。 理想MVCC難以實現的根本原因在于企圖通過樂觀鎖代替二段提交。修改兩行數據,但為了保證其一致性,與修改兩個分布式系統中的數據并無區別,而二提交是目前這種場景保證一致性的唯一手段。二段提交的本質是鎖定,樂觀鎖的本質是消除鎖定,二者矛盾,故理想的MVCC難以真正在實際中被應用,Innodb只是借了MVCC這個名字,提供了讀的非阻塞而已。

    參考文章

    https://www.cnblogs.com/chenpingzhao/p/5065316.html

    轉載于:https://www.cnblogs.com/FXqufei/p/9795435.html

    總結

    以上是生活随笔為你收集整理的关于mysql行级锁中MVCC的一些理解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。