MySQL MVCC

總結自小林coding,bojiangzhou

臟讀、不可重復讀、幻讀 說的都是并發讀取的問題,最簡單的方式就是給記錄加一把鎖,不管是更新、讀取記錄都需要競爭到這把鎖之后才能操作。但這種方式的并發性能可想而知會有多么低。

于是 InnoDB 就設計了MVCC來解決并發讀取的問題,MVCC 就是多版本并發控制(Multi-Version Concurrency Control)。在 RCRR 這兩種隔離級別下執行SELECT查詢時,通過訪問記錄的版本鏈,而不需要加鎖,這樣使得不同事務的讀-寫操作可以并發執行,從而提升數據庫的性能。

MVCC需要依賴undo log版本鏈:

  • 對于使用 RU 隔離級別的事務來說,由于可以讀到未提交事務修改過的記錄,所以直接讀取記錄的最新版本就好了。

  • 對于使用 RCRR 隔離級別的事務來說,都必須保證讀到已提交事務修改過的記錄,如果另一個事務修改的記錄還未提交,是不能直接讀取記錄的最新版本的,此時就可以沿著undo版本鏈查找當前事務可見的版本。

ReadView

那如何判斷版本鏈上的哪個版本是當前事務可見的呢?

InnoDB 設計了一個 ReadView,在執行一個事務的時候就會創建一個ReadView。ReadView 有四個關鍵屬性:

  • m_ids :指的是在創建 Read View 時,當前數據庫中「活躍事務」的事務 id 列表,注意是一個列表,“活躍事務”指的就是,啟動了但還沒提交的事務。

  • min_trx_id :指的是在創建 Read View 時,當前數據庫中「活躍事務」中事務 id 最小的事務,也就是 m_ids 的最小值。

  • max_trx_id :這個并不是 m_ids 的最大值,而是創建 Read View 時當前數據庫中應該給下一個事務的 id 值,也就是全局事務ID(Max Trx Id);

  • creator_trx_id :指的是創建該 Read View 的事務的事務 id。事務中只有在執行了增刪改操作時才會分配一個事務ID,如果是一個只讀事務,那 creator_trx_id 默認就為0

MVCC 流程

undo log 中的隱藏列 trx_id 表示產生這條 undo log 時的事務的事務ID。判斷此版本是否可訪問的依據就是用 undo log 中的 trx_id 屬性值與 ReadView 中的各個屬性做比較。

通過如下步驟來判斷版本是否可被訪問:

  • ① 如果 trx_id 等于 creator_trx_id ,說明當前事務在訪問它自己修改過的記錄,所以該版本記錄可以被當前事務訪問。(可以自己訪問自己的事務)

  • ② 如果 trx_id 小于 min_trx_id,說明生成該版本記錄的事務在當前事務生成 ReadView 前已經提交,所以該版本記錄可以被當前事務訪問。(可以訪問已經提交的事務)

  • ③ 如果 trx_id 大于或等于max_trx_id,說明生成該版本記錄的事務在當前事務生成 ReadView 后才開啟,所以該版本記錄不可以被當前事務訪問。(不能訪問“未來”的事務)

  • ④ 如果 trx_idmin_trx_idmax_trx_id 之間,此時再判斷一下 trx_id 是不是在 m_ids 列表中,如果在,說明創建 ReadView 時生成該版本記錄的事務還是活躍的,該版本記錄不可以被訪問(不能訪問同期未提交的事務);如果不在,說明創建 ReadView 時生成該版本記錄的事務已經被提交,該版本記錄可以被訪問。(可以訪問同期已提交的事務)

RC 和 RR

READ COMMITTEDREPEATABLE READ 隔離級別的區別就是它們生成ReadView的時機不同。

  • READ COMMITTED 是每次查詢前都會生成一個獨立的 ReadView。

  • REPEATABLE READ 則只在第一次查詢前生成一個 ReadView,之后的查詢都重復使用這個 ReadView。

  • READ UNCOMMITTED 則不需要生成 ReadView,直接讀取行記錄的數據。

快照讀和當前讀

簡單的SELECT查詢,是讀取undo版本鏈上的一個快照版本,可以稱為快照讀一致性非鎖定讀。由于是讀取的快照,因此在RR隔離級別下可以避免幻讀的發生。

