搜尋
首頁資料庫mysql教程MySQL跨行事務模型(圖文詳解)

MySQL跨行事務模型(圖文詳解)

MySQL事務模型在網路上也有很多的介紹,在寫這篇文章之前本人也翻看了很多資料作為參考,以期讓自己理解的更加深入全面。看了大多數介紹文章之後發現部分文章並不完整,例如有的只介紹了幾種隔離等級下MySQL的表現,並沒有從技術角度進行解讀。有的文章說的倒很全面,但缺乏些許條理,讀起來並不容易理解。這也是筆者希望能帶給大家一點不一樣的東西,從技術角度解讀,並且利於理解。

MySQL事務原子性保證

交易原子性要求交易中的一系列操作要麼全部完成,要麼不做任何操作,不能只做一半。原子性對於原子操作很容易實現,就像HBase中行級事務的原子性實作比較簡單。但對於多條語句組成的事務來說,如果事務執行過程中發生異常,需要確保原子性就只能回滾,回滾到事務開始前的狀態,就像這個事務根本沒有發生過一樣。如何實現呢?

MySQL實作回滾操作完全依賴undo log,多說一句,undo log在MySQL除了用來實現原子性保證之外,還用來實現MVCC,下文也會涉及到。使用undo實作原子性在操作任何資料之前,首先會將修改前的資料記錄到undo log中,再進行實際修改。如果出現異常需要回滾,系統可以利用undo中的備份將資料還原到交易開始之前的狀態。下圖是MySQL中表示事務的基本資料結構,其中與undo相關的欄位為insert_undo和update_undo,分別指向本次事務所產生的undo log。

MySQL跨行事務模型(圖文詳解)

交易回溯根據update_undo(或insert_undo)找到對應的undo log,做逆向操作即可。對於已經標記刪除的數據清理刪除標記,對於更新數據直接回滾更新;插入操作稍微複雜一些,不僅需要刪除數據,還需要刪除相關的聚集索引以及二級索引記錄。

undo log是MySQL核心中非常重要的一塊內容,涉及知識比較多且複雜,例如:

1. undo log必須在資料修改之前持久化,undo log持久化需不需要記錄redo以防止宕機異常?如果需要就又涉及宕機恢復…

2. 透過undo log如何實現MVCC?

3. 那些undo log可以在什麼場景下回收清理?如何清理?

MySQL交易一致性保證:強一致性交易保證

MySQL交易隔離等級


Read Uncommitted (RU技術解讀:使用X鎖實現寫寫並發)

Read Uncommitted只實現了寫寫並發控制,並沒有有效的讀寫並發控制,導致當前事務可能讀到其他事務中還未提交的修改數據,這些數據準確性並不可靠(有可能被回滾掉),因此在此基礎上所做的一切假設就都不靠譜的。在現實場景中很少有業務會選擇該隔離等級。

寫寫並發實作機制和HBase並無兩樣,都是使用兩階段鎖定協定對對應記錄加行鎖定實作。不過MySQL中行鎖機制較為複雜,依行記錄是否為主鍵索引、唯一索引、非唯一索引或無索引等分為多種加鎖情況。

1. 如果id列是主鍵索引,MySQL只會為叢集索引記錄加鎖。

2. 如果id欄位是唯一二級索引,MySQL會為二級索引葉子節點以及叢集索引記錄加鎖。

3. 如果id列是非唯一索引,MySQL會為所有滿足條件(id = 15)的二級索引葉子節點以及對應的聚集索引記錄加鎖。

4. 如果id列是無索引的,SQL會走叢集索引全表掃描,並將掃描結果載入到SQL Server層進行過濾,因此InnoDB會先為掃描過的所有記錄加上鎖,如果SQL Server層過濾不符合條件,InnoDB會釋放該鎖。因此InnoDB會為掃描到的所有記錄都加鎖,很恐怖吧!

接下來無論是RC、RR,抑或是Serialization,寫寫並發控制都使用上述機制,所以不再贅述。接下來會重點分析RC和RR隔離等級中的讀寫並發控制機制。

在詳細介紹RC和RR之前,有必要在此先行介紹MySQL中MVCC機制,因為RC和RR都使用MVCC機制來實現事務之間的讀寫並發。只不過兩者在實現細節上有一些區別,具體區別接下來再聊。

MVCC in MySQL

MySQL中MVCC機制比較HBase來說要複雜的多,涉及的資料結構也比較複雜。為了解釋的比較清晰,以一個栗子為模版來解釋。例如目前有一行記錄如下圖所示:

