【MYSQL】事務隔離級別以及InnerDB底層實現

事務隔離級別

讀未提交(Read Uncommitted)

允許事務讀取其他事務未提交的數據,可能會導致臟讀。

讀已提交(Read Committed)

一個事務只能看見已經提交的事務所做的更改,可以避免臟讀,但可能會遇到不可重復讀。

可重復讀(Repeatable Read)

在一個事務內,多次讀取同一數據的結果是一致的,即使其他事務在這期間對數據進行了修改和提交。此隔離級別可以防止不可重復讀,但可能遇到幻讀。

串行化(Serializable)

最高隔離級別,通過完全序列化事務來避免所有并發問題,這通常通過鎖定事務訪問的行來實現,性能開銷較大。

在這里插入圖片描述

MVCC的具體實現

隱藏字段

InnoDB存儲引擎在每行數據的后面添加了三個隱藏字段:

1、DB_TRX_ID(6字節):記錄創建或最后一次更新該行的事務ID。

在InnoDB中,每個事務都有一個唯一的事務ID,叫做transaction
id(縮寫trx_id),它是在事務開始時候向InnoDB的事務系統申請的,并且按照申請順序嚴格遞增。在這里DB_TRX_ID就表示最近一次對該行數據作修改(insert或update)的事務ID。至于delete操作,InnoDB認為是一個update操作,不過會更新一個另外的刪除位,將行表示為deleted,并非真正刪除。

2、DB_ROLL_PTR(7字節):回滾指針,指向當前記錄行的undo log信息,用于回滾該行的舊版本

3、DB_ROW_ID(6字節):行標識,如果表沒有顯式的主鍵或唯一索引時使用。這個字段和MVCC關系不大,所以我們在這里不必關注。

這是隨著新行插入而單調遞增的行ID。理解:當表沒有主鍵或唯一非空索引時,InnoDB就會使用這個行ID自動產生聚簇索引。如果表有主鍵或唯一非空索引,聚簇索引就不會包含這個行ID了。

Read View(一致性視圖)

read view的真正作用是用來做可見性判斷的,里面保存了“對本事務不可見的其他活躍事務”。

按照可重復讀的定義,一個事務啟動的時候,能夠看到所有已經提交的事務結果。但是之后,這個事務執行期間,其他事務的更新對它不可見。因此,一個事務只需要在啟動的時候聲明說,“以我啟動的時刻為準,如果一個數據版本是在我啟動之前生成的,就認;如果是我啟動以后才生成的,我就不認,我必須要找到它的上一個版本”。當然,如果“上一個版本”也不可見,那就得繼續往前找。

Read View有4個重要的字段

1、m_ids :創建 Read View 時,當前數據庫中「活躍事務(啟動了但沒提交)」的事務 id 列表,注意是一個列表。
2、min_trx_id :創建 Read View 時,當前數據庫中「活躍事務」中事務 id 最小的事務,也就是 m_ids 的最小值。
3、max_trx_id :不是 m_ids 的最大值,而是創建 Read View 時當前數據庫中應該給下一個事務的 id 值,也就是全局事務中最大的事務 id 值 + 1;
4、creator_trx_id :指的是創建該 Read View 的事務的事務 id。

在這里插入圖片描述
在可見性的實現上,InnoDB為每個事務構建了一個數組,用來保存這個事務啟動瞬間,當前正在”活躍“的所有事務ID。”活躍“指的是啟動了但還沒提交。

數組里面事務 ID 的最小值記為低水位,當前系統里面已經創建過的事務 ID 的最大值加 1 記為高水位。這個視圖數組和高水位,就組成了當前事務的一致性視圖(read-view)。這里需要注意:低水位到高水位之間的某些事務ID是沒在數組中的,沒在的原因是它們已經提交了,比如低水位為100,高水位為106,而數組中可能只有100、101、103、105這四個事務ID,104和102不在的原因是因為在當前事務啟動時,這兩個事務已經提交了。