但如果是INSERT、DELETE、UPDATE語句,例如下面的SQL,這個 UPDATE 語句會更新 balance=0 的記錄,這種方式就稱為當前讀,讀取的是最新的數據。當前讀能讀取到別的事務已提交的修改,就可能會產生幻讀的問題。UPDATE account SET balance=100 WHERE balance = 0;

而對于幻讀現象,不建議將隔離級別升級為串行化,因為這會導致數據庫并發時性能很差。MySQL InnoDB 引擎的默認隔離級別雖然是「可重復讀」,但是它很大程度上避免幻讀現象,解決的方案有兩種:

  • 針對快照讀(普通 select 語句),是通過 MVCC 方式解決了幻讀,因為可重復讀隔離級別下,事務執行過程中看到的數據,一直跟這個事務啟動時看到的數據是一致的,即使中途有其他事務插入了一條數據,是查詢不出來這條數據的,所以就很好了避免幻讀問題。

  • 針對當前讀(select ... for update 等語句),是通過 next-key lock(記錄鎖+間隙鎖)方式解決了幻讀,因為當執行 select ... for update 語句的時候,會加上 next-key lock,如果有其他事務在 next-key lock 鎖范圍內插入了一條記錄,那么這個插入語句就會被阻塞,無法成功插入,所以就很好了避免幻讀問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/43460.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/43460.shtml
英文地址,請注明出處:http://en.pswp.cn/web/43460.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C#——二進制流序列化和反序列化

C#二進制流序列化和反序列化 在C#中,可以使用BinaryFormatter來進行二進制的序列化和反序列化。 首先,定義一個可序列化的類 [Serializable] public class MyObject {public int IntProperty { get; set; }public string StringProperty { get; set; …

ubuntu 上配置開機自動啟動ssh

一般安裝了就會自動啟動。但是各種rc.local, cron都測試了一下,還是這個systemd有效 使用 systemd 服務 創建文件 sudo nano /etc/systemd/system/custom-ssh.service [Unit] DescriptionStart SSH service at boot Afternetwork.target[Service] ExecStart/usr/…

軟件開發(續).NET框架

1.解釋一下.NET框架中的CLR(公共語言運行時)是什么,以及它的作用和功能是什么? CLR(Common Language Runtime)的概念和作用 在.NET框架中,CLR(Common Language Runtime&#xff09…

代碼優化(2)——小程序登錄

驗證身份的時候,依賴的是cookie里面的token $this->request->server(HTTP_TOKEN,$this->request->request(token, \think\Cookie::get(token))) 小程序的交互權限驗證,一般放到header里面進行鑒權,極少是通過cookie來傳遞參數驗證…

一起來了解深度學習中的“梯度”

文章目錄 前言一、什么是梯度?二、梯度計算三、優化算法四、示例五、梯度的作用六、形象化解釋七、如果完全不懂公式可以實現這個算法嗎?1. 使用 Hugging Face Transformers 實現深度學習任務1) 安裝庫2) 加載預訓練模型和分詞器3) 準備數據4) 進行推理5…

LeetCode HOT100(二)雙指針

移動0 給定一個數組 nums,編寫一個函數將所有 0 移動到數組的末尾,同時保持非零元素的相對順序。 請注意 ,必須在不復制數組的情況下原地對數組進行操作。 輸入: nums [0,1,0,3,12] 輸出: [1,3,12,0,0] 解法1:雙指針交換 指針L&…

“論基于構件的軟件開發方法及其應用”寫作框架,軟考高級論文,系統架構設計師論文

論文真題 基于構作的軟件開發 (Component-Based Software Development,CBSD) 是一種基于分布對象技術、強調通過可復用構件設計與構造軟件系統的軟件復用途徑。基于構件的軟件系統中的構件可以是COTS (Commercial-Off-the-Shelf)構件&#x…

Spring Boot輕松整合Minio實現文件上傳下載功能

一、Linux 安裝Minio 安裝 在/root/xxkfz/soft目錄下面創建文件minio文件夾,進入minio文件夾,并創建data目錄; [rootxxkfz soft]# mkdir minio [rootxxkfz soft]# cd minio [rootxxkfz minio]# mkdir data 執行如下命令進行下載 [rootxx…