MySQL跨行事務模型(圖文詳解)

前面四列是該行記錄的實際列值,需要重點關注的是DB_TRX_ID和DB_ROLL_PTR兩個隱藏列(對使用者不可見)。其中DB_TRX_ID表示修改該行事務的事務ID,而DB_ROLL_PTR表示指向該行回滾段的指針,該行記錄上所有版本數據,在undo中都通過鍊錶形式組織,該值實際指向undo中該行的歷史記錄鍊錶。

現在假設有一個事務trx2修改了該行數據,該行記錄就會變為下圖形式,DB_TRX_ID為最近修改該行事務的事務ID(trx2),DB_ROLL_PTR指向undo歷史記錄鍊錶:

MySQL跨行事務模型(圖文詳解)

了解了MySQL行記錄之後,再來看看交易的基本架構,下圖是MySQL的事務資料結構,上文我們提到過。事務在開啟之後會建立一個資料結構儲存事務相關資訊、鎖定資訊、undo log以及非常重要的read_view資訊。

read_view保存了當前事務開啟時整個MySQL中所有活躍事務列表,如下圖所示,在當前事務開啟的時候,系統中活躍的事務有trx4、trx6、trx7以及trx10。另外,up_trx_id表示當前事務啟動時,當前事務鍊錶中最小的事務ID;low_trx_id表示當前事務啟動時,當前事務鍊錶中最大的事務ID。

MySQL跨行事務模型(圖文詳解)

read_view是實作MVCC的關鍵點,它用來判斷記錄的哪個版本對目前交易可見。如果目前事務要讀取某行記錄,該行記錄的版本號(事務ID)為trxid,那麼:

#1. 如果trxid

2. 如果trxid > low_trx_id,表示該行事務所在的事務是在目前事務建立之後才開啟,所以該行記錄對目前事務不可見。

3. 如果up_trx_id

以下面行記錄為例,該行記錄存在多個版本(trx2、trx5、trx7以及trx12),其中trx12是最新版本。看看該行記錄中哪個版本對目前交易可見。

1. 該行記錄的最新版本為trx12,與當前事務read_view進行對比發現,trx12大於當前活躍事務清單中的最大事務trx10,表示trx12是在當前事務創建之後才開啟的,因此不可見。

2. 再查看該行記錄的第二個最新版本為trx7,與當前事務read_view對比發現,trx7介於當前活躍事務列表最小事務ID和最大事務ID之間,表明該行記錄所在事務在目前交易建立的時候處於活動狀態,在活躍清單中遍歷發現trx7確實存在,說明該事務尚未提交,所以對目前事務不可見。

3. 繼續查看該記錄的第三個最新版本trx5,也介於當前活躍事務清單最小事務ID和最大事務ID之間,表明該行記錄所在事務在當前事務創建的時候處於活動狀態,但遍歷發現該版本並不在活躍事務列表中,說明trx5對應事務已經提交(註:事務提交時間與事務編號沒有任何關聯,有可能事務編號大的事務先提交,事務編號小的事務後提交),因此trx5版本行記錄對目前事務可見,直接傳回。

MySQL跨行事務模型(圖文詳解)


Read Committed(技術解讀:寫入並發使用X鎖,讀寫並發使用MVCC避免髒讀)

上文介紹了MySQL中MVCC技術實作機制,但要明白RC隔離等級下事務可見性,還需要get一個核心點:RC隔離等級下的交易在每次執行select時都會產生一個最新的read_view取代原有的read_view。

MySQL跨行事務模型(圖文詳解)

如上圖所示,左側為1號事務,在不同時間點對id=1的記錄分別查詢了三次。右邊為2號事務,id=1的記錄進行了更新。更新前記錄只有一個版本,更新好變成了兩個版本。

1號事務在RC隔離等級下每次執行select請求都會產生一個最新的read_view,前兩次查詢產生的全域事務活躍清單中包含trx2,因此根據MVCC規定查到的記錄為老版本;最後一次查詢的時間點位於2號事務提交之後,因此產生的全域活躍事務清單中不包含trx2,此時在根據MVCC規定查到的記錄就是最新版本記錄。

Repeatable Read(技術解讀:寫寫並發使用X鎖,讀寫並發使用MVCC避免不可重複讀;當前讀使用Gap鎖避免幻讀)