![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/08fb5599b2f74ecea93f2893b603cacd.png在這里插入圖片描述
這樣,對于當前事務的啟動瞬間來講,一個數據的DB_TRX_ID,存在以下幾種可能:

1、如果落在綠色部分,表示這個版本是已提交的事務或者是當前事務自己生成的,這個數據是可見的;
2、如果落在紅色部分,表示這個版本是由將來啟動的事務生成的,是肯定不可見的;(需要去undo log找可見版本)
3、如果落在黃色部分,那就包括兩種情況:
a. 如果DB_TRX_ID在數組中(也就說明這個事務在當前事務啟動時還活躍),那么表示這個這個版本是由還沒提交的事務生成的,不可見;(需要去undo log找可見版本)
b. 若 row trx_id 不在數組中,表示這個版本是已經提交了的事務生成的,可見。

讀提交和可重復讀的read view產生區別:

在innodb中的可重復讀級別, 只有事務在begin之后,執行第一條select(讀操作)時, 才會創建一個快照(read view),將當前系統中活躍的其他事務記錄起來;并且事務之后都是使用的這個快照,不會重新創建,直到事務結束。
在innodb中的讀提交級別, 事務在begin之后,執行每條select(讀操作)語句時,快照會被重置,即會重新創建一個快照(read view)。

undo log

undo log中存儲的是老版本數據,當一個事務需要讀取記錄行時,如果當前記錄行不可見,可以順著undo log鏈找到滿足其可見性條件的記錄行版本,這也是InnoDB利用”所有數據都有多個版本“這個特性,來實現可見性的核心。

下圖記錄了一行數據被多個事務連續更新后的狀態(圖中的row trx_id就是上面提到的DB_TRX_ID):

在這里插入圖片描述

圖中虛線框內是同一行數據的四個版本,當前最新版本是 V4,k 的值是 22,它是被 事務ID 為 25 的事務更新的,因此它的 DB_TRX_ID 是 25。

在上圖中,三個虛線箭頭其實就代表了undo log;V1、V2、V3其實并不是物理上真實存在的,而是每次需要的時候根據當前版本和undo log計算出來的,比如,需要V2的時候,就是通過V4依次執行U3、U2計算出來。

比如,假如有一個事務的低水位是18,它要讀取上面圖中的數據,那么當它訪問時候,獲取了當前的DB_TRX_ID為25,假設這個25在數組中(說明這個25在事務啟動時依然活躍),那么因為25高于低水位,所以對于當前事務來說不可見,于是這個事務就會從V4通過U3計算得出V3,V3的DB_TRX_ID=17小于18,所以這個數據是可見的,所以對于當前事務來講,這個事務的值通過undo log就可以構造出來,為11。

大多數對數據的變更操作包含insert/update/delete,在InnoDB里,undo log分為如下兩類:

insert undo log:事務insert新記錄時產生的undo log,只在事務回滾時需要,并且在事務提交后就可以立即丟棄
update undo log:事務對記錄進行delete和update操作時產生的undo log,不僅在事務回滾時需要,快照讀也需要,只有當數據庫所使用的快照不涉及該日志記錄,對應的回滾日志才會被purge線程刪除。

Purge線程: 為了實現InnoDB的MVCC機制,更新或者刪除操作都只是設置一下舊記錄的deleted_bit,并不真正將舊記錄刪除。
為了節省磁盤空間,InnoDB有專門的purge線程來清理deleted_bit為true的記錄。purge線程自己也維護了一個read
view,如果某個記錄的deleted_bit為true,并且DB_TRX_ID相對于purge線程的read
view可見,那么這條記錄一定是可以被安全清除的。

在MySQL InnoDB引擎中,各隔離級別是如何實現的呢?

讀未提交(Read Uncommitted)

InnoDB實際上并不直接支持此隔離級別,因為這會引發臟讀、不可重復讀和幻讀等問題。如果要實現的話,數據庫可允許事務讀取其他事務尚未提交的數據,不做任何額外的并發控制即可。

讀已提交(Read Committed)

InnoDB通過多版本并發控制(MVCC)機制實現。在讀已提交的隔離級別下,每個事務在每次讀取數據時都會生成一個自己的讀視圖(Read View)。這個視圖是由事務開始時正在提交的事務所影響的數據項的快照構成的。

具體實現上,MySQL會在每行數據后添加3個隱藏的列來實現MVCC,這3個列分別是:
1、DB_TRX_ID:記錄創建或最后一次更新該行的事務ID。
2、DB_ROLL_PTR:指向回滾段的指針,用于回滾該行的舊版本。
3、DB_ROW_ID:行標識,如果表沒有顯式的主鍵或唯一索引時使用。這個字段和MVCC關系不大,所以我們在這里不必關注。

當事務需要讀取數據時,它會讀取DB_TRX_ID不為當前事務ID的行,即已提交事務的數據。
在這里插入圖片描述

可重復讀(Repeatable Read)

這是InnoDB默認的隔離級別,InnoDB也是通過MVCC機制來實現可重復讀隔離級別的。可重復讀隔離級別是啟動事務時生成一個 Read View,然后整個事務期間都在用這個 Read View。

MVCC機制為每個事務分配一個唯一的事務ID,并記錄每行數據的創建版本號和刪除版本號,確保在同一個事務內多次讀取同一數據時結果一致,解決了不可重復讀的問題。MVCC通過數據行的隱藏列(例如事務ID、回滾指針等)以及undo日志來管理多個事務對同一數據的并發訪問,確保事務看到的數據在事務期間保持一致,即便其他事務已經修改或刪除了這些數據。

MVCC通過維護數據的多個版本來實現事務的隔離性,而無需依賴傳統的鎖機制(雖然InnoDB也使用鎖,但主要是為了解決寫沖突)。每個事務看到的數據是由該事務的開始時間點決定的,這保證了在可重復讀級別下,即使其他事務提交了新的數據,當前事務仍然能夠看到它開始時的數據狀態,避免了臟讀、不可重復讀的問題,但幻讀仍可能在某些場景下發生,除非使用了Next-Key Locks或者將隔離級別調整為串行化。

選擇該隔離級別是因為主從同步如果先后讀取不一致,可能會出現主從同步問題。

串行化(Serializable)

雖然InnoDB支持串行化隔離級別,但實際應用中較少使用,因為它通過完全鎖定讀取的行來防止并發修改,這會嚴重影響系統的并發性能。在串行化級別下,InnoDB會對涉及的行加鎖,“寫”會加“寫鎖”,“讀”會加“讀鎖”。當出現讀寫鎖沖突的時候,后訪問的事務必須等前一個事務執行完成,阻止其他事務并發修改,以此實現最高的隔離性。

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

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

相關文章

win7系統快速安裝python

下載安裝包 建議選擇python3.8左右的,我下載的是3.7.8,最新版本的pythonwin7可能不支持 python網址 下拉尋找 安裝python 1.雙擊安裝包 更換完地址選擇安裝(install) 安裝完成后點擊close即可 測試是否安裝成功 1.winr快捷鍵打開黑窗口輸入cmd …

idea創建的maven項目pom文件引入的坐標報紅原因

如下所示 我們在引入某些依賴坐標的時候,即使點擊了右上角的mavne刷新之后還是報紅。 其實這是正常現象,實際上是我們的本地倉庫當中沒有這些依賴坐標,而idea就會通過報紅來標記這些依賴來說明在我們的本地倉庫是不存在的。 那有的同學就會…

【HICE】dns正向解析

1.編輯倉庫 2.掛載 3.下載軟件包 4.編輯named.conf 5.編輯named.haha 6.重啟服務 7.驗證本地域名是否解析

1116. 打印零與奇偶數

題目描述 現有函數 printNumber 可以用一個整數參數調用,并輸出該整數到控制臺。 例如,調用 printNumber(7) 將會輸出 7 到控制臺。 給你類 ZeroEvenOdd 的一個實例,該類中有三個函數:zero、even 和 odd 。ZeroEvenOdd 的相同實…

六、快速啟動框架:SpringBoot3實戰-個人版

六、快速啟動框架:SpringBoot3實戰 文章目錄 六、快速啟動框架:SpringBoot3實戰一、SpringBoot3介紹1.1 SpringBoot3簡介1.2 系統要求1.3 快速入門1.4 入門總結回顧復習 二、SpringBoot3配置文件2.1 統一配置管理概述2.2 屬性配置文件使用2.3 YAML配置文…

短劇app開發搭建需要哪些資質證件?

短劇APP需要辦理的資質包括增值電信業務經營許可證(ICP)、網絡文化經營許可證(文網文)、廣播電視節目制作經營許可證,以及軟件著作權(軟著)。 增值電信業務經營許可證(ICP&#xff…

ODOO17的郵件機制-系統自動推送修改密碼的郵件

用戶收到被要求重置密碼的郵件: 我們來分析一下ODOO此郵件的工作機制: 1、郵件模板定義 2、渲染模板的函數: 3、調用此函數的機制: 當用戶移除或增加了信任的設備(如電腦、手機端等),系統會自…

Python爬蟲之什么是逆向工程?逆向是什么?

Python爬蟲之什么是逆向工程?逆向是什么? 在Python爬蟲領域,逆向工程是一種重要的技術手段,尤其在面對復雜的網站結構和加密的數據時。逆向工程通常涉及對目標網站的分析,包括其前端代碼、后端邏輯、數據傳輸方式等&am…

CentOS 7.9 停止維護(2024-6-30)后可用在線yum源 —— 筑夢之路

眾所周知,centos 7 在2024年6月30日,生命周期結束,官方不再進行支持維護,而很多環境一時之間無法完全更新替換操作系統,因此對于yum源還是需要的,特別是對于互聯網環境來說,在線yum源使用方便很…

三級_網絡技術_01_網絡系統結構與設計的基本原則

1.下列關于RPR技術的描述中,錯誤的是()。 RPR與FDDI一樣使用雙環結構 在RPR環中,源節點向目的節點成功發出的數據幀要由目的節點從環中收回 RPR環中每一個節點都執行MPLS公平算法 RPR環能夠在50ms內實現自愈 2.下列關于RPR技術的描述中,…

從0到1:培訓老師預約小程序開發筆記二

背景調研 培訓老師預約小程序: 教師和學生可以更便捷地安排課程,并提升教學質量和學習效果,使之成為管理和提升教學效果的強大工具。培訓老師可以在小程序上設置自己的可預約時間,學員可以根據老師的日程安排選擇合適的時間進行預…

記錄第一次使用air熱更新golang項目

下載 go install github.com/cosmtrek/airlatest 下載時提示: module declares its path as: github.com/air-verse/air but was required as: github.com/cosmtrek/air 此時,需要在go.mod中加上這么一句: replace github.com/cosmtrek/air &…

如何使用Pip從Git倉庫安裝Python包:深入探索遠程依賴管理

如何使用Pip從Git倉庫安裝Python包:深入探索遠程依賴管理 Python的包管理工具Pip使得安裝和管理Python庫變得非常簡單。有時,我們需要安裝那些尚未發布到PyPI的包,或者想要嘗試最新的開發版本。這時,可以直接從Git倉庫安裝包。本…

qt QGridLayout 簡單實驗1

1.概要 2.實驗 2.1 實驗1 簡單實驗跨行 2.1.1 代碼 #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~W…

STM32 - 內存分區與OTA

最近搞MCU&#xff0c;發現它與SOC之間存在諸多差異&#xff0c;不能沿用SOC上一些技術理論。本文以STM L4為例&#xff0c;總結了一些STM32 小白入門指南。 標題MCU沒有DDR&#xff1f; 是的。MCU并沒有DDR&#xff0c;而是讓代碼存儲在nor flash上&#xff0c;臨時變量和棧…

yolov5實例分割跑通以及C#讀取yolov5_Seg實例分割轉換onnx進行檢測部署

一、首先需要訓練yolov5_seg的模型&#xff0c;可以去網上學習&#xff0c;或者你直接用我的&#xff0c; 訓練環境和yolov5—7.0的環境一樣&#xff0c;你可以直接拷過來用。 yolov5_seg算法 鏈接&#xff1a;https://pan.baidu.com/s/1m-3lFWRHwg5t8MmIOKm4FA 提取碼&…

【MySQL】1.初識MySQL

初識MySQL 一.MySQL 安裝1.卸載已有的 MySQL2.獲取官方 yum 源3.安裝 MySQL4.登錄 MySQL5.配置 my.cnf 二.MySQL 數據庫基礎1.MySQL 是什么&#xff1f;2.服務器&#xff0c;數據庫和表3.mysqld 的層狀結構4.SQL 語句分類 一.MySQL 安裝 1.卸載已有的 MySQL //查詢是否有相關…

《Windows API每日一練》8.3 scrollbar控件

在第三章SYSMETS2.C實例中&#xff0c;我們是通過CreateWindow函數創建窗口的參數窗口樣式中添加垂直或水平滾動條。本節我們將講述作為子窗口控件的滾動條。 本節必須掌握的知識點&#xff1a; 滾動條類 滾動條控件和著色 8.3.1 滾動條類 ■窗口滾動條與滾動條控件的異同 …

Python常量與變量的終極指南:從基礎到進階的15個要點

今天&#xff0c;我們將一起揭開Python中最基本但也極其重要的概念——常量與變量的神秘面紗。別擔心&#xff0c;我會用最簡單直白的語言&#xff0c;讓你從入門到略有小成&#xff0c;一步步掌握這些核心知識。準備好你的筆記本&#xff0c;讓我們開始這場Python之旅吧&#…

在Linux環境下搭建Redis服務結合內網穿透實現通過GUI工具遠程管理數據庫

文章目錄 前言1. 安裝Docker步驟2. 使用docker拉取redis鏡像3. 啟動redis容器4. 本地連接測試4.1 安裝redis圖形化界面工具4.2 使用RDM連接測試 5. 公網遠程訪問本地redis5.1 內網穿透工具安裝5.2 創建遠程連接公網地址5.3 使用固定TCP地址遠程訪問 前言 本文主要介紹如何在Li…