新聞中心
隨著互聯(lián)網(wǎng)的飛速發(fā)展,數(shù)據(jù)庫作為存儲數(shù)據(jù)的基礎(chǔ)設(shè)施,對于保障互聯(lián)網(wǎng)業(yè)務(wù)的可靠性和穩(wěn)定性起到了至關(guān)重要的作用。在互聯(lián)網(wǎng)業(yè)務(wù)中,由于數(shù)據(jù)操作的并發(fā)性,數(shù)據(jù)庫的并發(fā)性能成為了關(guān)鍵瓶頸。在眾多的數(shù)據(jù)庫技術(shù)中,MVCC技術(shù)成為了提高數(shù)據(jù)庫并發(fā)性能的關(guān)鍵技術(shù)。

什么是MVCC技術(shù)?
MVCC全稱為Multi-Version Concurrency Control,即多版本并發(fā)控制。MVCC技術(shù)是一種并發(fā)控制機制,它是為了解決數(shù)據(jù)庫在高并發(fā)環(huán)境下數(shù)據(jù)一致性與性能的問題而提出的。MVCC是在保證事務(wù)一致性、隔離性的前提下提高數(shù)據(jù)庫并發(fā)性能的重要技術(shù)。
MVCC技術(shù)的實現(xiàn)方式
MVCC技術(shù)的實現(xiàn)方式有兩種,一種是基于版本鏈表,即在每個數(shù)據(jù)塊中維護(hù)一個版本鏈表,每個版本鏈表節(jié)點包含一個版本號和對應(yīng)的數(shù)據(jù)。另一種是基于快照隔離,即為每個事務(wù)創(chuàng)建一個數(shù)據(jù)庫快照來進(jìn)行事務(wù)處理。
基于版本鏈表的實現(xiàn)方式,采用了多版本存儲數(shù)據(jù),在讀取數(shù)據(jù)時,將版本號更高的數(shù)據(jù)返回。同時,寫入新數(shù)據(jù)時,基于CAS算法(Compare and Swap)實現(xiàn)原子性地更新。這樣就能夠?qū)崿F(xiàn)數(shù)據(jù)的讀取和寫入的并發(fā)控制。在每個事務(wù)中,讀取的數(shù)據(jù)版本號大于等于事務(wù)開始時的版本號,事務(wù)寫入的數(shù)據(jù)版本號等于事務(wù)開始時的版本號。
基于快照隔離的實現(xiàn)方式,將每個事務(wù)隔離出來,每個事務(wù)處理時都有自己的數(shù)據(jù)庫快照??煺罩邪耸聞?wù)開始時的所有數(shù)據(jù)。在事務(wù)處理過程中,不會對其他事務(wù)可見,其中數(shù)據(jù)的修改只有在事務(wù)提交時才會對其他事務(wù)可見。
MVCC技術(shù)的優(yōu)點
MVCC技術(shù)的出現(xiàn),主要是為了解決傳統(tǒng)鎖機制的死鎖問題和性能問題。
在傳統(tǒng)鎖機制中,由于鎖的粒度過大,因此容易發(fā)生死鎖問題。同時,鎖的開銷也非常大,容易出現(xiàn)性能瓶頸。而MVCC技術(shù)實現(xiàn)了原子性,避免了死鎖問題。同時,由于讀取數(shù)據(jù)時只需要讀取一個版本的數(shù)據(jù),沒有鎖的粒度限制,因此將塊粒度調(diào)小,從而提高并發(fā)性能。在讀多寫少的情況下,MVCC技術(shù)的性能更為優(yōu)越。
在MVCC技術(shù)中,每個事務(wù)都有自己的快照,因此對其他事務(wù)的影響非常小,避免了傳統(tǒng)鎖機制中由于阻塞而造成的性能損失,提高了并發(fā)性能。同時,在MVCC技術(shù)中,對于讀多寫少的業(yè)務(wù)場景,可以采用基于快照隔離的方式實現(xiàn),進(jìn)一步提高了并發(fā)性能。
MVCC技術(shù)的應(yīng)用
目前,MVCC技術(shù)已經(jīng)廣泛應(yīng)用于各類數(shù)據(jù)庫中。例如,Oracle數(shù)據(jù)庫的默認(rèn)隔離級別是Read Committed,它采用的就是MVCC技術(shù)。PostgreSQL數(shù)據(jù)庫也采用了MVCC技術(shù),并將其作為默認(rèn)隔離級別。
同時,MVCC技術(shù)也被用于各種分布式系統(tǒng)中,如Hadoop、Spark等。這些分布式系統(tǒng)都需要對數(shù)據(jù)進(jìn)行并發(fā)處理,因此也需要采用MVCC技術(shù)實現(xiàn)數(shù)據(jù)一致性和性能的平衡。
MVCC技術(shù)是一種非常重要的技術(shù),為了解決傳統(tǒng)鎖機制在高并發(fā)場景下的性能和死鎖問題而提出。該技術(shù)實現(xiàn)對讀取數(shù)據(jù)和寫入數(shù)據(jù)的并發(fā)控制,避免了鎖的粒度問題和死鎖問題,提高數(shù)據(jù)庫的并發(fā)性能。同時,由于其應(yīng)用范圍廣泛,因此成為了數(shù)據(jù)庫和分布式系統(tǒng)中重要的技術(shù),未來也將得到不斷完善和發(fā)展。
相關(guān)問題拓展閱讀:
- Access數(shù)據(jù)庫中如何避免臟數(shù)據(jù)
- MySQL 事務(wù)的默認(rèn)隔離級別是什么?可以解決幻讀問題么?
Access數(shù)據(jù)庫中如何避免臟數(shù)據(jù)
臟讀dirtyreads:當(dāng)事務(wù)讀取還未被提交的數(shù)據(jù)時,就會發(fā)生這種事件。舉例來說:Transaction1修改了一行數(shù)據(jù),然后Transaction2在Transaction1還未提交修改操作之前讀取了被修改的行。如果Transaction1回滾了修改操作,那么Transaction2讀取的數(shù)據(jù)就可以看作是從未存在過的。
不可重復(fù)的讀non-repeatablereads:當(dāng)事務(wù)兩次讀取同一行數(shù)據(jù),但每次得到的數(shù)據(jù)都不一樣時,就會發(fā)生這種事件。舉例來說:Transaction1讀取一行數(shù)據(jù),然后Transaction2修改或刪除該行并提交修改操作。當(dāng)Transaction1試圖重新讀取該行時,它就會得到不同的數(shù)據(jù)值(如果該行被更新)或發(fā)現(xiàn)該行不再存在(如果該行被刪除)。
虛讀phantomread:如果符合搜索條件的一行數(shù)據(jù)在后面的讀取操作中出現(xiàn),但該行數(shù)據(jù)卻不屬于最初的數(shù)據(jù),就會發(fā)生這種事件。舉例來說:Transaction1讀取滿足某種搜索條件的一些行,然后Transaction2插入了符合Transaction1的搜索條件的一個新行。如果Transaction1重新執(zhí)行產(chǎn)生原來那些行的查詢,就會得到不同的行。
MYSQL事務(wù)隔離級別的認(rèn)識
:27
在hibernate中如果要連續(xù)不間斷的保存多個實體的實例,那么在我們保存之一個的時候,其實在數(shù)據(jù)庫里是不存在數(shù)據(jù)的,即使用Session.flush()也無濟于事,這到底是怎么回事呢?讓我很是疑惑…….
在查閱了相關(guān)的資料后,原來是數(shù)據(jù)庫對于事務(wù)的隔離級別的限制問題,而我原來的MYSQL數(shù)據(jù)庫正好是不支持我上述操作的隔離級別。
1、在MYSQL中查詢事務(wù)隔離級別:
select@@tx_isolation;(tx其實就是transaction的縮寫或者習(xí)慣縮寫法)
我的結(jié)果是REPEATABLE-READ(即可重復(fù)讀,稍后會引用專業(yè)結(jié)束文檔)
2、修改MYSQL事務(wù)隔離界別:
settransactionisolationlevel目標(biāo)隔離級別;
3、再次查詢隔離級別進(jìn)行檢驗是否已經(jīng)成功修改。
這樣在修改了隔離級別之后,在進(jìn)行save()的時候,數(shù)據(jù)庫中就會存在一些數(shù)據(jù)了,問題解決了。關(guān)于其他的數(shù)據(jù)庫產(chǎn)品,思想都是一樣的。
附加、官方的SQL事務(wù)隔離級別文檔:
SQL標(biāo)準(zhǔn)定義了4類隔離級別,包括了一些具體規(guī)則,用來限定事務(wù)內(nèi)外的哪些改變是可見的,哪些是不可見的。低級別的隔離野碼級一般支持更高的并發(fā)處理,并擁有吵悉更低的系統(tǒng)開銷。
ReadUncommitted(讀取未提交內(nèi)容)
在該隔離級別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級別很少用于實際應(yīng)用,因為它的性能也不比其他級別好多少。讀取未提交的數(shù)據(jù),也被稱之為臟讀(DirtyRead)。
ReadCommitted(讀取提交內(nèi)容)
這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級別(但不是MySQL默認(rèn)的)。它滿足了隔離的簡單定義:一個事務(wù)只能看見已經(jīng)提交事務(wù)所做的升脊乎改變。這種隔離級別也支持所謂的不可重復(fù)讀(Read),因為同一事務(wù)的其他實例在該實例處理其間可能會有新的commit,所以同一select可能返回不同結(jié)果。
RepeatableRead(可重讀)
這是MySQL的默認(rèn)事務(wù)隔離級別,它確保同一事務(wù)的多個實例在并發(fā)讀取數(shù)據(jù)時,會看到同樣的數(shù)據(jù)行。不過理論上,這會導(dǎo)致另一個棘手的問題:幻讀(PhantomRead)。簡單的說,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時,另一個事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時,會發(fā)現(xiàn)有新的“幻影”行。InnoDB和Falcon存儲引擎通過多版本并發(fā)控制(MVCC,ConcurrencyControl)機制解決了該問題。
(可串行化)
這是更高的隔離級別,它通過強制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數(shù)據(jù)行上加上共享鎖。在這個級別,可能導(dǎo)致大量的超時現(xiàn)象和鎖競爭。
MySQL 事務(wù)的默認(rèn)隔離級別是什么?可以解決幻讀問題么?
我們設(shè)想一個場景,這個場景中我們需要插入多條相關(guān)聯(lián)的數(shù)據(jù)到數(shù)據(jù)庫,不幸的是,這個過程可能會遇到下面這些問題:
上面的任何一個問題都可能會導(dǎo)致數(shù)據(jù)的不一致性。為了保證數(shù)據(jù)的一致性,系統(tǒng)必須能夠處理這些問題。事務(wù)就是我們抽象出來簡化這些問題的首選機制。事務(wù)的概念起源于數(shù)據(jù)庫,目前,已經(jīng)成為一個比較廣泛的概念。
何為事務(wù)?
一言蔽之,
事務(wù)是邏輯上的一組操作,要么都執(zhí)行,要么都不執(zhí)行。
事務(wù)最經(jīng)典也經(jīng)常被拿出來說例子就是轉(zhuǎn)賬了。假如小明要給小紅轉(zhuǎn)賬 1000 元,這個轉(zhuǎn)賬會涉及到兩個關(guān)鍵操作,這兩個操作必須都成功或者都失敗。
事務(wù)會把這兩個操作就可以看成邏輯上的一個整體,這個整體包含的操作要么都成功,要么都要失敗。這樣就不會出現(xiàn)小明余額減少而小紅的余額卻并沒有增加的情況。
大多數(shù)情況下,我們在談?wù)撌聞?wù)的時候,如果沒有特指
分布式事務(wù)
,往往指的就是
數(shù)據(jù)庫事務(wù)
。
數(shù)據(jù)庫事務(wù)在我們?nèi)粘i_發(fā)中接觸的最多了。如果你的項目屬于單體架構(gòu)的話,你接觸到的往往就是數(shù)據(jù)庫事務(wù)了。
那數(shù)據(jù)庫事務(wù)有什么作用呢?
簡單來說,數(shù)據(jù)庫事務(wù)可以保證多個對數(shù)據(jù)庫的操作(也就是 SQL 語句)構(gòu)成一個邏昌穗輯上的整體。構(gòu)成這個邏輯上的整體的這些數(shù)據(jù)庫操作遵循:
要么全部執(zhí)行成功,要么全部不執(zhí)行
。
另外,關(guān)系型數(shù)據(jù)庫(例如: MySQL 、 SQL Server 、 Oracle 等)事務(wù)都有
ACID
特性:
ACID
這里要額外補充一點:
只有粗迅瞎保證了事務(wù)的持久性、原子性、隔離性之后,一致性才能得到保障。也就是說 A、I、D 是手段,C 是目的!
在典型的應(yīng)用程序中,多個事務(wù)并發(fā)運行,經(jīng)常會操作相同的數(shù)據(jù)來完成各自的任務(wù)(多個用戶對同一數(shù)據(jù)進(jìn)行操作)。并發(fā)雖然是必須的,但可能會導(dǎo)致以下的問題。
不可重復(fù)讀和幻讀區(qū)別
:不可重復(fù)讀的重點是修改比如多次讀取一條記錄發(fā)現(xiàn)其中某些列的值被修改,幻讀的重點在于新增或者刪除比如多次查詢同一條查詢語句(DQL)時,記錄發(fā)現(xiàn)記錄增多或減少了。
SQL 標(biāo)準(zhǔn)定義了四個隔離級別:
隔離級別臟讀不可重復(fù)讀幻讀 READ-UNCOMMITTED READ-COMMITTED REPEATABLE-READ SERIALIZABLE
MySQL 的隔離級別基于鎖和 MVCC 機制共同實現(xiàn)的。
SERIALIZABLE 隔離級別,是通過鎖來實現(xiàn)的。除了 SERIALIZABLE 隔離級別,其他的隔離級別都是基于 MVCC 實現(xiàn)。
不過, SERIALIZABLE 之外的其他隔離級別可能也需要用到鎖機制,就比如 REPEATABLE-READ 在當(dāng)前讀情況下需要使用加鎖讀來保證不會出現(xiàn)幻讀。
MySQL InnoDB 存儲引擎的默認(rèn)支持的隔離級別是
REPEATABLE-READ(可重讀)
。我們可以通過 SELECT @@tx_isolation; 命令來查看,MySQL 8.0 該命令改為 SELECT @@transaction_isolation;
從上面對 SQL 標(biāo)準(zhǔn)定義了四個隔離級別的介紹可以看出,標(biāo)準(zhǔn)的 SQL 隔離級別定義里,REPEATABLE-READ(可重復(fù)讀)是不可以防止幻讀的。
但是!InnoDB 實現(xiàn)的 REPEATABLE-READ 隔離級別其實是可以解決幻讀問題發(fā)生的,主要有下面兩巖空種情況:
因為隔離級別越低,事務(wù)請求的鎖越少,所以大部分?jǐn)?shù)據(jù)庫系統(tǒng)的隔離級別都是
READ-COMMITTED
,但是你要知道的是 InnoDB 存儲引擎默認(rèn)使用
REPEATABLE-READ
并不會有任何性能損失。
InnoDB 存儲引擎在分布式事務(wù)的情況下一般會用到 SERIALIZABLE 隔離級別。
數(shù)據(jù)庫 mvcc的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于數(shù)據(jù)庫 mvcc,數(shù)據(jù)庫MVCC,提高并發(fā)性能的關(guān)鍵技術(shù),Access數(shù)據(jù)庫中如何避免臟數(shù)據(jù),MySQL 事務(wù)的默認(rèn)隔離級別是什么?可以解決幻讀問題么?的信息別忘了在本站進(jìn)行查找喔。
成都網(wǎng)站營銷推廣找創(chuàng)新互聯(lián),全國分站站群網(wǎng)站搭建更好做SEO營銷。
創(chuàng)新互聯(lián)(www.cdcxhl.com)四川成都IDC基礎(chǔ)服務(wù)商,價格厚道。提供成都服務(wù)器托管租用、綿陽服務(wù)器租用托管、重慶服務(wù)器托管租用、貴陽服務(wù)器機房服務(wù)器托管租用。
網(wǎng)頁標(biāo)題:數(shù)據(jù)庫MVCC,提高并發(fā)性能的關(guān)鍵技術(shù) (數(shù)據(jù)庫 mvcc)
標(biāo)題來源:http://www.dlmjj.cn/article/cdicgsi.html


咨詢
建站咨詢