和RC模式不同,RR模式下事務不會再每次執行select的時候產生最新的read_view,而是在事務第一次select時就產生read_view,後續不會再變更,直至當前事務結束。這樣可以有效避免不可重複讀,使得當前事務在整個事務過程中讀到的資料保持一致。示意圖如下:

MySQL跨行事務模型(圖文詳解)

這個就很容易理解,三次查詢所使用的全域活躍事務清單都一樣,且都是第一次產生的read_view,那之後查到的記錄必然和第一次查到的記錄一致。

RR隔離等級能夠避免幻讀嗎?

如果對幻讀還不了解的話,可以參考系列的第一篇文章。如下圖所示,1號事務對針對id>1的過濾條件執行了三次查詢,2號事務執行了一次插入,插入的記錄剛好符合id>1這個條件。可以看出來,三次查詢得到的資料是一致的,這個是由RR隔離等級的MVCC機制保證的。這麼看來,是避免了幻讀,但在最後1號事務在id=2處插入一筆記錄,MySQL會回傳Duplicate entry的錯誤,可見避免了幻讀是一種假象。

MySQL跨行事務模型(圖文詳解)

嚴格意義避免幻讀(技術解讀:當前讀使用Gap鎖避免幻讀)

之前提到的所有RR層級的select語句我們稱為快照讀,快照讀能夠保證不可重複讀,但並不能避免幻讀。於是MySQL又提出」目前讀」的概念,常見的目前讀語句有:

1.  select for update

2.  select lock in share mode

3.  update / delete

並且規定,RR層級下目前讀取語句會為記錄加上一種特殊的鎖定-Gap鎖, Gap鎖並沒有鎖定某個特定的記錄,而是鎖定記錄與記錄之間的間隔,確保這個間隔中不會插入新的其他記錄。下圖是示意圖:

MySQL跨行事務模型(圖文詳解)

上圖中1號交易首先執行了一個目前讀的select語句,這個語句會在id > 0的所有間隔加上Gap鎖,接下來2號交易在id = 3處執行插入時系統就會回傳Lock wait timeout execcded的例外狀況。當然,其他事務可以在id

Serializable(技術解讀:S鎖(讀)+X鎖(寫))

Serialization隔離級別是最嚴格的隔離級別,所有讀取請求都會加上讀鎖,不分快照讀和目前讀,所有寫會加上寫鎖。當然,這種隔離等級的效能因為鎖開銷而相對最差。

MySQL事務持久性保證

MySQL事務持久化策略和HBase基本上相同,但是涉及的元件相對比較多,主要有doublewrite、redo log以及binlog:

1. MySQL資料持久化(DoubleWrite)

實際上MySQL的真實資料寫入分為兩次寫入,一次寫入到一個稱為DoubleWrite的地方,寫成功之後再真實寫入資料所在磁碟。為什麼要寫兩次?這是因為MySQL資料頁大小與磁碟一次原子操作大小不一致,有可能會出現部分寫入的情況,例如預設InnoDB資料頁大小為16K,而磁碟一次原子寫入大小為512位元組(磁區大小) ,這樣一個資料頁寫入需要多次IO,這樣一旦中間發生異常就會出現資料遺失。另外要注意的是DoubleWrite效能並不會影響太大,因為寫入DoubleWrite是順序寫入,對效能影響來說不是很大。

2. redolog持久化策略(innodb_flush_log_at_trx_commit)#​​

##redolog是InnoDB的WAL,資料先寫入redolog並落盤,再寫入更新到bufferpool。 redolog的持久化策略和HBase中hlog的持久化策略一致,預設為1,表示每次事務提交之後log就會持久化到磁碟;該值為0表示每隔1秒鐘左右由非同步執行緒持久化到磁碟,這種情況下MySQL發生宕機有可能會遺失部分資料。值為2表示每次交易提交之後log會flush到作業系統緩衝區,再由作業系統異步flush到磁碟,這種情況下MySQL發生宕機不會遺失數據,但機器宕機有可能會遺失部分數據。

3. binlog持久化策略(sync_binlog)#

binlog作為Server層的日誌系統,主要以events的形式順序紀錄了資料庫的各種操作,同時可以紀錄每次作業所花費的時間。在MySQL官方文件上,主要介紹了Binlog的兩個最基本核心作用:備份和複製,因此binlog的持久化會一定程度影響資料備份和複製的完整性。和redo持久化策略相同,可取值有0,1,N。預設為0,表示寫入作業系統緩衝區,異步flush到磁碟。該值為1表示同步寫入磁碟。為N則表示每寫N次作業系統緩衝就執行一次刷新操作。

