MySQL - 多版本控制 MVCC 机制初探
文章目錄
- 生猛干貨
- MVCC (Multi-Version Concurrency Control)原理
- 快照讀與當前讀
- MVCC 多版本實現
- 總結
- 搞定MySQL
生猛干貨
帶你搞定MySQL實戰,輕松對應海量業務處理及高并發需求,從容應對大場面試
MVCC (Multi-Version Concurrency Control)原理
MySQL InnoDB 存儲引擎,實現的是基于多版本的并發控制協議——MVCC,而不是基于鎖的并發控制。
MVCC 最大的好處是讀不加鎖,讀寫不沖突。在讀多寫少的 OLTP(On-Line Transaction Processing)應用中,讀寫不沖突是非常重要的,極大的提高了系統的并發性能。
快照讀與當前讀
在 MVCC 并發控制中,讀操作可以分為兩類: 快照讀(Snapshot Read)與當前讀 (Current Read)。
-
快照讀:讀取的是記錄的可見版本(有可能是歷史版本),不用加鎖。
-
當前讀:讀取的是記錄的最新版本,并且當前讀返回的記錄,都會加鎖,保證其他事務不會再并發修改這條記錄。
MVCC 只在 Read Commited 和 Repeatable Read 兩種隔離級別下工作
如何區分快照讀和當前讀呢? 可以簡單的理解為:
-
快照讀:簡單的 select 操作,屬于快照讀,不需要加鎖。
-
當前讀:特殊的讀操作,插入/更新/刪除操作,屬于當前讀,需要加鎖。
MVCC 多版本實現
為了更直觀地理解 MVCC 的實現原理,這里舉一個“事務對某行記錄更新的過程”的案例來講解 MVCC 中多版本的實現。
假設 F1~F6 是表中字段的名字,1~6 是其對應的數據。后面三個隱含字段分別對應該行的隱含ID、事務號和回滾指針,如下圖所示
-
隱含 ID(DB_ROW_ID),6 個字節,當由 InnoDB 自動產生聚集索引時,聚集索引包括這個 DB_ROW_ID 的值
-
事務號(DB_TRX_ID),6 個字節,標記了最新更新這條行記錄的 Transaction ID,每處理一個事務,其值自動 +1
-
回滾指針(DB_ROLL_PT),7 個字節,指向當前記錄項的 Rollback Segment 的 Undo log記錄,通過這個指針才能查找之前版本的數據
【更新過程】
首先,假如這條數據是剛 INSERT 的,可以認為 ID 為 1,其他兩個字段為空。
然后,當事務 1 更改該行的數據值時,會進行如下操作,如下圖所示
-
用排他鎖鎖定該行;記錄 Redo log;
-
把該行修改前的值復制到 Undo log,即圖中下面的行;
-
修改當前行的值,填寫事務編號,使回滾指針指向 Undo log 中修改前的行
接下來,與事務 1 相同,此時 Undo log 中有兩行記錄,并且通過回滾指針連在一起。因此,如果 Undo log 一直不刪除,則會通過當前記錄的回滾指針回溯到該行創建時的初始內容,所幸的是在 InnoDB 中存在 purge 線程,它會查詢那些比現在最老的活動事務還早的 Undo log,并刪除它們,從而保證 Undo log 文件不會無限增長,如下圖所示
總結
MVCC機制的實現就是通過read-view機制與undo版本鏈比對機制,使得不同的事務會根據數據版本鏈對比規則讀取同一條數據在版本鏈上的不同版本數據。
搞定MySQL
總結
以上是生活随笔為你收集整理的MySQL - 多版本控制 MVCC 机制初探的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL - 存储引擎初探
- 下一篇: MySQL - 并发事务问题及解决方案