這篇文章主要講解了“保證數據一致性的方式”,文中的講解內容簡(jiǎn)單清晰,易于學(xué)習與理解,下面請大家跟著(zhù)小編的思路慢慢深入,一起來(lái)研究和學(xué)習“MySQL保證數據一致性的方式”吧!
一、MySQL事務(wù)模型ACID
MySQL是一個(gè)多引擎數據庫,其中InnoDB支持數據庫事務(wù),也是最常用的引擎。下邊就介紹InnoDB的事務(wù)模型
MySQL官方文檔對事務(wù)是這么描述的“事務(wù)是可以提交或回滾的原子工作單元。當事務(wù)對數據庫進(jìn)行多個(gè)更改時(shí),要么提交事務(wù)時(shí)所有更改都成功,要么回滾事務(wù)時(shí)撤消所有更改?!?/p>
“ACID模型是一組數據庫設計原則,強調業(yè)務(wù)數據和關(guān)鍵應用程序的可靠性很重要。MySQL包含與ACID模型緊密結合的innodb存儲引擎組件,確保數據不會(huì )被破壞,結果不會(huì )被軟件崩潰和硬件故障等異常情況所篡改。當您依賴(lài)ACID的特性,就不再需要重新發(fā)明一致性檢查和崩潰恢復機制?!?/p>
ACID模型按照字母拆解分為四大特性
A : atomicity 原子性。原子性是我們對事務(wù)最直觀(guān)的理解:事務(wù)就是一系列的操作,要么全部都執行,要么全部都不執行。
C : consistency 一致性。數據庫事務(wù)不能破壞關(guān)系數據的完整性以及業(yè)務(wù)邏輯上的一致性。例如對銀行轉帳事務(wù),不管事務(wù)成功還是失敗,應該保證事務(wù)結束后ACCOUNTS表中Tom和Jack的存款和不變。
I : isolation 隔離性。在并發(fā)環(huán)境中,當不同的事務(wù)同時(shí)操縱相同的數據時(shí),每個(gè)事務(wù)都有各自的完整數據空間。
D : durability 持久性。只要事務(wù)成功結束,它對數據庫所做的更新就必須永久保存下來(lái)。即使發(fā)生系統崩潰,重新啟動(dòng)數據庫系統后,數據庫還能恢復到事務(wù)成功結束時(shí)的狀態(tài)。
二、InnoDB存儲引擎架構
下邊這張圖是InnoDB的架構,包括兩大部分,內存結構(In-Memory Structures)和磁盤(pán)上的結構(On-Disk Structures)。
在這張圖中,尤其要關(guān)注“Redo Log”和“Undo Tablespaces”這兩個(gè)區域,它們跟事務(wù)息息相關(guān)。
內存結構(In-Memory Structures)更多的目的是在提高性能,因此本文不會(huì )過(guò)多關(guān)注。如果感興趣,可以訪(fǎng)問(wèn)MySQL的官方網(wǎng)站www.mysql.com
“Undo Tablespaces”包含Undo Log(撤消日志),Undo Log是撤消日志記錄的集合,其中包含如何撤消事務(wù)對聚集索引記錄的最新更改的信息。Undo Log存在于撤消日志段中,這些日志段包含在回滾段中。
MySQL事務(wù)的四個(gè)特性中ACD三個(gè)特性是通過(guò)Redo Log(重做日志)和Undo Log 實(shí)現的,而 I(隔離性)是通過(guò)Lock(鎖)來(lái)實(shí)現。
三、普及個(gè)概念MVCC
MVCC,Multi-Version Concurrency Control,多版本并發(fā)控制。這項技術(shù)使得InnoDB的事務(wù)隔離級別下執行一致性讀操作有了保證,換言之,就是為了查詢(xún)一些正在被另一個(gè)事務(wù)更新的行,并且可以看到它們被更新之前的值。這是一個(gè)可以用來(lái)增強并發(fā)性的強大技術(shù),查詢(xún)不用等待另一個(gè)事務(wù)釋放鎖。這項技術(shù)廣泛應用于數據庫,例如Oracle,PostgreSQL。當然也有一些數據庫產(chǎn)品以及mysql的其它存儲引擎不支持它。
看一看MVCC機制的示意圖,圖下邊會(huì )給出文字解釋
圖中底部橫軸是時(shí)間,縱向的箭頭用來(lái)標記增、刪、改、查發(fā)生的時(shí)刻。尤其注意時(shí)間軸上方兩條色塊,代表數據的兩個(gè)版本V1、V2。為了醒目,我把V1、V2用紅色方框圈了起來(lái)(多版本的體現)。從左向右解讀這張圖
1、T1事務(wù)插入數據a=3,然后提交,生成了數據對應的V1版本
2、T2事務(wù)開(kāi)始讀取a數據,讀取會(huì )持續一段時(shí)間,由于開(kāi)始讀取的時(shí)刻,只有V1版本,所以最終T2讀到a=3
3、T2讀取過(guò)程中,T3對數據a進(jìn)行修改,a=4,生成a數據的V2版本,但此時(shí)并未提交,因此生效的是V1版本數據。
4、T3修改提交之前,T4讀取a數據,由于此時(shí)V1版本數據生效,因此,T4讀到a=3
5、T3提交a=4的修改,V1版本數據失效,V2生效。a的值變?yōu)?
6、T5讀取a的值,讀到V2版本,a=4
至此,MVCC的概念就搞明白了,那么MySQL是怎么實(shí)現的呢?
四、InnoDB多版本的實(shí)現
1、三個(gè)隱藏字段
在內部,InnoDB向數據庫中存儲的每一行數據添加三個(gè)字段。
(1)DB_TRX_ID字段,6字節。表示插入或更新行的最后一個(gè)事務(wù)的事務(wù)標識符。此外,刪除在內部被視為更新,其中行中的特殊位被設置為將其標記為已刪除。
(2)DB_ROLL_PTR字段,7字節,叫做回滾指針(roll pointer)?;貪L指針指向寫(xiě)入回滾段的撤消日志(Undo Log)。如果行已更新,則撤消日志包含重建更新前該行內容所需的信息。
(3)DB_ROW_ID字段,6字節。包含一個(gè)隨著(zhù)新行插入而單調增加的行ID,如果innodb自動(dòng)生成聚集索引,則該索引包含行ID值。否則,DB_ROW_ID列不會(huì )出現在任何索引中。
2、多版本產(chǎn)生過(guò)程
以新增一條記錄并對該記錄進(jìn)行2次修改來(lái)說(shuō)明具體實(shí)現
這條記錄有3個(gè)隱含字段(前面已經(jīng)介紹),分別應對行的ID、事務(wù)號和回滾指針。
當插入的是一條新數據時(shí),記錄上對應的回滾段指針為NULL
這個(gè)過(guò)程做了以下幾件事
用排他鎖鎖定該行
把該行修改前的值拷貝到Undo Log中
修改當前行的值,填寫(xiě)事務(wù)編號,使回滾指針指向Undo Log中的修改前的行
記錄Redo Log,包括Undo Log中的變化
多次更新后,回滾指針會(huì )把不同版本的記錄串在一起。在InnoDB中存在purge線(xiàn)程,它會(huì )查詢(xún)那些比現在最老的活動(dòng)事務(wù)還早的Undo Log,并刪除它們,從而保證Undo Log文件不至于無(wú)限增長(cháng)。
3、提交與回滾
當事務(wù)正常提交時(shí),InnoDB只需要更改事務(wù)狀態(tài)為commit即可,不需要做其他額外的工作
回滾(rollback)需要根據當前回滾指針從Undo Log中找出事務(wù)修改前的版本,并恢復。如果事務(wù)影響的行非常多,回滾則可能會(huì )很慢,根據經(jīng)驗值沒(méi)提交的事務(wù)行數在1000~10000之間,InnoDB效率還是非常高的(唐成-數據庫多版本實(shí)現內幕)。
commit效率高,rollback代價(jià)大
4、可見(jiàn)性
事務(wù)隔離是數據庫處理的基礎之一,隔離是縮寫(xiě)ACID中的I。隔離級別是當多個(gè)事務(wù)同時(shí)進(jìn)行更改和執行查詢(xún)時(shí),微調性能、可靠性、一致性和結果再現性之間的平衡的設置。
InnoDB提供SQL1992標準定義的四個(gè)隔離級別,READ UNCOMMITTED(未提交讀), READ COMMITTED(已提交讀), REPEATABLE READ(可重復讀), and SERIALIZABLE(可串行化)。默認的是REPEATABLE READ
每種隔離級別具體的意義可以百度查到,實(shí)現原理深入進(jìn)去比較復雜。注意到每條數據隱藏的事務(wù)ID字段DB_TRX_ID有時(shí)序性,理論上可以根據一些策略,借助這個(gè)字段來(lái)實(shí)現與隔離級別相關(guān)的功能。事實(shí)上InnoDB也是這么做的。當然這個(gè)功能還涉及很多鎖的問(wèn)題,這里不再展開(kāi)。
MySQL官方文檔在“鎖和事務(wù)模型”這一章節開(kāi)始就介紹了InnoDB的鎖,截個(gè)目錄,感興趣可以去讀一下。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站