總結一下,本文是資料庫事務系列文章的第三篇,核心介紹了MySQL的單機跨行事務模型,其中對隔離​​性所涉及到的鎖定技術、MVCC機制進行了比較詳細的說明。對事務原子性、持久性等相關特性也進行簡單的分析與說明。接著筆者將會帶大家一起聊聊分散式事務模型,看看和單機事務模型到底有何差別。

推薦學習:MySQL教學

以上是MySQL跨行事務模型(圖文詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:cnblogs。如有侵權,請聯絡admin@php.cn刪除
MySQL和其他SQL方言之間的語法有什麼區別?MySQL和其他SQL方言之間的語法有什麼區別?Apr 27, 2025 am 12:26 AM

mysqldiffersfromothersqldialectsinsyntaxforlimit,自動啟動,弦樂範圍,子征服和表面上分析。 1)MySqluessLipslimit,whilesqlserverusestopopandoraclesrontersrontsrontsrontsronnum.2)

什麼是mysql分區?什麼是mysql分區?Apr 27, 2025 am 12:23 AM

MySQL分區能提升性能和簡化維護。 1)通過按特定標準(如日期範圍)將大表分成小塊,2)物理上將數據分成獨立文件,3)查詢時MySQL可專注於相關分區,4)查詢優化器可跳過不相關分區,5)選擇合適的分區策略並定期維護是關鍵。

您如何在MySQL中授予和撤銷特權?您如何在MySQL中授予和撤銷特權?Apr 27, 2025 am 12:21 AM

在MySQL中,如何授予和撤銷權限? 1.使用GRANT語句授予權限,如GRANTALLPRIVILEGESONdatabase_name.TO'username'@'host';2.使用REVOKE語句撤銷權限,如REVOKEALLPRIVILEGESONdatabase_name.FROM'username'@'host',確保及時溝通權限變更。

說明InnoDB和Myisam存儲引擎之間的差異。說明InnoDB和Myisam存儲引擎之間的差異。Apr 27, 2025 am 12:20 AM

InnoDB適合需要事務支持和高並發性的應用,MyISAM適合讀多寫少的應用。 1.InnoDB支持事務和行級鎖,適用於電商和銀行系統。 2.MyISAM提供快速讀取和索引,適合博客和內容管理系統。

MySQL中有哪些不同類型的連接?MySQL中有哪些不同類型的連接?Apr 27, 2025 am 12:13 AM

MySQL中有四種主要的JOIN類型:INNERJOIN、LEFTJOIN、RIGHTJOIN和FULLOUTERJOIN。 1.INNERJOIN返回兩個表中符合JOIN條件的所有行。 2.LEFTJOIN返回左表中的所有行,即使右表中沒有匹配的行。 3.RIGHTJOIN與LEFTJOIN相反,返回右表中的所有行。 4.FULLOUTERJOIN返回兩個表中所有符合或不符合JOIN條件的行。

MySQL中有哪些不同的存儲引擎?MySQL中有哪些不同的存儲引擎?Apr 26, 2025 am 12:27 AM

mysqloffersvariousStorageengines,每個suitedfordferentusecases:1)InnodBisidealForapplicationsNeedingingAcidComplianCeanDhighConcurncurnency,supportingtransactionsancions and foreignkeys.2)myisamisbestforread-Heavy-Heavywyworks,lackingtransactionsactionsacupport.3)記憶

MySQL中有哪些常見的安全漏洞?MySQL中有哪些常見的安全漏洞?Apr 26, 2025 am 12:27 AM

MySQL中常見的安全漏洞包括SQL注入、弱密碼、權限配置不當和未更新的軟件。 1.SQL注入可以通過使用預處理語句防止。 2.弱密碼可以通過強制使用強密碼策略避免。 3.權限配置不當可以通過定期審查和調整用戶權限解決。 4.未更新的軟件可以通過定期檢查和更新MySQL版本來修補。

您如何確定MySQL中的慢速查詢?您如何確定MySQL中的慢速查詢?Apr 26, 2025 am 12:15 AM

在MySQL中識別慢查詢可以通過啟用慢查詢日誌並設置閾值來實現。 1.啟用慢查詢日誌並設置閾值。 2.查看和分析慢查詢日誌文件,使用工具如mysqldumpslow或pt-query-digest進行深入分析。 3.優化慢查詢可以通過索引優化、查詢重寫和避免使用SELECT*來實現。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。