Java內存劃分詳解:從基礎到進階

Java內存劃分詳解:從基礎到進階 1. 程序計數器(Program Counter Register)2. Java虛擬機棧(Java Virtual Machine Stack)3. 堆(Heap)4. 方法區(Method Area)5. 運行時常量…

DDD架構面試問題

基礎概念 什么是領域驅動設計(DDD)? 請解釋一下DDD的核心思想和目標。 DDD中的領域(Domain)是什么? 請描述一下領域的概念以及它在軟件開發中的重要性。 什么是限界上下文(Bounded Context&am…

ArduPilot開源代碼之OpticalFlow_backend

ArduPilot開源代碼之OpticalFlow_backend 1. 源由2. Library設計3. 重要例程3.1 OpticalFlow_backend::_update_frontend3.2 OpticalFlow_backend::_applyYaw 4. 總結5. 參考資料 1. 源由 光流計是一種低成本定位傳感器,所有的光流計設備傳感驅動代碼抽象公共部分統…

[計網初識1] TCP/UDP

學習內容 1.TCP建立鏈接的3次握手,斷開連接的4次揮手 2.TCP報文段組成 內容 1.TCP 建立連接的3次握手? 假設主動方是客戶端,被動方是服務端。 第一次 客戶端給服務端發送 “hello,我是客戶端” (TCP段中 SYN1) 第二次 服務端給客戶端發送"我接…

從零開始的python學習生活2

接上封裝 class Phone:__volt0.5def __keepsinglecore(self):print("讓cpu以單核運行")def if5G(self):if self.__volt>1:print("5G通話已開啟")else:self.__keepsinglecore()print("電量不足,無法使用5G通話,已經設置為單…

Django項目創建的準備工作【 2 】

【 一 】調整后端目錄 #1 目錄結構 """ ├── luffy_api├── logs/ # 項目運行時/開發時日志目錄 - 包├── manage.py # 腳本文件├── luffy_api/ # 項目主應用,開發時的代碼保存 - 包├── apps/ …

【Git基本操作】添加文件 | 修改文件 | 及其各場景下.git目錄樹的變化

目錄 1. 添加文件&add操作和commit操作 2. .git樹狀目錄的變化 3. git其他操作 4. 修改文件 4.1 git status 4.2 git diff 1. 添加文件&add操作和commit操作 add操作:將工作區中所有文件的修改內容 添加進版本庫的暫存區中。commit操作:…

云端編碼:將您的技術API文檔安全存儲在iCloud的最佳實踐

云端編碼:將您的技術API文檔安全存儲在iCloud的最佳實踐 作為一名技術專業人士,管理不斷增長的API文檔庫是一項挑戰。iCloud提供了一個無縫的解決方案,允許您在所有設備上存儲、同步和訪問您的個人技術API文檔。本文將指導您如何在iCloud中高…

系統服務綜合實驗(dns服務,nfs服務)

題目:現有主機 node01 和 node02,完成如下需求: 1、在 node01 主機上提供 DNS 和 WEB 服務 2、dns 服務提供本實驗所有主機名解析 3、web服務提供 www.rhce.com 虛擬主機 4…

three-tile: 1. 第一個three-tile程序

上篇介紹了:three-tile: 一個開源的輕量級三維瓦片庫-CSDN博客 three-tile 是一個開源的輕量級三維瓦片庫,它基于threejs使用typescript開發,提供一個三維地形模型,能輕松給你的應用增加三維瓦片地圖。 項目地址&…

C#知識|賬號管理系統:UI層-添加賬號窗體設計思路及流程。

哈嘍,你好啊,我是雷工! 前邊練習過詳情頁窗體的設計思路及流程: 《C#知識|上位機UI設計-詳情窗體設計思路及流程(實例)》 本節練習添加賬號窗體的UI設計,以下為學習筆記。 01 效果展示 02 添加窗體 在UI層添加Windows窗體,設置名稱為:FrmAddAcount.cs 設置窗體屬…

Nginx七層(應用層)反向代理:UWSGI代理uwsgi_pass篇

Nginx七層(應用層)反向代理 UWSGI代理uwsgi_pass篇 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this a…